Calculating Age

Sometimes you would like to display the age of an entry as compared to a specific date. In the case, of my daughter's blog, I've displayed her actual age at the time of each post, based on her birth date and the authored-on date of the entry.

Updated to support time difference too.

Updated to correct date_delta function's accuracy.

This is a Movable Type/PHP tip. I haven't written a Movable Type plugin to do this yet, but I probably will shortly. If you're using something other than PHP-- like ASP-- you can adapt this technique to work for your environment.

First, you need to this PHP code which does the calculation itself:

function date_delta($ts_start_date, $ts_end_date) {
  $secs_in_day = 86400;

  $i_years = gmdate('Y', $ts_end_date) - gmdate('Y', $ts_start_date);
  $i_months = gmdate('m', $ts_end_date) - gmdate('m', $ts_start_date);
  $i_days = gmdate('d', $ts_end_date) - gmdate('d', $ts_start_date);
  if ($i_days < 0)
    $i_months--;
  if ($i_months < 0) {
    $i_years--;
    $i_months += 12;
  }
  if ($i_days < 0) {
    $i_days = gmdate('d', gmmktime(0, 0, 0,
      gmdate('m', $ts_start_date)+1,
      0,
      gmdate('Y', $ts_start_date))) -
      gmdate('d', $ts_start_date);
    $i_days += gmdate('d', $ts_end_date);
  }

  # calculate HMS delta
  $f_delta = $ts_end_date - $ts_start_date;
  $f_secs = $f_delta % $secs_in_day;
  $f_secs -= ($i_secs = $f_secs % 60);
  $i_mins = intval($f_secs/60)%60;
  $f_secs -= $i_mins * 60;
  $i_hours = intval($f_secs/3600);

  return array($i_years, $i_months, $i_days,
               $i_hours, $i_mins, $i_secs);
}

function calculate_age($s_start_date,
    $s_end_date = '',
    $b_show_days = 0) {
  $b_show_time = strlen($s_start_date > 8);
  $ts_start_date =
    mktime(substr($s_start_date, 8, 2),
      substr($s_start_date, 10, 2),
      substr($s_start_date, 12, 2),
      substr($s_start_date, 4, 2),
      substr($s_start_date, 6, 2),
      substr($s_start_date, 0, 4));
  if ($s_end_date) {
    $ts_end_date =
      mktime(substr($s_end_date, 8, 2),
        substr($s_end_date, 10, 2),
        substr($s_end_date, 12, 2),
        substr($s_end_date, 4, 2),
        substr($s_end_date, 6, 2),
        substr($s_end_date, 0, 4));
  } else {
    $ts_end_date = time();
  }

  list ($i_age_years, $i_age_months, $i_age_days,
        $i_age_hours, $i_age_mins, $i_age_secs) =
       date_delta($ts_start_date, $ts_end_date);

  # output
  $s_age = '';
  if ($i_age_years)
    $s_age .= "$i_age_years year".
      (abs($i_age_years)>1?'s':'');
  if ($i_age_months)
    $s_age .= ($s_age?', ':'').
      "$i_age_months month".
      (abs($i_age_months)>1?'s':'');
  if ($b_show_days && $i_age_days)
    $s_age .= ($s_age?', ':'').
      "$i_age_days day".
      (abs($i_age_days)>1?'s':'');

  if ($b_show_time && $i_age_hours)
    $s_age .= ($s_age?', ':'').
      "$i_age_hours hour".
      (abs($i_age_hours)>1?'s':'');
  if ($b_show_time && $i_age_mins)
    $s_age .= ($s_age?', ':'').
      "$i_age_mins minute".
      (abs($i_age_mins)>1?'s':'');
  if ($b_show_time && $i_age_secs)
    $s_age .= ($s_age?', ':'').
      "$i_age_secs second".
      (abs($i_age_secs)>1?'s':'');
  return $s_age;
}

This function takes one to three parameters. The first parameter is the 'start date' -- the date you want to compare against. In the case of Savannah's blog, this is her birth date. The second parameter is the date of the event (the blog entry's authored-on date). You can leave the second parameter out if you want to compare the 'start date' to the current system date (this uses the current system time of your server). Last, the 'show days' parameter is for whether you want to print days or not. If you do, pass a value of 1, otherwise, pass a 0 or don't pass a value at all and it will only return age in terms of months and years.

Here's an example of how to use this function in your Movable Type template. This is taken from Savannah's main index template:

