Here's a refined attempt.
1) People born on February 29 are called leaplings.
2) For legal purposes most jurisdictions consider 1 March to be the
birthdate of a leapling in non-leap years for the purposes of
determining legal age.
3) There are some jurisdictions, e.g. Taiwan which use 28 February instead.
# The lyday is an altered yday. It is computed as if every year
# was a leap year. It's purpose is to determine whether a date has
# been 'virtually' crossed
def lyday
yday + ((leap_year? || yday < 60) ? 0 : 1)
end
···
On 3/16/07, Pit Capitain <pit@capitain.de> wrote:
Rick DeNatale schrieb:
> I think that this does the right thing:
> (...)
tryit(Date.new(2007,3,1), Date.new(2004,3,1))
tryit(Date.new(2004,3,1), Date.new(2001,3,2))
# =>
There are 2 years between 2004-03-01 and 2007-03-01
There are 3 years between 2001-03-02 and 2004-03-01
#
# The leapling date is 1 March, xxxx by default. The year of the
leapling date is
# ignored.
def self.ly_adjust(first, second, leapling_date)
if first.leap_day? && !second.leap_year?
leapling_date ||= Date.new(2004,3,1)
Date.new(first.year, leapling_date.month, leapling_date.day)
else
first
end
end
# return the number of years since the given date.
# leapling date is a date, (in any year) which is
# considered the anniversary of February 29 in non leap years.
# In most jurisdictions the legal birthday in non-leap years for determining
# legal ages is March 1, which is the default, however some jurisdictions
# legislate another date, most commonly February 28.
def years_since(date,leapling_date = nil)
first, last = *(self >= date ? [date, self] : [self, date])
first = Date.ly_adjust(first,last, leapling_date)
(self <=> date) * ((last.year - first.year) - (first.lyday >
last.lyday ? 1 : 0))
end
end
# The following methods demonstrate and test the above code.
# These really should be Test::Unit test cases, but I think that this form works
# better for showing what the code does as well as verification.
#
# tryit displays the number of years between an end date and a start date
# for leapling_dates of nil, 1 March, and 28 February,
# it prints each result, and returns an array of the three results.
def tryit(start_date,end_date)
leapling_dates = [nil]
result =
for ld in [nil, Date.new(2000,3,1), Date.new(2000,2,28)]
puts "With leapling_date of #{ld}" if ld
diff = end_date.years_since(start_date,ld)
result << diff
puts "There are #{diff} years between #{start_date} and #{end_date}"
end
puts
result
end
# tryit2 takes two dates, and the array expected from tryit
# It calls tryit, checks the result and prints an error message if
# the results aren't as expected.
# It then reverses the arguments which should result in negated
# values of the expected results.
def tryit2(start_date,end_date,expected)
puts "***** Error *****" unless expected == tryit(start_date, end_date)
expected = expected.map {|e| -e}
puts "***** Error *****" unless expected == tryit(end_date, start_date)
end
tryit2(Date.new(2000,3,14), Date.new(2007,3,15), [7, 7, 7])
tryit2(Date.new(2000,3,15), Date.new(2007,3,15), [7, 7, 7])
tryit2(Date.new(2000,3,16), Date.new(2007,3,15), [6, 6, 6])
tryit2(Date.new(2000,2,29), Date.new(2007,2,27), [6, 6, 6])
tryit2(Date.new(2000,2,29), Date.new(2007,2,28), [6, 6, 7])
tryit2(Date.new(2000,2,29), Date.new(2007,3,1), [7, 7, 7])
tryit2(Date.new(2000,2,29), Date.new(2007,3,2), [7, 7, 7])
tryit2(Date.new(2004,3,1), Date.new(2007,3,1), [3, 3, 3])
rick@frodo:/public/rubyscripts$ ruby datemath.rb
There are 7 years between 2000-03-14 and 2007-03-15
With leapling_date of 2000-03-01
There are 7 years between 2000-03-14 and 2007-03-15
With leapling_date of 2000-02-28
There are 7 years between 2000-03-14 and 2007-03-15
There are -7 years between 2007-03-15 and 2000-03-14
With leapling_date of 2000-03-01
There are -7 years between 2007-03-15 and 2000-03-14
With leapling_date of 2000-02-28
There are -7 years between 2007-03-15 and 2000-03-14
There are 7 years between 2000-03-15 and 2007-03-15
With leapling_date of 2000-03-01
There are 7 years between 2000-03-15 and 2007-03-15
With leapling_date of 2000-02-28
There are 7 years between 2000-03-15 and 2007-03-15
There are -7 years between 2007-03-15 and 2000-03-15
With leapling_date of 2000-03-01
There are -7 years between 2007-03-15 and 2000-03-15
With leapling_date of 2000-02-28
There are -7 years between 2007-03-15 and 2000-03-15
There are 6 years between 2000-03-16 and 2007-03-15
With leapling_date of 2000-03-01
There are 6 years between 2000-03-16 and 2007-03-15
With leapling_date of 2000-02-28
There are 6 years between 2000-03-16 and 2007-03-15
There are -6 years between 2007-03-15 and 2000-03-16
With leapling_date of 2000-03-01
There are -6 years between 2007-03-15 and 2000-03-16
With leapling_date of 2000-02-28
There are -6 years between 2007-03-15 and 2000-03-16
There are 6 years between 2000-02-29 and 2007-02-27
With leapling_date of 2000-03-01
There are 6 years between 2000-02-29 and 2007-02-27
With leapling_date of 2000-02-28
There are 6 years between 2000-02-29 and 2007-02-27
There are -6 years between 2007-02-27 and 2000-02-29
With leapling_date of 2000-03-01
There are -6 years between 2007-02-27 and 2000-02-29
With leapling_date of 2000-02-28
There are -6 years between 2007-02-27 and 2000-02-29
There are 6 years between 2000-02-29 and 2007-02-28
With leapling_date of 2000-03-01
There are 6 years between 2000-02-29 and 2007-02-28
With leapling_date of 2000-02-28
There are 7 years between 2000-02-29 and 2007-02-28
There are -6 years between 2007-02-28 and 2000-02-29
With leapling_date of 2000-03-01
There are -6 years between 2007-02-28 and 2000-02-29
With leapling_date of 2000-02-28
There are -7 years between 2007-02-28 and 2000-02-29
There are 7 years between 2000-02-29 and 2007-03-01
With leapling_date of 2000-03-01
There are 7 years between 2000-02-29 and 2007-03-01
With leapling_date of 2000-02-28
There are 7 years between 2000-02-29 and 2007-03-01
There are -7 years between 2007-03-01 and 2000-02-29
With leapling_date of 2000-03-01
There are -7 years between 2007-03-01 and 2000-02-29
With leapling_date of 2000-02-28
There are -7 years between 2007-03-01 and 2000-02-29
There are 7 years between 2000-02-29 and 2007-03-02
With leapling_date of 2000-03-01
There are 7 years between 2000-02-29 and 2007-03-02
With leapling_date of 2000-02-28
There are 7 years between 2000-02-29 and 2007-03-02
There are -7 years between 2007-03-02 and 2000-02-29
With leapling_date of 2000-03-01
There are -7 years between 2007-03-02 and 2000-02-29
With leapling_date of 2000-02-28
There are -7 years between 2007-03-02 and 2000-02-29
There are 3 years between 2004-03-01 and 2007-03-01
With leapling_date of 2000-03-01
There are 3 years between 2004-03-01 and 2007-03-01
With leapling_date of 2000-02-28
There are 3 years between 2004-03-01 and 2007-03-01
There are -3 years between 2007-03-01 and 2004-03-01
With leapling_date of 2000-03-01
There are -3 years between 2007-03-01 and 2004-03-01
With leapling_date of 2000-02-28
There are -3 years between 2007-03-01 and 2004-03-01
--
Rick DeNatale
My blog on Ruby
http://talklikeaduck.denhaven2.com/