|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2005-05-20 16:02 UTC] benjamin dot rich at gmail dot com
Description:
------------
date("B", $timestamp) will return the swatch net time for $timestamp + the difference between local server time and BMT (net time meridian, swiss time, GMT+1).
Reproduce code:
---------------
date("B", date());
date("B", gmdate());
Both the above return the same, correct result - they will give the current net time. However:
$timestamp = mktime(some,GMT,date,and,time);
date("B", $timestamp);
will return the correct net time for this date/time PLUS the difference between local server time (say, GMT-4) and BMT (GMT+1) - putting it off (by, in this case, 5 hours).
Expected result:
----------------
date("B", $timestamp); should return the net time for this timestamp, assuming the timestamp represents a date and time in at some arbitrary location like GMT+0.
Actual result:
--------------
Instead, it adds an incorrect factor to the resulting net time
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Dec 01 01:00:01 2025 UTC |
Here is a piece of my code that reproduces the error. I've put in some fake data for it. --- echo "it is " . date("r @B") . " Local Time<br />\n"; echo "and " . gmdate("r @B") ." GMT<br />\n"; echo "" . date("@B") . " net time as of now<br />\n"; //note: the above show the correct net time - the same net time for both local and gmt dates/times. //however, when we calculate the net time for a given date, which we convert to gmt.... $_blog_timezone = "+10"; $_server_timezone= "-4"; $blogitem_date = "2004-05-20"; $blogitem_time = "18:41"; if ($blogitem_date != "") { if (ereg("([0-9]{1,4})-([0-9]{1,2})-([0-9]{2})", $blogitem_date, $t_date)) $t_datestring = $t_date[1] . "." . $t_date[2] . "." . $t_date[3]; } $test_ereg = ereg("([0-9]{2}):([0-9]{2})", $blogitem_time, $t_time); $blog_timestamp = mktime($t_time[1], $t_time[2], 0, $t_date[2], $t_date[3], $t_date[1]); $gmt_timestamp = $blog_timestamp + (3600 * flip_sign($_blog_timezone)); $server_timestamp = $gmt_timestamp + (3600 * $_server_timezone); $swatch_net_time = date("@B", $gmt_timestamp); echo "net time for this article is $swatch_net_time" ----- $swatch_net_time will be 5 hours ahead - the difference between the server's local time (gmt-4) and BMT (gmt+1). If we change the local time to, say, gmt, there will still be an hour difference added to the net time - again, local time (gmt+0) diff to BMT (gmt+1) = 1hour. if a given date is left in it's local timezone (GMT+10 in the above example), the difference will be: (diff between server local time and BMT) + local timezone. In other words, if I hadn't converted the date in the above script to GMT first, the resulting net time would have been 5hours + 10hours out. I theorise this whole problem is something to do with the date function doing several things transparently to calculate net time, which it doesn't bother with to calculate other representations for a date. Given a timestamp with no timezone info (it's not taken from the local clock), the function must assume the date is in GMT and then figure out BMT to calculate net-time for it. But, for some reason, something is going awry and it's not only calculating the diff between local server time and GMT, etc. etc., but it's also *adding* this extra factor to the resulting date. I may be missing something huge here, but it seems to be a bug in date().problem somewhat solved through experimentation. date() is not the problem - timestamps generated by mktime() are. Here is some code to show this: <?PHP echo "it is " . date("r I @B") . " Local Time<br />\n"; echo "and " . gmdate("r I @B") ." GMT<br />\n"; echo "" . date("@B I") . " net time as of now<br />\n"; $timestamp = strtotime(date("r")); echo "net time from current local timestamp (not local clock) is: " . date("r @B", $timestamp) . "<br /n>"; echo "and getting the timestamp from mktime(11,06,10,5,21,2005) which should give @087 gives " . date("r B", mktime(11,06,10,5,21,2005)) . "<br />\n"; ?> on a server with a local time of gmt+10, all dates come out with the correct net time. on a server where the local time is set to gmt+0, all dates come out with the correct date time except the one who's timestamp was generated by mktime(). In this instance, the date/time that are produced are *correct*, but the net-time produced *incorrect* - it is @504 instead of the correct @087, which means the net time is exactly 10hours ahead of what it should be. given that, in this instance, the server doesn't know that my local timezone is gmt+10 (since the server timezone is gmt+0 and I didn't write anything into the code to account for my timezone), something strange is happening between mktime() and date(). mktime() generates the correct timestamp because we see the date/time are correct for the input; but date() formats the timestamp into net-time incorrectly; BUT *does not do this when the timestamp is returned by time() or other functions*.this problem also occurs with timestamps generated from strtotime: <?PHP echo "it is " . date("r I @B") . " Local Time<br />\n"; echo "and " . gmdate("r I @B") ." GMT<br />\n"; echo "" . date("@B I") . " net time as of now<br />\n"; $timestamp = strtotime(date("r")); echo "net time from current local timestamp (not local clock) is: " . date("r @B", $timestamp) . "<br /n>"; echo "and getting the timestamp from mktime(11,06,10,5,21,2005) which should give @087 gives " . date("r @B", mktime(11,06,10,5,21,2005)) . "<br />\n"; echo "and getting the timestamp from strtotime(\"21 May 2005 11:06:10am\") which should give @087 gives " . date("r @B", strtotime("21 May 2005 11:06:10am")) . "<br />\n"; ?> see http://cracksmokingducks.com/time.phpSorry, discovered this entire 2 day long hellride is not due to a php bug but, of course, my own stupidity =P I discovered I was incorrectly converting dates to GMT by making date("O") the server timezone, when it should have been date("O")/100.