9

I currently have this less-than-ideal solution:

  def years_between_dates(date_from, date_to)
    ((date_to.to_time - date_from.to_time) / 1.year.seconds).floor
  end

The calculation doesn't have to be exact (w/ leap years etc), but does need to be fairly accurate and take into account months. 3.8 years should return 3 years, hence the floor.

I am converting to_time to account for both Date, Time, and DateTime.

I can't help but think there is a more succinct way of doing the above.

Damien Roche
  • 13,189
  • 18
  • 68
  • 96

4 Answers4

4

Seems like yours is in fact the most elegant way.

Even in the definition of distance_of_time_in_words rails has:

distance_in_minutes = ((to_time - from_time) / 60.0).round
distance_in_seconds = (to_time - from_time).round

Reference

A little better version could be:

def years_between_dates(date_from, date_to)
  ((date_to - date_from) / 365).floor
end
Vedant Agarwala
  • 18,146
  • 4
  • 66
  • 89
4

I stumbled across this looking for something else...

Am I crazy? Can't you just do:

def years_between_dates(date_from, date_to)
  date_to.year - date_from.year
end

or if you needed it to say "years" afterwards:

def years_between_dates(date_from, date_to)
  return "#{date_to.year - date_from.year} years"
end

I see that Piioo is right, here is a revised version. But it also doesn't compensate for leap years, which would require something more elaborate. I wouldn't use this for longer periods where accuracy is key.

def years_between_dates(date_from, date_to)
  years = (date_to - date_from).to_i / 365
  return "#{years} years"
end
bryanfeller
  • 336
  • 4
  • 8
1

if you want to get the real years between two dates, you have to consider the months and days, for example if you want to get the dates between 2010-10-01 to 2021-09-09 , the real years must be 10 years. Then you can use the next function:

  def years_between_dates(since_date, until_date)
    years = until_date.year - since_date.year
    if (until_date.month < since_date.month) ||
       (until_date.month == since_date.month && until_date.day < since_date.day)
      years -= 1
    end
    years
  end
Community
  • 1
  • 1
andres.ara
  • 206
  • 2
  • 8
  • can this condition be simplified to `until_date.month <= since_date.month && until_date.day < since_date.day`? – CaTs Mar 03 '22 at 08:11
1

Simple as:

((Time.now-1.year.ago)/1.year).abs
nazar kuliyev
  • 1,215
  • 1
  • 12
  • 13