On 3/16/07, Pit C. [email protected] wrote:
There are 3 years between 2001-03-02 and 2004-03-01
Thanks, yep my bad!
Here’s a refined attempt.
I’ve fixed that problem and I’ve also added support to specify a day
to be used as the anniversary date for a leap-day. I did extensive
research (on Wikipedia ) and it seems that:
- People born on February 29 are called leaplings.
- 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.
- There are some jurisdictions, e.g. Taiwan which use 28 February
instead.
Although some leaplings try to pass themselves off as approximately
1/4 their legal age, I haven’t made allowances for that in the
following code:
rick@frodo:/public/rubyscripts$ cat datemath.rb
require ‘date’
class Date
def leap_year?
year % 400 == 0 || year % 100 != 0 && year % 4 == 0
end
def leap_day?
month = 2 && day == 29
end
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
return the ‘legal’ anniversary day cooresponding to first in the
year of last
This is the first date unless that date is leap day (29 February
xxxx) and the
second date is within a leap year.
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/