Calculate age in Rails with a birthday

January 28, 2008

 
No Gravatar

This is one of those random things that shows up every now and then.

1
2
3
4
5
6
7
8
9
#this will approximate the user's age
  def calculate_age(birthday)
    Date.today.year - birthday.to_date.year
  end
 
#this is exact
def calculate_age(birthday)
  (Date.today - birthday).to_i / 365
end
  • This seems to do the job:

    ((Time.now.to_time - birthday.to_time) / 1.years).to_i
  • NOV
    today, birthday = [Date.today, self].map do |d|
    d.strftime("%Y%m%d").to_i
    end
    (today - birthday) / 10000
  • NOV

    class Date
    def to_age
    integer_style = "%Y%m%d"
    today = Date.today.strftime(integer_style).to_i
    birthday = Date.today.strftime(integer_style).to_i
    (today - birthday) / 10000
    end
    end

    => birthday.to_age

    If the birthday.class.class_name == Time, you can use below.

    http://d.hatena.ne.jp/secondlife/20050922/11273...
  • rolf

    def age(birthday)
    y=(Date.today.year) - (birthday.year)
    m=(Date.today.month)-(birthday.month)
    d=(Date.today.day)-(birthday.day)
    case
    when (m<0)
    age=y-1
    when (m=0)
    case
    when(d0)
    age=y
    end
    when (m>0)
    age=y
    end
    age
    end
  • rolf
    I've put the next few lines in my application_helper, I'm using it to calculate the age of people today(but this could be any date), just passing @person.birthday to it. gr rolf


    def age(birthday)
    y=(Date.today.year) - (birthday.year)
    m=(Date.today.month)-(birthday.month)
    d=(Date.today.day)-(birthday.day)
    case
    when (m<0)
    age=y-1 #april-mei=-1; april-april=0; april-maart=1#15-15=0; 15-16=-1; 15-13=2
    when (m=0)
    case
    when(d0)
    age=y
    end
    when (m>0)
    age=y
    end
    age
    end
  • api
    ( (Date.today - birthday).to_i / 365.25).floor this will work with leap-year
  • Hi Tobi,

    We couldn't get the above to work. Here's what worked for us in the controller:

    birthday = Time.mktime(params[:year], params[:month].to_i, params[:day].to_i)
    @age = age(birthday)

    protected

    def age( birthday )
    age = Date.today.year - birthday.year
    today = Time.now
    age -= 1 if birthday > today.years_ago( age )
    age
    end
  • Tobi
    ups it should be:

    def age( birthday )
    age = Date.today.year - birthday.year
    age -= 1 if birthday > Date.today.years_ago( age )
    age
    end
  • Tobi
    Hey thanks for your solution.

    The exact age with leap years seams a bit tricky. Unfortunately the above solution has still 2 problems:
    1. it changes the actual birthday data which we may need later in progress
    2. it raises an "InvalidDate Exception" if now is a leapyear day, e.g. 2008/2/29

    I solved this with:


    def age( birthday )
    return 0 unless info.birthday
    age = Date.today.year - birthday.year
    age -= 1 if birthday > Date.today.years_ago( age )
    age
    end

    check http://pastie.caboo.se/165173 for the belonging tests
  • anonymous
    i also was not aware of all the gotchas involved with dates, times and timezones...

    somehow i missed this detail:
    you cannot compare DateTime with Time, so use the to_date Method on both Objects

    def age
      now = Time.now.utc.to_date
      now.year - birthday.year - (birthday.to_date.change(:year => now.year) > now ? 1 : 0)
    end
  • Jonathan
    Thanks for that post. When we did the age calculation it was meant to give us an approximation of our user base. Since it was not critical to have 100% accurate information, leap year was overlooked :)
  • anonymous
    the result of the second example is not very accurate because leap years are ignored.
    to get around this, just use the following:

    def age
    now = Time.now.utc
    now.year - birthday.year - (birthday.to_time.change(:year => now.year) > now ? 1 : 0)
    end
blog comments powered by Disqus