(age: <?= calculate_age('19990819','<$MTEntryDate
    format="%Y%m%d"$>', 1) ?> old)


Note that the format of the dates are always YYYYMMDD or YYYYMMDDHHMISS if you want the time difference too (where YYYY=year, MM=month, DD=day, HH=24 hour value, MI=minutes, SS=seconds).

Here's an example that includes the time difference:

Posted <?= calculate_age('<$MTEntryDate
    format="%Y%m%d%H%M%S"$>','',1) ?> ago.

That's all there is to it!

TrackBack

TrackBack URL for this entry:
http://bradchoate.com/mt/feedback/tb/26

Listed below are links to weblogs that reference Calculating Age:

» changing things up from lily of the valley
autumn cleaning around here (ok, so I admit I broke out an actual vacuum the other day... but this is another story!) [Read More]

16 Comments

notaw said:

Nice script! You wouldn't happen to be able to point me in the right direction for slightly adjusting your script to display the time that has gone by since a post was posted.
Sort of like this:
Posted 10hrs ago.
Posted 5 mins ago etc.
Any help or pointers would be appreciated.
-N.

Jason said:

Very good idea you came up with! I have a feeling I will be using it in about three months for pretty much the same thing. Very cute daughter by the way.

pat said:

when i attempt to implement this script using the server date as a reference (i.e. not using the MTEntryDate tag), it always displays years, months, days, minutes and seconds regardless of how i attempt to format the date. i would like to make this relative to my server date, but only show years, months and days.

any ideas?

randy said:

PHP Newbie - Help Needed & Appreciated.

Where do I paste this code into my page? Is the first part that does the calculation actually one php function? or 2? Do I need to include the php tags?

Thanks ahead of time for your assistance.

Keep up the good work!
wishiwasgolfing

Jake said:

Do you plan to release this as a Movabletype plugin anytime soon? I noticed you mentioned that you might... but it's been a few months since then. The way I have my blog set up right now... (xml parsed into php) this won't work.

amancay said:

Is there any way to include "if" commands to handle multiple authors???

mike said:

I'm very new to PHP, and I'm trying to use this tip to get my daughter's age on her blog, but the PHP parser seems to quit at the first 'greater than sign' (line 29 or so, $s_start_date > 8) and just prints the rest of the PHP on the page. I don't have access to the PHP setup as I am using a commercial ISP. I thought the PHP parser would wait until the '?>' to end the PHP lines. any help would be greatly appreciated.

btw, my daughter was born 09/17/1999, very close to your daughter. And congrats on the baby boy.

-Mike

mike said:

d'oh! I solved the problem with a .htaccess directive to look for the index.php4 file first. thanks for the great tools.

Andy said:

This script doesnt seem to support dates before January 1 1970 because it implements the unix time stamp. Is this right?

amancay said:

http://amancay.com/agenda/archives/001069.php
somehow registers as 24yrs, 11mos, 30days... even though it is clearly my 25th birthday... even yesterday registered as the same age (only hours older) odd format in the calculation???

btw birthdate=197711270045

amancay said:

woo hoo! It works perfectly (as far as I can tell) now!
Great job on follow-up, Brad!

Eric said:

I tried to use this for my daughter's blog, but when it got to 13 days using this:

The output was this:

I'm 1 year, 12 months, 11 days old today!

Clearly a bug with crossing a month boundary .. I don't have time to track it down at the moment, but it seems related to having the month and year be

Eric

Eric said:

Ok, so putting in PHP code doesn't work in this form. The input was 20030119 for the start date and 20030201 for the end date. It will spit out incorrect info even if you hardcode this into a PHP page, (i.e. not just when you run it through an MT template).

Output is as described in the previous comment.

best, Eric

The second line of the calculate_age function needs to be changed to:

$b_show_time = strlen($s_start_date) > 8;

...otherwise it will always show hours, minutes and seconds, and incorrectly at that.

Thanks for your work.
If it's already known that this script doesn't work for dates before 1970, could you --please-- give some clue of how to solve that problem?

hari said:

Sir, i want a simple program of how to get the date of birth from the Microsoft Acess database and calculate the date of birth with the present date ....

if u can do this favour it would be great
please show an example..

Thanking you

About

This article was published on July 12, 2002 9:12 AM.

The article previously posted was EzPop.

The next article is Internet Explorer rendering problem.

Many more can be found on the home page or by looking through the archives.

Powered by Movable Type