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.
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?