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:
Here's my solution which also allows calculating the age at a specific date:
def age on = Date.today
(_ = on.year - birthday.year) - (on < birthday.since(_.years) ? 1 : 0)
end
def birthday(user)
today = Date.today
new = user.birthday.to_date.change(:year => today.year)
user = user.birthday
if Date.civil_to_jd(today.year, today.month, today.day) >= Date.civil_to_jd(new.year, new.month, new.day)
age = today.year - user.year
else
age = (today.year - user.year) -1
end
age
end
If you don't care about a day or two, this would be shorter and pretty self-explanitory.
(Time.now - Time.gm(1986, 1, 27).to_i).year - 1970
One liner in Ruby on Rails (ActiveSupport). Handles leap years, leap seconds and all.
def age(birthday)
(Time.now.to_s(:number).to_i - birthday.to_time.to_s(:number).to_i)/10e9.to_i
end
Logic from here - Calculate age in C#
Assuming both dates are in same timezone, if not call utc()
before to_s()
on both.
The following seems to work (but I'd appreciate it if it was checked).
age = now.year - bday.year
age -= 1 if now.to_a[7] < bday.to_a[7]
Because Ruby on Rails is tagged, the dotiw gem overrides the Rails built-in distance_of_times_in_words and provides distance_of_times_in_words_hash which can be used to determine the age. Leap years are handled fine for the years portion although be aware that Feb 29 does have an effect on the days portion that warrants understanding if that level of detail is needed. Also, if you don't like how dotiw changes the format of distance_of_time_in_words, use the :vague option to revert to the original format.
Add dotiw to the Gemfile:
gem 'dotiw'
On the command line:
bundle
Include the DateHelper in the appropriate model to gain access to distance_of_time_in_words and distance_of_time_in_words_hash. In this example the model is 'User' and the birthday field is 'birthday.
class User < ActiveRecord::Base
include ActionView::Helpers::DateHelper
Add this method to that same model.
def age
return nil if self.birthday.nil?
date_today = Date.today
age = distance_of_time_in_words_hash(date_today, self.birthday).fetch("years", 0)
age *= -1 if self.birthday > date_today
return age
end
Usage:
u = User.new("birthday(1i)" => "2011", "birthday(2i)" => "10", "birthday(3i)" => "23")
u.age