In response to the announcement that WordPress 3.2 (due later this month) will require PHP 5.2.4+, I upgraded my Windows test machine today from XAMPP 1.5.5 to 1.7.4, which in turn bumped me up from PHP 5.2.0 to 5.3.5.
I’ve got just about everything working again, but one test page is behaving strangely. I have a MySQL table with tz identifiers by country code and the following script determines and displays the current time in each of the timezones:
<?php
echo "<table>";
$result = mysql_query("SELECT * FROM zone_data ORDER BY `id` ASC;");
while ($row = mysql_fetch_assoc($result)) {
putenv("TZ=".$row['zone_name']);
echo "<tr>";
echo "<th>".$row['zone_code']."</th>";
echo "<td>".$row['zone_name']."</td>";
echo "<td>".date("D j M Y / H:i T",$_GET['t']);
if (date("I") == 1) { echo "*"; } // asterisk if in DST
echo " (".date("P",$_GET['t']).")</td>";
echo "</tr>";
}
echo "</table>";
?>
The expected output, which runs just fine on the production server in PHP 5.2.17, should be along the lines of:
Z Etc/UTC Fri 3 Jun 2011 / 03:22 UTC (+00:00)
AD Europe/Andorra Fri 3 Jun 2011 / 05:22 CEST* (+02:00)
AE Asia/Dubai Fri 3 Jun 2011 / 07:22 GST (+04:00)
AF Asia/Kabul Fri 3 Jun 2011 / 07:52 AFT (+04:30)
AG America/Antigua Thu 2 Jun 2011 / 23:22 AST (-04:00)
...
…but instead I’m told that the time is the same as my system time, America/New_York (currently UTC-4) in every zone:
Z Etc/UTC Thu 2 Jun 2011 / 23:22 EDT* (-04:00)
AD Europe/Andorra Thu 2 Jun 2011 / 23:22 EDT* (-04:00)
AE Asia/Dubai Thu 2 Jun 2011 / 23:22 EDT* (-04:00)
...
Now, I had noticed that line 1001 of the new php.ini installed with XAMPP 1.7.4 had originally contained date.timezone = Europe/Berlin, so I’d replaced it with date.timezone = America/New_York. But in both cases, every instance of the date() function is being dictated by this setting regardless of anything I’ve said otherwise with putenv(). The same holds true for all other pages using date() (although gmdate(), obviously, returns GMT as expected).
I tried commenting out that line, but PHP 5.3.5 threw lovely errors saying that it’s “not safe to rely on the system’s timezone settings” and that I’m required to use the date.timezone directive in php.ini, even though I always use putenv() when I use date() or similar functions.
It’s a bit frustrating to be forced to make a “super-global” setting, especially for a case like this where the whole point is to temporarily enter a new TZ environment and glean some useful information from it.
So… Is there any way I can have the date.timezone directive behave as a default that is overridable by putenv() such that the latter isn’t completely ignored? Is there anything else you can think of that might be causing the unexpected/bizarre behavior outlined above?
I’m inclined to believe that this is just some server setting that needs to be changed to allow putenv() to continue working in PHP 5.3.5 as it did in 5.2.0 (and does in 5.2.17). Of course, if there’s a “better way” altogether, I wouldn’t mind hearing about it (I always like learning new things!). But mostly I want my old code to work on my new install.
Let me know if you need any more information about my setup.
The
TZenvironment variable is ignored under PHP 5.3. (The PHP manual page fordate_default_timezone_getdescribes the order the various settings will be considered in, including thatTZonly applies for PHP < 5.3).Simple solution: instead of
putenv, usedate_default_timezone_setto set your different timezones.The above is the most direct replacement for
putenv, but theDateTimeclass offers a better way to do date operations in different timezones while not affecting the “current” timezone for other date operations.DateTime‘s constructor can take aDateTimeZoneargument that only affects the timezone for that particular object (this can also be set withsetTimezone():