Page 1 of 1

Calculating age tutorial Rate Topic: -----

#1 Pilot-Doofy  Icon User is offline

  • New D.I.C Head
  • member icon

Reputation: 5
  • View blog
  • Posts: 11
  • Joined: 09-October 06

Posted 21 October 2006 - 05:25 PM

In this tutorial we'll look at the following:
1. How to create a timestamp from a date
2. How to find difference between timestamps
3. Account for negative timestamps (dates before 1/1/1970)
4. Calculate someone's age based on a DOB

First, let's look at the functions we'll be using. Please become familiar with these functions before proceeding with the tutorial.
time()
mktime()
floor()

Okay, let's get started! If you have ever used the date() function I'm sure that you know how it works. You give it a formatted date to output and a timestamp (even if you don't manually provide a timestamp the current timestamp is used). Well, the mktime() function is basically the opposite of that.

For instance, if we put this code into a script it would give us the timestamp for 12:00am on October 4, 2006 (today).
mktime(0, 0, 0, 10, 4, 2006);

Now, let me explain how it works in case you didn't remember from the online documentation. The parameters go in this order:
hour, minute, second, month, day, year, (DST)

The first 6 are pretty self explanitory. The 7th parameter is usually left off and just allows you to create timestamps based on DST (daylight savings time). For example, the following would give us the same timestamp from above but would account for DST.

mktime(0, 0, 0, 10, 4, 2006, 1);

As you can see, we set the 7th parameter to 1 (which is true in boolean logic).

I don't think I need to explain the time() function, but if you were absolutely too lazy to read the documentation and you know nothing about PHP, it returns the current UNIX timestamp (starting from January 1, 1970). Hence, if you have a date before January 1, 1970 the timestamp will be negative or not exist (depending on how old the date is). You may think this isn't important but we'll run into problems later if we don't account for it.

Lastly, the floor() function is similar to round() or ceil() except that floor() founds down rather than evenly or upward as round() and ceil() do, respectively.

Alright, now let's look at some code:
<?php
$ageTime = mktime(0, 0, 0, 9, 9, 1919); // Get the person's birthday timestamp
$t = time(); // Store current time for consistency
$age = ($ageTime < 0) ? ( $t + ($ageTime * -1) ) : $t - $ageTime;
$year = 60 * 60 * 24 * 365;
$ageYears = $age / $year;

echo 'You are ' . floor($ageYears) . ' years old.';
?>


Okay, let's break it down line by line. The first line stores the timestamp for the DOB you're attempting to get the age of. Secondly we store $t in a variable both for short-hand use and so that we keep the same timestamp throughout the code. (If you get a timestamp at the top of the page and get one at the bottom of the page they could differ depending on how long it took the page to execute.)

The next line is the most important line in the code. Why do we use the ternary operator to check if the $ageTime timestamp is less than 0? Well, by checking if it's less than 0 we can determine if it is a negative value. Remember when I said negative timestamps could cause problems later? ;) Well, we're preventing those problems from happening here!

For example, let's say you have a timestamp of -3600, or 11:00pm December 31, 1969. Well, when we calculate the difference we need to subtract the the age timestamp ($ageTime) from the current timestamp. This works perfectly fine for anyone under the age of 36. ;) Well, if we were to subtract the timestamp for -3600 it would actually add 3600 onto the current timestamp. So technically it would say you're not even born yet, which I'm sure some older folks wouldn't mind hearing. ;)

Eitherway, that's not what we're trying to achieve. How do we fix this? Well, we can simply multiple the timestamp by a -1 which would reverse the number or make it positive. However, we only want to reverse the number IF the timestamp is negative, if it isn't then we leave it alone.

Okay, so that was a mouthfull, might want to reread the previous paragraphs until you have a firm grasp on the concept at hand. Once you do, feel free to procede.

The next steps are pretty easy. We simply store the amount of time in seconds that a year is so that we know what that number is being used for. The logic behind that number is this:

60 seconds (1 minute) x 60 minutes (1 hour, and a TV show lol) x 24 hours (1 day) x 365 days (1 year).

Note that this doesn't account for leap years and the extra day in those years. If you wanted to get really percise (which in most cases is useless) then you can easily find out how many leap years have occurred since that person's DOB and add the appropriate amount of days.

Next we divide the difference in the two timestamps by the $year variable, which splits their age into years.

We're done now, right? Sorry, not just yet.

We want to make this age calculator graceful. To do this, we need to round down the amount of years we get when we divide $ageYears by $year. The reason behind this is that when you tell someone your age and you're actually 22 years and 300 days old, you would still say you're 22. The idea is that you're 22 (or any other age) all the way up until your next birthday, so we want the age calculator to reflect this concept as well.

Okay, so we've used the floor() function to round down the person's age. Now we're all done. You can print the person's age, use it in profiles, or do whatever with it!

Pretty simple, eh?

Is This A Good Question/Topic? 3
  • +

Replies To: Calculating age tutorial

#2 satish4044  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 7
  • Joined: 25-April 07

Posted 25 April 2007 - 11:24 PM

really this tutorial is useful to me thanks for giving this type of good tutorial
Was This Post Helpful? 0
  • +
  • -

#3 neclon  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 05-March 08

Posted 05 March 2008 - 11:27 AM

