View Full Version : Timespan between two dates.

02-18-2008, 01:56 AM

I have a problem in PHP - I have a person's birthdate, and I would like to know how old he or she is.

I had though of just determining the age in seconds, then dividing by however many seconds are in a year, but that won't work because of leap years.

I'd like a function where I can put in 2 dates, or 2 timestamps, and have it return the number of years between the two. The best I could think of was doing a date('Y',$age_timestamp) but that could still be off by a day depending on leap years again.

Is there something in PHP that I can use to get the result I need?

02-18-2008, 04:54 AM
Date calculations are really a pain, especially when
it gets into timezones (hour calculations).

But I've assumed you already looked here:

Here are a lot of attempts ... some better than others:

02-18-2008, 09:04 AM
Yeah, I ended up using the date() function for now. I would like something better, though.

I guess I could run it through MySQL - a bit cumbersome, but I believe it can do what I want.

I looked at a couple of the ones in the google search too - it's funny - there is one where the person gets the birthday from a MySQL database, then tries to compute the age with PHP - it would make much more sense to just use the query to make MySQL calculate the age ;)

I would be doing that except I'm trying to calculate the age for storage in a session before I put the birthday into the database.

02-18-2008, 11:27 AM
Hi, yep, this is a pain in the arse!

You can do it pure PHP, but using a hack - compute the year as it would be if the person's birthday was the start of Unix Time and then subtract Unix Time at the real Unix 0 (as follows!):

$birthday_date = "5th September 1980"; //This person will now be 27.
$birthday_unixtime = strtotime($birthday_date); //Get their birthday as a Unix timestamp.
$now_unixtime = time(); //Get the current unix timestamp.
$difference_unixtime = $now_unixtime - $birthday_unixtime; //Get the year "relative" to the person's birthday.
$age_years = date("Y", $difference_unixtime) - date("Y", 0); //Do the subtraction.

var_dump($age_years); //Happy time.

This should work for dates before 1970 because strtotime will give negative timestamps for unix timestamps before 1st Jan 1970.

02-18-2008, 11:29 AM
The definition of a persons age is the difference in the year, minus one if their birthday has not occurred in the current year.

If you are using msyql, you can do this directly in the query - http://dev.mysql.com/doc/refman/5.0/en/date-calculations.html

Here is the same calculation using php -

// calculate age using php
// (Current year - birth year) - 1 (if current mm-dd < birthday mm-dd)

// some test values
$dates = array();
$dates[] = "2008-01-16";
$dates[] = "2007-01-15";
$dates[] = "1900-01-15";
$dates[] = "1958-11-11";
$dates[] = "2006-01-16";

// some of the presidential candidates
$dates[] = "1947-10-26";
$dates[] = "1961-08-04";
$dates[] = "1953-06-10";
$dates[] = "1947-11-15";
$dates[] = "1942-11-20";
$dates[] = "1944-05-27";
$dates[] = "1930-05-13";
$dates[] = "1946-10-08";

function year($date)
return substr($date, 0, 4);
} // end of year function

function mmdd($date)
return substr($date, 5,5);
} // end of mmdd function

function age($date)
$today = date("Y-m-d");
return year($today) - year($date) - (mmdd($today) < mmdd($date));
} // end of function age

foreach($dates as $date)
echo "DOB: $date, Age: " . age($date) . "<br />";

Edit: I started writing this post before msle's post, but by not depending on the php date() function in the calculation (the above code only uses it to get the current date, which could be entered through other means), you avoid all the problems with its' minimum and maximum timestamp values, which are not DOB/age friendly.

02-18-2008, 02:20 PM
jonnyb didn't specify the resolution of the birthdate...
for example, 40.25 years, or just 40, or 40 years, 2 months, 3 days ... etc.

I think that "resolution" would be the whole key to what script to use.

02-19-2008, 12:47 AM
I was going for whole years ;)

Thanks for the excellent posts though. I should be updating the script soon and will add a better option than the one I used yesterday in a pinch.