No matter how careful you are, it's very easy - especially with a site involving multiple stages and multiple admins, coders, and end-user authors - to get dates and times mixed up in any web framework. I'm going to send you to Drupal.org first, but then we are going to look into how PHP handles dates and times.
Pay particular attention to the section on Time Zone settings unique to each date field instance !
Ok, to PHP date/time handling. Once you get a hold of the PHP: DateTime class it's quite easy.
PHP handles dates/times and timezones in a similar; behind the scenes, there is an invariant, which for all intents and purposes you can call UTC "universal time". PHP happily allows you to create a DateTime object from a wide range of strings using:
public static DateTime DateTime::createFromFormat ( string $format , string $time [, DateTimeZone $timezone ] )
Note that nice DateTimeZone parameter !
Now PHP knows how to transform the timezone, without changing the "universal time" behind the scenes:
public DateTime DateTime::setTimezone ( DateTimeZone $timezone )
Note that in doing so you are NOT changing the actual datetime invariant ! You are merely changing the output you would see from the
public string DateTime::format ( string $format )
You can even transform to the timezone object corresponding 'UTC' if you wish, but there's really nothing special about it from the point of view of dealing with the DateTime object, it does not care, it just sees 'UTC' as what in maths would be called an eigenvalue (in this case corresponding to our choice of invariance point). It's as if the
setTimezone method is rotating the earth so we can "see" the time from a different perspective (via the
Here's an example from an actual Drupal project I have been working on. A colleague had (just as I prefer it) written some Profile2 data fields to database using the field-specific setting Site's time zone:
When entering data into the field, the data entered is assumed to be in the site's time zone. When the data is saved to the database, it is converted to UTC. When retrieved from the database, the data is converted to the Site's time zone for anonymous users or the User's time zone for logged in users when User-configurable time zones is enabled.
Now be very careful about that bit 'When retrieved from the database' ! It means here in fact when Drupal retrieves it from the database and passes it through the full date field conversion cycle. The date in this case was indeed in UTC (in the actual database table), and I was given access to it in that form, like this:
Which is in PHP date format:
But I am in the timezone 'Australia/Sydney' in summer (near Bondi Beach in fact, although I don't get to boogie board as much as I'd like), which is +11 hours ahead, and that time was in fact written in our local time at 2015-02-12 16:34:13 (which I am quite sure of, because I was not working at 5:34AM in the morning).
Our client needed the date to be sent to their marketing system in 'Australia/Sydney' time. And they also needed it a different format, for processing it at their end in their marketing system. PHP to the rescue, like this:
php > $date_db_string = '2015-02-12 05:34:13'; php > $timezone_local = new DateTimeZone('Australia/Sydney'); php > $timezone_utc = new DateTimeZone('UTC'); php > $datetime = DateTime::createFromFormat('Y-m-d H:i:s',$date_db_string, $timezone_utc); php > print_r($datetime); DateTime Object ( [date] => 2015-02-12 05:34:13.000000 [timezone_type] => 3 [timezone] => UTC ) php > $datetime->setTimezone($timezone_local); php > print_r($datetime); DateTime Object ( [date] => 2015-02-12 16:34:13.000000 [timezone_type] => 3 [timezone] => Australia/Sydney ) php > echo $datetime->format('m/d/Y h:i:s A'); 02/12/2015 04:34:13 PM
And there you have it, the date time in the correct format (and correct time for Sydney)
02/12/2015 04:34:13 PM, being the afternoon, and a far more civilised time to work.
[timezone]above always BOTH change within the DateTime object as the timezone is changed, but the implied invariant "universal time", behind the scenes, under the hood, in fact stays the same.
Drupal too leverages this facility, and has the ability to serve dates according to a single Drupal system time, or according to user specific timezones, if user specific timezones are permitted under Home > Administration > Configuration > Regional and Language:
There you can set the Default time zone and whether:
[ ] Users may set their own time zone.
That's just for the various formats.
Programmatically you can get at the
date_default_timezone($check_user = TRUE):
Returns a timezone name to use as a default.
bool $check_user: (optional) Whether or not to check for a user-configured timezone. Defaults to TRUE.
string The default timezone for a user, if available, otherwise the site.
Finally, Drupal7 also offers a massive range of date manipulation functions via the date_api.module.