I wanted to post an alternative that is somewhat simplified to the way we really do this kind of thing in our head. I needed to account for leap years because I needed accuracy. I also had a note to add that simplifies the above tutorial (since negative timestamps really do not change the outcome at all and the alternative formula given if it's below 0 gives the same result as simply subtracting).

Instead of trying to convert a final timestamp into years and rounding and accounting for leap years I just subtract the Date of birth year from this year and then subtract one more if their birthday has not come up yet. This takes advantage of PHP automatically converting strings to numbers for formulas. It also allows the date of birth input to be a little more dynamic with strtotime (which could be replaced by mktime if one was worried about resource efficiency:

//Calculate someone's age based on a date of birth string
$year = date("Y");  // Get this year as a string, date(string format, [timestamp default: now])
$dobtime = strtotime("04/09/1980"); // Get date of birth as a timestamp
$age = $year - date("Y",$dobtime);  // Take advantage of auto conversion to subtract this year from the year of the DOB
$bday = date("m/d/",$dobtime).$year; // Create a timestamp from their month and day of birth combined with this year
if((time()-strtotime())<0) $age = $age - 1; // Compare their bday for this year to current timestamp and subtract one from the year if their birthday has not occurred yet




One note on the above excellent tutorial:
$age = ($ageTime < 0) ? ( $t + ($ageTime * -1) ) : $t - $ageTime;

The handling of negative timestamps due to a date of birth being before 1970 is overcomplicating the code. The 2 above calculations are identical in result so there is really nothing different between them:

4 - 1 = 3
4 + (1*-1) = 4+(-1) = 3

4 - (-1) = 5
4 + (-1*-1) - 4+1 = 5

If you subtract a negative number you are adding. That is the desired result since the resultant timestamp needs to be bigger than the timestamp provided by (time()). For 2008 timestamp is 38 years. If you are born earlier than 1970 you are older than that so you need the additive result of subtracting the negative to get the full difference in time.

Mod edit - Please :code:
Was This Post Helpful? 0
  • +
  • -

#4 neclon  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 2
  • Joined: 05-March 08

Posted 24 March 2008 - 12:06 PM

View Postneclon, on 5 Mar, 2008 - 11:27 AM, said:

//Calculate someone's age based on a date of birth string
$year = date("Y"); // Get this year as a string, date(string format, [timestamp default: now])
$dobtime = strtotime("04/09/1980"); // Get date of birth as a timestamp
$age = $year - date("Y",$dobtime); // Take advantage of auto conversion to subtract this year from the year of the DOB
$bday = date("m/d/",$dobtime).$year; // Create a timestamp from their month and day of birth combined with this year
if((time()-strtotime())<0) $age = $age - 1; // Compare their bday for this year to current timestamp and subtract one from the year if their birthday has not occurred yet


Correction to code (forgot to put the the $bday variable into the strtotime argument on the last line):

//Calculate someone's age based on a date of birth string
$year = date("Y");  // Get this year as a string, date(string format, [timestamp default: now])
$dobtime = strtotime("04/09/1980"); // Get date of birth as a timestamp
$age = $year - date("Y",$dobtime);  // Take advantage of auto conversion to subtract this year from the year of the DOB
$bday = date("m/d/",$dobtime).$year; // Create a timestamp from their month and day of birth combined with this year
if((time()-strtotime($bday))<0) $age = $age - 1; // Compare their bday for this year to current timestamp and subtract one from the year if their birthday has not occurred yet


Mod edit - Please :code:
Was This Post Helpful? 0
  • +
  • -

#5 critical  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 06-August 08

Posted 06 August 2008 - 06:52 AM

Cheers I have been stuck for ages trying to suss out how this was done. Great post!!

This post has been edited by critical: 06 August 2008 - 07:03 AM

Was This Post Helpful? 0
  • +
  • -

#6 dwm206  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 1
  • Joined: 28-December 09

Posted 28 December 2009 - 02:44 PM

My date of birth is Jan 1, 1960. I tried your code as you described with a small twist. So it's currently 12/28/2009, I'm still 49. but when I do your calculation below I get that I'm 50. I'm not going to be fifty for 4 days. Help! :-)

$foo = split('-','1960-01-01');
		$ageTime = mktime(0,0,0,$foo[1],$foo[2],$foo[0]);
		$t = time();
		$age = ($ageTime < 0) ? ($t + ($ageTime * -1) ) : ($t - $ageTime);
$year = 60 * 60 * 24 * 365;
$ageYears = floor($age / $year);


David

Mod edit - Please :code:
Was This Post Helpful? 0
  • +
  • -

#7 Guest_ropsiU*


Reputation:

Posted 09 September 2010 - 07:07 AM

View Postdwm206, on 28 December 2009 - 01:44 PM, said:

My date of birth is Jan 1, 1960. I tried your code as you described with a small twist. So it's currently 12/28/2009, I'm still 49. but when I do your calculation below I get that I'm 50. I'm not going to be fifty for 4 days. Help! :-)

$foo = split('-','1960-01-01');
		$ageTime = mktime(0,0,0,$foo[1],$foo[2],$foo[0]);
		$t = time();
		$age = ($ageTime < 0) ? ($t + ($ageTime * -1) ) : ($t - $ageTime);
$year = 60 * 60 * 24 * 365;
$ageYears = floor($age / $year);


David


Should be:
$year = 60 * 60 * 24 * 365.25;


because of leap-years.

Mod edit - Please :code:
Was This Post Helpful? 0

#8 Guest_Henry*


Reputation:

Posted 23 February 2011 - 05:55 PM

You have overcomplicated it, in my opinion. Breaking it down in to seconds is unnecessary.

Just do this:

        $adjust = (date("md") >= date("md", strtotime($dob))) ? 0 : -1;
        $years = date("Y") - date("Y", strtotime($dob));
        return $years + $adjust;



$dob can be in "YYYY-mm-dd" format, or anything that strtotime will understand.
Was This Post Helpful? 0

Page 1 of 1