Very nice piece of code Rick! I'm a Ruby newbee and I find it facinating 
when I see code that applies better the "Ruby Way". Thanks for sharing.

I borrow parts of your code and rewrote the method I sent:

class Date
  def elapsedYearsAndDays(rangeDate)
    startDate, endDate = *(self >= rangeDate ? [rangeDate, self] : 
[self, rangeDate])
    #This is the real problem: Febraury 29th!
    isMagicDate = (startDate.month == 2) && (startDate.day == 29)
    startDate += 1 if !endDate.leap? && isMagicDate
    elapsedYears = endDate.year - startDate.year
    previousStartDate = Date.new(endDate.year, startDate.month, 
startDate.day)
    if endDate < previousStartDate
      elapsedYears -= 1
      previousStartDate = Date.new(endDate.year - 1, startDate.month, 
startDate.day)
      previousStartDate -= 1 if previousStartDate.leap? && isMagicDate
    end
    return elapsedYears, endDate - previousStartDate
  end
end

startDates = [Date.today,
        Date.new(1963, 11, 22),
        Date.new(2007, 3, 1),
        Date.new(2004, 3, 1),
        Date.new(2004, 2, 29),
        Date.new(2004, 3, 1),
        Date.new(2004, 2, 29),
        Date.new(2007,3,15),
        Date.new(2000,3,14)]

endDates = [Date.new(1963, 11, 22),
      Date.new(1963, 11, 22),
      Date.new(2004, 3, 1),
      Date.new(2001, 3, 2),
      Date.new(2001, 3, 1),
      Date.new(2001, 3, 1),
      Date.new(2009, 3, 1),
      Date.new(2000,3,14),
      Date.new(2007,3,15)]

startDates.each_with_index do |startDate, index|
  elapsedYears, elapsedDays = 
startDate.elapsedYearsAndDays(endDates[index])
  daysMessage = (elapsedDays > 0) ? (" and #{elapsedDays} day(s)") : ''
  puts "Start date: #{startDate} End date: #{endDates[index]}"
  puts "Elapsed time: #{elapsedYears} year(s)#{daysMessage}\n\n"
end

=begin
---------------------------------------------------------------------------
At the same time I took your code and added the same test dates I used:
=end

require 'date'
class Date

  # return the number of days since the beginning of the year
  def years_since(date)
    # The parens in the expression below aren't strictly necessary, but
    # I think it makes what's going on a little bit clearer.
    first, last = *(self >= date ? [date, self] : [self, date])
    (self <=> date) * ((last.year - first.year) - (first.yday > 
last.yday ? 1 : 0))
  end
end

startDates = [Date.today,
        Date.new(1963, 11, 22),
        Date.new(2007, 3, 1),
        Date.new(2004, 3, 1),
        Date.new(2004, 2, 29),
        Date.new(2004, 3, 1),
        Date.new(2004, 2, 29),
        Date.new(2007,3,15),
        Date.new(2000,3,14)]

endDates = [Date.new(1963, 11, 22),
      Date.new(1963, 11, 22),
      Date.new(2004, 3, 1),
      Date.new(2001, 3, 2),
      Date.new(2001, 3, 1),
      Date.new(2001, 3, 1),
      Date.new(2009, 3, 1),
      Date.new(2000,3,14),
      Date.new(2007,3,15)]

startDates.each_with_index do |startDate, index|
  elapsedYears = startDate.years_since(endDates[index])
  puts "Start date: #{startDate} End date: #{endDates[index]}"
  puts "Elapsed time: #{elapsedYears} year(s)\n\n"
end

=begin
As you can see from the results, both pieces of code give the same 
results
except when a leap year is involved. I think my version is correct in 
those cases :) because we don't want to say that a complete year has 
passed until that is totally true.
Regards,

Nando
=end

-- 
Posted via http://www.ruby-forum.com/.