PHP Tip datestamps timestamps

Are you struggling with “date math?” If you’ve fallen into the trap of converting string-based timestamps into month, day, year, hour, minute, and second, and then trying to perform some sort of math or calculations based upon these values, consider storing timestamps in epoch format instead. Today’s tip is a bit longer than usual but you might find it worth the extra read!

“Epoch” time represents the number of seconds which have elapsed since midnight, January 1st, 1970 GMT. Because the format is based upon a value which has some meaning in terms of time – seconds – calculating time becomes a snap compared to calculating time with string values. As an example, suppose you currently store datestamps in string format, and you have an existing stamp, e.g. “2003-03-04 13:56:11.”

To find the date and time 8 hours after that stamp, you’d need something like this:

<?php
$stamp = “2003-03-04 13:56:11”;
list($date, $time) = split(‘ ‘, $stamp);
list($year, $month, $day) = split(‘-‘, $date);
list($hour, $minute, $second) = split(‘:’, $time);

#Add 8 hours
if(($hour + 8) <= 23){
$hour += 8;
#We got lucky!
die(“$year-$month-$day $hour:$minute:$second”);
}
else{
#A rather large amount of code would go here,
#determining whether it’s necessary to add
#a month and year, whether or not we’re dealing
#with a leap year, etc.
}
?>

If you’re doing things that way, you’re punishing yourself entirely too much. Here’s how it works using epoch stamps. Let’s start with the same time – 13:56:11 on March 3rd 2003 – and add 8 hours:

<?php
$stamp = 1046807771;
echo date(“Y-m-d H:i:s”, $stamp + (3600 * 8));
?>

And there you have it, we know that 8 hours from our starting point would be 2003-03-04 21:56:11. No muss, no fuss, no bother. Another example, this one perhaps a bit more practical, is determining whether or not a specific event happened within a certain time period. Suppose your website tracks customer logins in a database, and automatically forces logins more than 24 hours old to expire. This, too, is easier with epoch:

<?php
$lastlogin = 1046807771;
if($lastlogin < (time() – 86400)){
die(“Sorry, your login has expired!”);
}
?>

The time() function returns the current epoch timestamp. By comparing the last login stamp to the result of time() minus 86400 – the number of seconds in a day – we can determine whether or not the last login occurred more than 24 hours ago.

Aside from making date calculations simpler, there are three other advantages to using epoch time as opposed to string-based timestamps:

First, most (if not all) unix systems inherently support the epoch format and use it to track time internally; epoch time is often referred to as “unix time” for this reason.

Second, because epoch time is measured according to GMT, the integer representing the accurate epoch time is exactly the same everywhere in the world. This eliminates some timezone confusion and provides for more portability between different servers in different timezones. Of course, the current epoch time has different meaning in different time zones, our example of 1046807771 would have been 11:56 AM in the Pacific timezone and 2:56 PM on the east coast.

Finally, on some systems, an epoch time representation uses less storage space than a string-based one. Consider the difference in size between the integer 1046807771 and the string “2003-03-04 13:56:11.” In MySQL, an integer (such as an epoch value) takes only 4 bytes of storage[1], whereas a datetime value requires 8 bytes, and a timestamp stored as a varchar could require 15-20 bytes. Storing timestamps as integer(10) fields instead of datestamp or varchar fields in your database can save space.

[1] MySQL’s timestamp data type, which displays as YYYYMMDDHHMMSS, is stored as an epoch value and requires only 4 bytes as well. If all of your date math will be done within SQL queries, use the timestamp data type instead of storing epoch stamps in integer fields.

Comments are closed.