How to calculate how many years passed since a given date in Ruby?

I have a gem/plugin called dotiw that has a distance_of_time_in_words_hash that will return a hash like: { :years => 59, :months => 11, :days => 27 }. From that you could work out if it's near a certain limit.


Do you want age as people typically understand it, or are you looking for a precise measure of time elapsed? If the former, there is no need to worry about leap years and other complications. You simply need to compute a difference in years and reduce it if the person has not had a birthday yet this year. If the latter, you can convert seconds elapsed into years, as other answers have suggested.

def age_in_completed_years (bd, d)
    # Difference in years, less one if you have not had a birthday this year.
    a = d.year - bd.year
    a = a - 1 if (
         bd.month >  d.month or 
        (bd.month >= d.month and bd.day > d.day)
    )
    a
end

birthdate = Date.new(2000, 12, 15)
today     = Date.new(2009, 12, 14)

puts age_in_completed_years(birthdate, today)

An approach that handles leap years

Whenever you're calculating elapsed years since a date, you have to decide how to handle leap year. Here is my approach, which I think is very readable, and is able to take leap years in stride without using any "special case" logic.

def years_completed_since(start_date, end_date)

  if end_date < start_date
    raise ArgumentError.new(
      "End date supplied (#{end_date}) is before start date (#{start_date})"
    )
  end

  years_completed = end_date.year - start_date.year

  unless reached_anniversary_in_year_of(start_date, end_date)
    years_completed -= 1
  end

  years_completed
end

# No special logic required for leap day; its anniversary in a non-leap
# year is considered to have been reached on March 1.
def reached_anniversary_in_year_of(original_date, new_date)
  if new_date.month == original_date.month
    new_date.day >= original_date.day
  else
    new_date.month > original_date.month
  end
end

require 'date'

def years_since(dt)
    delta = (Date.today - Date.parse(dt)) / 365
    delta.to_i
end