Jan
2010
User Time Zones in PHP
When writing applications that are meant to be used by users the world over (not just users within a localized network), it’s important to be able to show dates and times relative to the users time zone. If one user posts something at 11:30 EST, and a few minutes later, a user in California checks the post, it would look as if it were made in the future. Not cool.
Lucky, it’s quite easy to localize dates and times using PHP’s built in date classes.
Storing the Time Zone
The first thing we’ll need to do is setup a mechanism for the user to select their time zone. This should be stored in the database for each user. To generate a list of locales for the user to select, we can use the DateTimeZone class’s static method listIdentifiers():
<select id="timezone" name="timezone">
<?php foreach(DateTimeZone::listIdentifiers() as $timezone): ?>
<option value="<?php echo $timezone; ?>"><?php echo $timezone; ?></option>
<?php endforeach; ?>
</select>Storing Dates in GMT
Now that we have the user’s time zone preference, we can convert any date/time into their local time. In order to do this, however, we need to store all dates in our database in Greenwich Mean Time (GMT) as this provides a basis for us to convert all dates into user defined time zones. We could store the dates in our time zone, and calculate the offsets from our time zone, but it’s much easier to calculate an offset from zero (which is GMT, +0000), and it provides much more portable code.
To format these dates, we will use the DateTime class and set its time zone to GMT. Note that we could also use the gmdate() function in PHP. To store the current date, it’s easy:
$date = new DateTime(null, new DateTimeZone('GMT')); $date = $date->format('Y-m-d h:i:s P');
But if we have a user specified date, we can convert it to GMT by changing the time zone after constructing the object:
$userTimeZone = new DateTimeZone('America/Chihuahua'); $date = new DateTime('2010-01-01 6:32 PM', $userTimeZone); $date->setTimezone(new DateTimeZone('GMT')); $date = $date->format('Y-m-d h:i:s P');
Pulling Dates in the User’s Local Time Zone
Now when we pull a date from the database, it will be in GMT. Using our user’s time zone, we can use the setTimeZone() method again, but this time setting the time zone to the local time zone:
$userTimeZone = new DateTimeZone('America/Chihuahua'); $date = new DateTime('2010-01-01 6:32 PM', new DateTimeZone('GMT')); $date->setTimezone($userTimeZone); $date = $date->format('Y-m-d h:i:s P');
This is exactly like our last snippet, only the time zones are switched. Now we have a date in the user’s local time zone and each user will see the correct time an action occurred relative to their time zone.
Edit: It’s also probably worth noting that the DateTimeZone class will automatically handle Daylight Saving Time and Summer Time (over in Europe) when converting between time zones.
For more information, checkout the documentation on the PHP date classes:
- DateTime
- DateTimeZone
- DateInterval
Another excellent article! I’m just going to start using your site as a checklist every time I start a new project. I always love reading your stuff and it comes in so insanely handy.
Oh, and I love the timezone – America/Chihuahua. Awesome!
Thanks! Usually when I write something, it’s write after how I found out how to do it. Just trying to share the knowledge and hopefully make it easier on someone else!