Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP 5.4 Can't Determine Time Zones on its own

I'm just looking for a little clarification on this. PHP 5.4 eliminated the TZ environmental variable and the "guessing" that date_default_timezone_get used to do. So now it appears to me there's no way to get the server's timezone at all.

So my question is this: is it possible to get the server timezone in PHP 5.4? I know I can manually set it in php.ini, but that seems kind of silly when there's a computer that's perfectly capable of knowing what time it is. I expect the answer is "no", so perhaps somebody can shed some light on why a programming language would be unable to determine its time zone if that's the case.

like image 609
Andrew Avatar asked Jul 31 '12 19:07

Andrew


2 Answers

There is no reliable way to guess timezone on every system. Different systems use different conventions and sometimes even different timezone definitions (such as Unix and Windows), sometimes have conflicting timezone specifiers (the same 3-letter zone abbreviation can mean different things in different places). So if you want to have code that is portable between systems, the only way to reliably do it is to ask the user. See for example this thread: http://marc.info/?t=132356551500002&r=1&w=2 on some of the issues with it (look for emails from Derick Rethans - he is the PHP datetime extension maintainer).

If you have a way to find out timezone that you trust - such as TZ variable - then you could always do date_default_timezone_set($_SERVER['TZ']);. However in general this is not a reliable method, so it must be your decision to trust it, PHP can not make it for you.

like image 53
StasM Avatar answered Nov 20 '22 15:11

StasM


If you look here you can see the code from PHP 5.3 that would attempt to guess the system timezone. There isn't that much to it, but it appears the reasons for removing the guessing is mostly related to DST as that is where the issues seem to surface.

A breakdown of the whole guessing process looks like:

  • Checks to see if it's already defined globally (php.ini or previous guess) (line 851-853)
  • Check TZ environment variable (rarely ever defined from my experience) (line 855-858)
  • Check date.default_timezone from php.ini (special case as it should already be defined) (line 860-872)
  • Try to guess the timezone from the system by comparing the time() against the localtime(). The spec seems to say setting the timezone is optional, as there could be issues with threaded versions of this call (line 873-890)
  • Win32: Call WinAPI function GetTimeZoneInformation() and try to determine system time zone (line 893-928)
  • Netware: Check the _timezone value if defined (line 929-937)
  • Fallback to UTC if none of the above checks succeeded

I can only speculate, but maybe they only removed it since it was a guess to begin with and isn't always reliable.

Also due to PHP's popularity, it is installed on almost every Linux based shared hosting plan where the customers are often not in the same timezone as the server so falling back to the server timezone for those people is no better than using UTC by default. Then it only causes confusion as these customers have to come to SO to ask why the time is wrong in PHP.

I'm not familiar enough with C and the standard, but it seems like guessing timezone based on localtime has issues with multithreaded code or isn't available in some cases. Since on non-Windows platforms, this is the best way to determine the timezone, it doesn't make sense to do if say half the time it doesn't return anything or causes problems for multi-threaded PHP.

Then of course there is the issue of DST in some places where the timezone and offset is different based on the time of year.

Hope that helps.

like image 2
drew010 Avatar answered Nov 20 '22 15:11

drew010