anniversary 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +3 -0
- data/Gemfile +4 -0
- data/Rakefile +2 -0
- data/anniversary.gemspec +22 -0
- data/lib/anniversary.rb +2 -0
- data/lib/anniversary/date_additions.rb +55 -0
- data/lib/anniversary/version.rb +3 -0
- data/spec/lib/date_additions_spec.rb +72 -0
- data/spec/spec_helper.rb +3 -0
- metadata +91 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
data/anniversary.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "anniversary/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "anniversary"
|
7
|
+
s.version = Anniversary::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Rick Denatale"]
|
10
|
+
s.email = ["rick.denatale@gmail.com", "rickd@scimedsolutions.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Add method to Ruby's Date to get [years, months, days] between two dates}
|
13
|
+
s.description = %q{Adds the method Date#years_months_days_since which returns the number of days, months and years since another date}
|
14
|
+
|
15
|
+
s.rubyforge_project = "anniversary"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.add_development_dependency "rspec", "~>2"
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
end
|
data/lib/anniversary.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
class Date
|
4
|
+
def in_year_with_correction(yr,mth=month)
|
5
|
+
Date.civil_with_missing_day_correction(yr, mth, day)
|
6
|
+
end
|
7
|
+
alias_method :in_year_and_month_with_correction, :in_year_with_correction
|
8
|
+
|
9
|
+
def self.civil_with_missing_day_correction(year, month, day)
|
10
|
+
days_in_month = [
|
11
|
+
# J F M A M J J A S O N D
|
12
|
+
0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
13
|
+
][month]
|
14
|
+
days_in_month = 29 if (month == 2) && ((year % 4 == 0) && ((year % 400 == 0) || (year % 100 != 0)))
|
15
|
+
if (days_in_month < day)
|
16
|
+
month += 1
|
17
|
+
day = day - days_in_month
|
18
|
+
end
|
19
|
+
civil(year, month, day)
|
20
|
+
end
|
21
|
+
|
22
|
+
def years_months_days_since(date, debug = false)
|
23
|
+
if date < self
|
24
|
+
puts "#{self}.years_months_days_since(#{date})" if debug
|
25
|
+
anniversary_this_year = date.in_year_with_correction(year)
|
26
|
+
puts "anniversary_this_year is #{anniversary_this_year}" if debug
|
27
|
+
years = if anniversary_this_year <= self
|
28
|
+
year - date.year
|
29
|
+
else
|
30
|
+
year - date.year - 1
|
31
|
+
end
|
32
|
+
last_monthiversary = monthiversary_this_month = date.in_year_and_month_with_correction(year, month)
|
33
|
+
puts "monthiversary_this_month is #{monthiversary_this_month}" if debug
|
34
|
+
if (monthiversary_this_month > self)
|
35
|
+
last_month = Date.civil(year, month, 1) << 1
|
36
|
+
last_monthiversary = date.in_year_and_month_with_correction(last_month.year, last_month.month)
|
37
|
+
end
|
38
|
+
puts "last_monthiversary is #{last_monthiversary}" if debug
|
39
|
+
|
40
|
+
if last_monthiversary > date
|
41
|
+
months = (last_monthiversary.month - anniversary_this_year.month)
|
42
|
+
months += 12 if months < 0
|
43
|
+
else
|
44
|
+
months = 0
|
45
|
+
end
|
46
|
+
days = (self - last_monthiversary).to_i
|
47
|
+
elsif date > self
|
48
|
+
date.years_months_days_since(self, debug).map {|v| -v}
|
49
|
+
else
|
50
|
+
years, months, days = 0, 0, 0
|
51
|
+
end
|
52
|
+
|
53
|
+
[years, months, days]
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
|
2
|
+
require 'spec_helper'
|
3
|
+
require 'anniversary.rb'
|
4
|
+
describe "::Date" do
|
5
|
+
|
6
|
+
context "years_months_days_since" do
|
7
|
+
def self.build_example(anniversary, subject, expected)
|
8
|
+
eyd, emd, edd = *expected
|
9
|
+
it "#{subject}.years_since(#{anniversary}) should give [#{eyd}, #{emd}, #{edd}]" do
|
10
|
+
subject.years_months_days_since(anniversary).should == [eyd, emd, edd]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.test_range(anniversary, last_date_to_test)
|
15
|
+
raise "Dates are incompatible" if last_date_to_test < anniversary
|
16
|
+
expected_year_diff = 0
|
17
|
+
expected_month_diff = 0
|
18
|
+
expected_day_diff = 0
|
19
|
+
test_date = anniversary
|
20
|
+
next_anniversary = ::Date.civil_with_missing_day_correction(test_date.year + 1, test_date.month, test_date.day)
|
21
|
+
next_month = ::Date.civil(test_date.year, test_date.month, 1) >> 1
|
22
|
+
next_monthiversary = ::Date.civil_with_missing_day_correction(next_month.year, next_month.month, test_date.day)
|
23
|
+
|
24
|
+
while (test_date <= last_date_to_test) do
|
25
|
+
build_example(anniversary, test_date, [expected_year_diff, expected_month_diff, expected_day_diff])
|
26
|
+
expected_day_diff += 1
|
27
|
+
test_date += 1
|
28
|
+
if test_date == next_monthiversary
|
29
|
+
next_month = ::Date.civil(test_date.year, test_date.month, 1) >> 1
|
30
|
+
next_monthiversary = ::Date.civil_with_missing_day_correction(next_month.year, next_month.month, test_date.day)
|
31
|
+
if test_date == next_anniversary
|
32
|
+
next_anniversary = ::Date.civil_with_missing_day_correction(test_date.year + 1, test_date.month, test_date.day)
|
33
|
+
expected_year_diff += 1
|
34
|
+
expected_month_diff = 0
|
35
|
+
else
|
36
|
+
expected_month_diff += 1
|
37
|
+
end
|
38
|
+
expected_day_diff = 0
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should give zeroes for the same date" do
|
44
|
+
anniversary = ::Date.civil(2001, 6, 1)
|
45
|
+
target = ::Date.civil(2001, 6, 1)
|
46
|
+
target.years_months_days_since(anniversary).should == [0, 0, 0]
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should handle a case where the date is in the next calendar month, but before the montiversary" do
|
50
|
+
anniversary = ::Date.civil(2001, 6, 15)
|
51
|
+
target = ::Date.civil(2001, 7, 1)
|
52
|
+
target.years_months_days_since(anniversary).should == [0, 0, 16]
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should handle a case where the date is one month after an anniversary on the first of the month" do
|
56
|
+
anniversary = ::Date.civil(2001, 6, 1)
|
57
|
+
target = ::Date.civil(2001, 7, 1)
|
58
|
+
target.years_months_days_since(anniversary).should == [0, 1, 0]
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should handle a case where the date is new years day after the anniversary" do
|
62
|
+
anniversary = ::Date.civil(2001, 6, 1)
|
63
|
+
target = ::Date.civil(2002, 1, 1)
|
64
|
+
target.years_months_days_since(anniversary).should == [0, 7, 0]
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
test_range( ::Date.civil(2000,6,1), ::Date.civil(2010,8,31))
|
69
|
+
test_range( ::Date.civil(2000, 6, 15), ::Date.civil(2010,8,31))
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: anniversary
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Rick Denatale
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-01-13 00:00:00 -05:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: rspec
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 7
|
30
|
+
segments:
|
31
|
+
- 2
|
32
|
+
version: "2"
|
33
|
+
type: :development
|
34
|
+
version_requirements: *id001
|
35
|
+
description: Adds the method Date#years_months_days_since which returns the number of days, months and years since another date
|
36
|
+
email:
|
37
|
+
- rick.denatale@gmail.com
|
38
|
+
- rickd@scimedsolutions.com
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files: []
|
44
|
+
|
45
|
+
files:
|
46
|
+
- .gitignore
|
47
|
+
- Gemfile
|
48
|
+
- Rakefile
|
49
|
+
- anniversary.gemspec
|
50
|
+
- lib/anniversary.rb
|
51
|
+
- lib/anniversary/date_additions.rb
|
52
|
+
- lib/anniversary/version.rb
|
53
|
+
- spec/lib/date_additions_spec.rb
|
54
|
+
- spec/spec_helper.rb
|
55
|
+
has_rdoc: true
|
56
|
+
homepage: ""
|
57
|
+
licenses: []
|
58
|
+
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
|
62
|
+
require_paths:
|
63
|
+
- lib
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
hash: 3
|
70
|
+
segments:
|
71
|
+
- 0
|
72
|
+
version: "0"
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 3
|
79
|
+
segments:
|
80
|
+
- 0
|
81
|
+
version: "0"
|
82
|
+
requirements: []
|
83
|
+
|
84
|
+
rubyforge_project: anniversary
|
85
|
+
rubygems_version: 1.4.1
|
86
|
+
signing_key:
|
87
|
+
specification_version: 3
|
88
|
+
summary: Add method to Ruby's Date to get [years, months, days] between two dates
|
89
|
+
test_files:
|
90
|
+
- spec/lib/date_additions_spec.rb
|
91
|
+
- spec/spec_helper.rb
|