Frank DENIS random thoughts.

An age is not a duration

Once you know the birth date, how to compute how old someone is?

A common belief for computer geeks is that an age is a duration. Here’s a typical function that illustrates this.

require "time"
DURATION = 1461 * 24 * 60 * 60 / 4
def age(d)
  ((Time.now - Time.parse(d)) / DURATION).floor
end

Let’s see:

age "1977-04-13"
=> 30

It seems to work. But it actually doesn’t.

For non-computer geeks, birthdays are about dates. Someone born on April 13 will celebrate his birthday on April 13. This is the day he will legally get older.

Let’s change a bit the function in order to enter arbitrary dates:

def age(a, b)
  ((Time.parse(a) - Time.parse(b)) / DURATION).floor
end

Ok. I’m born on 1999-02-02. How old will I be on 2000-02-02?

age "2000-02-02 00:00:00", "1999-02-02"
=> 0

WRONG. On 02-02 I will be 1.

I’m born on 2000-02-28. How old will I be on 2001-02-27?

age "2001-02-27 06:00:00", "2000-02-28"
=> 1

WRONG AGAIN. On 2001-02-27 I will still be 0. I will be 1 on 02-28. Yes, ask mum.

I’m born on 1999-03-01. How old will I be on 2000-02-29?

age "2000-02-29 06:00:00" "1999-03-01"
=> 1

WRONG AGAIN. If my birthday is on 03-01, I will celebrate it on 03-01, not on 02-29.

For the record, here’s a simple way to get the correct age (adapted from a code snippet by Marc Love):

def age(d)
  date = Time.parse(d)
  now = Date.today
  age = now.year - date.year
  if now.month < date.month ||
     (now.month == date.month && date.day >= now.day)
    age = age - 1
  end
  return age
end