views:

1817

answers:

5

For those of us who use standard shared hosting packages, such as GoDaddy or Network Solutions, how do you handle datetime conversions when your hosting server (PHP) and MySQL server are in different time zones?

Also, does anybody have some best practice advice for determining what time zone a visitor to your site is in and manipulating a datetime variable appropriately?

+3  A: 

Store everything as UTC. You can do conversions at the client level, or on the server side using client settings.

php - date

mysql - utc-timestamp

Joel Meador
+1 I get the shifty-eyed look but I always store unix/epoch time as a signed int (want signed for date maths). Never any confusion and survives government TZ shifts.
Xepoch
+9  A: 

As of PHP 5.1.0 you can use date_default_timezone_set() function to set the default timezone used by all date/time functions in a script.

For MySql (quoted from MySQL Server Time Zone Support page)

Before MySQL 4.1.3, the server operates only in the system time zone set at startup. Beginning with MySQL 4.1.3, the server maintains several time zone settings, some of which can be modified at runtime.

Of interest to you is per-connection setting of the time zones, which you would use at the beginning of your scripts

SET timezone = 'Europe/London';

As for detecting the client timezone setting, you could use a bit of JavaScript to get and save that information to a cookie, and use it on subsequent page reads, to calculate the proper timezone.

//Returns the offset (time difference) between Greenwich Mean Time (GMT) 
//and local time of Date object, in minutes.
var offset = new Date().getTimezoneOffset(); 
document.cookie = 'timezoneOffset=' + escape(offset);

Or you could offer users the chioce to set their time zones themselves.

Željko Živković
A: 

I save all my dates as a bigint due to having had issues with the dateTime type before. I save the result of the time() PHP function into it, now they count as being in the same timezone :)

Teifion
A: 

thank for sharing the info it help to understand how to change the server time .

A: 

RE the answer from Željko Živković, timezone descriptors like 'Europe/London' only work if the mySQL admin has added the timezone tables to the system, and keeps them updated.

Otherwise you are limited to numeric offsets like '-4:00'. Fortunately the php date('P') format provides it (as of 5.1.3)

So in say an app config file you might have

define('TZ', 'US/Pacific');
....
if (defined('TZ') && function_exists('date_default_timezone_set')) {
    date_default_timezone_set(TZ);
    $mdb2->exec("SET SESSION time_zone = " . $mdb2->quote(date('P')));
}

This means PHP and mySQL will agree on what timezone offset to use.

Always use TIMESTAMP for storing time values. The column is actually stored as UNIX_TIME (epoch) but implicitly converted from current time_zone offset when written, and back when read.

If you want to display times for users in other time zones, then instead of a global define(), set their given timezone in the above. TIMESTAMP values will be automatically converted by mySQL by the time your app sees the result set (which sometimes can be a problem, if you need to actually know the original timezone of the event too then it needs to be in another column)

and as far as, "why not just store all times as int's", that does lose you the ability to compare and validate dates, and means you always have to convert to date representation at the app level (and is hard on the eyes when you are looking at the data directly - quick, what happened at 1254369600?)

sbeam