I\'d like to get a person\'s age from its birthday. now - birthday / 365
doesn\'t work, because some years have 366 days. I came up with the following code:
The answers so far are kinda weird. Your original attempt was pretty close to the right way to do this:
birthday = DateTime.new(1900, 1, 1)
age = (DateTime.now - birthday) / 365.25 # or (1.year / 1.day)
You will get a fractional result, so feel free to convert the result to an integer with to_i
. This is a better solution because it correctly treats the date difference as a time period measured in days (or seconds in the case of the related Time class) since the event. Then a simple division by the number of days in a year gives you the age. When calculating age in years this way, as long as you retain the original DOB value, no allowance needs to be made for leap years.
DateHelper can be used to get years only
puts time_ago_in_words '1999-08-22'
almost 20 years
I know I'm late to the party here, but the accepted answer will break horribly when trying to work out the age of someone born on the 29th February on a leap year. This is because the call to birthday.to_date.change(:year => now.year)
creates an invalid date.
I used the following code instead:
require 'date'
def age(dob)
now = Time.now.utc.to_date
now.year - dob.year - ((now.month > dob.month || (now.month == dob.month && now.day >= dob.day)) ? 0 : 1)
end
To account for leap years (and assuming activesupport presence):
def age
return unless birthday
now = Time.now.utc.to_date
years = now.year - birthday.year
years - (birthday.years_since(years) > now ? 1 : 0)
end
years_since
will correctly modify the date to take into account non-leap years (when birthday is 02-29
).
I like this one:
now = Date.current
age = now.year - dob.year
age -= 1 if now.yday < dob.yday
def computed_age
if birth_date.present?
current_time.year - birth_date.year - (age_by_bday || check_if_newborn ? 0 : 1)
else
age.presence || 0
end
end
private
def current_time
Time.now.utc.to_date
end
def age_by_bday
current_time.month > birth_date.month
end
def check_if_newborn
(current_time.month == birth_date.month && current_time.day >= birth_date.day)
end```