php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #33082 date(B) returns wrong net time for static timestamp
Submitted: 2005-05-20 16:02 UTC Modified: 2005-05-21 04:59 UTC
From: benjamin dot rich at gmail dot com Assigned:
Status: Not a bug Package: Date/time related
PHP Version: 4.3.10 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: benjamin dot rich at gmail dot com
New email:
PHP Version: OS:

 

 [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

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-05-20 17:19 UTC] derick@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc.

If possible, make the script source available online and provide
an URL to it here. Try to avoid embedding huge scripts into the report.
 [2005-05-21 01:02 UTC] benjamin dot rich at gmail dot com
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().
 [2005-05-21 03:00 UTC] benjamin dot rich at gmail dot com
update - it seems that, given a timestamp, date() will assume it is in local time. Therefore, on a server with timezone gmt-4, when getting the net time for a date with timezone gmt+10, you need to do the following:

net time = local timezone - timestamp timezone - 1

the part on the end is a conundrum. i was assuming date() was calculating the diff between local timezone and BMT, but it seems it's just assuming your given timezone is in local server time but then *still adding 1 hour*.

so, if your timestamp is gmt+10, the resulting net time will be 10hours - server timezone + 1 hours out. if you convert the timestamp to gmt, the net time will be 0hours - server timezone + 1 hours out.

So essentially, date() is doing nothing wrong except adding an hour. why?

net time works off BMT, and BMT works off Central European Wintertime. Does this timezone have daylight saving which is transparently being added somewhere? This would explain the extra hour. I suppose if this weird effect goes away in June or July (in European Summer) then we can assume there's something to do with swiss daylight savings going on.

NOTE: also, see cracksmokingducks.com/time.php - this shows that local time (which is set to GMT on my server anyway) taken straight from the clock gives the correct net time when formatted with date() (check http://www.swatch.com/internettime/home.php to verify current net time)
 [2005-05-21 03:23 UTC] benjamin dot rich at gmail dot com
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*.
 [2005-05-21 03:39 UTC] benjamin dot rich at gmail dot com
FINAL CONCLUSION:

formatting a date with date(), using a timestamp provided by mktime(), will always show the correct date and time - BUT *net time will only be accurate if your server's local time is gmt+10*

By running my time.php script on my local webserver (php 4.3.11) under different timezones, I've found there'll always be a discrepency of, at maximum, 10hours, in net time, unless your local timezone is AEST/EST, gmt+10.

This also happens on my server, where local time is gmt+0 - the net time produced from a date() formatted mktime() timestamp is always 10hours ahead.

therefore, I don't know how or why, but mktime() timestamps throw off date() and causes it to imagine the meridian is gmt+10, not gmt+0.
 [2005-05-21 04:06 UTC] benjamin dot rich at gmail dot com
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.php
 [2005-05-21 04:21 UTC] benjamin dot rich at gmail dot com
Sorry, 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.
 [2005-05-21 04:59 UTC] rasmus@php.net
Careful with that.  Places on a half-hour timezone would show up as 0530, for example.  Dividing by 100 is not going to be correct for those.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Thu Jul 10 19:01:34 2025 UTC