Working with time zones in PHP

Some problems with time zones in PHP have long been in my mind, and I was wondering if they have better ways to handle this than what I'm doing right now.

All problems are related to changing the database retention date:

When working with a site that must support multiple time zones (for users) in order to normalize the timeout of the timeline of stored timestamps, I always store it in the server’s time zone using the CURRENT_TIMESTAMP attribute or the NOW() function.

This way, I don’t have to consider what time interval was set for PHP when the timestamp was introduced (since PHP time functions have time zone information). For each user, according to his preferences, I set the time zone somewhere in my boot file using:

 date_default_timezone_set($timezone); 

When I search for a date format using the php date() function, some form of conversion should happen, since MySQL currently stores the timestamp in Ymd H:i:s format. Ignoring the time zone, you can simply run:

 $date = date($format,strtotime($dbTimestamp)); 

The problem is that date() and strtotime() are both time-dependent functions, which means that if PHP's time zone is set differently than the server’s time zone, the time zone offset will be applied twice (instead).

To handle this, I usually retrieve MySQL timestamps using the UNIX_TIMESTAMP() function, which has no timezone information, which allows me to apply date() directly to it, thereby applying only the time offset.

I don’t like this “hack” because I can no longer retrieve these columns, as usual, or use * to retrieve all columns (sometimes this simplifies queries). Also, sometimes it's just not an option to use UNIX_TIMESTAMP() (especially when used with open source packages without significant abstraction for query composition).

Another problem is saving the timestamp when using CURRENT_TIMESTAMP or NOW() not an option - saving the created PHP timestamp will save it with a timezone offset that I would like to avoid.

I probably lack something really elementary here, but so far I have not been able to find a common solution to solve these problems, so I have to consider them in each case. Your thoughts are very welcome

+20
timezone database php
Dec 06 '08 at 21:05
source share
4 answers

A few months ago, we thought about this for a while. The technique we ended up with is pretty simple:

  • Save dates in GMT / UTC (for example, 0 time zone offset).
  • Apply the current user’s time zone offset after retrieving from the database (for example, before showing it to the user or whenever you want).

We use the Unix timestamp format. But it does not matter.

+10
Dec 08 '08 at 16:12
source share

Starting with PHP 5.2, you can use DateTime, which simplifies working with time zones:

 $datetime = new DateTime($dbTimestamp, $timezone); echo $datetime->format('Ymd H:i:s'); $datetime->setTimezone(new DateTimeZone('Pacific/Nauru')); echo $datetime->format('Ymd H:i:s'); 
+6
Jan 30 '13 at 2:22
source share

You can try to get MySQL to use UTC everywhere using SET time_zone .

Unfortunately, I don't have an answer for strtotime / UNIX_TIMESTAMP, in fact I have the same problem with Postgres.

+1
Dec 6 '08 at 21:23
source share

I did not find any elegant solution on the net, so I created a Timezone script HTML code generator , and here is the output directly. This is something like this:

 <select name="timezone" id="timezone"> <optgroup label="UTC -11:00"> <option value="Pacific/Midway">UTC -11:00 Midway</option> <option value="Pacific/Niue">UTC -11:00 Niue</option> <option value="Pacific/Pago_Pago">UTC -11:00 Pago_Pago</option> </optgroup> <optgroup label="UTC -10:00"> <option value="America/Adak">UTC -10:00 Adak</option> <option value="Pacific/Honolulu">UTC -10:00 Honolulu</option> <option value="Pacific/Johnston">UTC -10:00 Johnston</option> <option value="Pacific/Rarotonga">UTC -10:00 Rarotonga</option> <option value="Pacific/Tahiti">UTC -10:00 Tahiti</option> </optgroup> . . . . . . . . . . . . . . <optgroup label="UTC +13:00"> <option value="Pacific/Apia">UTC +13:00 Apia</option> <option value="Pacific/Enderbury">UTC +13:00 Enderbury</option> <option value="Pacific/Fakaofo">UTC +13:00 Fakaofo</option> <option value="Pacific/Tongatapu">UTC +13:00 Tongatapu</option> </optgroup> <optgroup label="UTC +14:00"> <option value="Pacific/Kiritimati">UTC +14:00 Kiritimati</option> </optgroup> </select> 

Enjoy it!

0
Jun 10 '13 at 20:44
source share



All Articles