Reputation: 3572
PHP Functions strftime()
and gmstrftime()
return (different) wrong results for format "%s"
. I tested it with PHP 5.5.14 and PHP 7.2.5, both with CLI and Apache (OpenSuse). I used timestamps with and without DST.
My question: Can you confirm the bug with other versions/systems?
<?PHP
header('Content-Type: text/plain; charset=utf-8');
$list = array(
1546303600, // 2018-01-01 00:46:40 UTC
1556703600, // 2019-05-01 09:40:00 UTC
);
echo "\ndate_default_timezone_set('UTC')\n";
date_default_timezone_set('UTC');
foreach ( $list as $time )
{
printf("\n%u\n%4s\n%s\n",
$time,
strftime('%s, %F %T %Z',$time),
gmstrftime('%s, %F %T %Z',$time) );
}
echo "\ndate_default_timezone_set('Europe/Berlin')\n";
date_default_timezone_set('Europe/Berlin');
foreach ( $list as $time )
{
printf("\n%u\n%4s\n%s\n",
$time,
strftime('%s, %F %T %Z',$time),
gmstrftime('%s, %F %T %Z',$time) );
}
?>
%s
should return the original timestamp, but it does not. The results difference is 1 hour (3600 seconds).
date_default_timezone_set('UTC')
1546303600
1546300000, 2019-01-01 00:46:40 UTC <<< WRONG!
1546300000, 2019-01-01 00:46:40 GMT <<< WRONG!
1556703600
1556700000, 2019-05-01 09:40:00 UTC <<< WRONG!
1556700000, 2019-05-01 09:40:00 GMT <<< WRONG!
date_default_timezone_set('Europe/Berlin')
1546303600
1546303600, 2019-01-01 01:46:40 CET
1546300000, 2019-01-01 00:46:40 GMT <<< WRONG!
1556703600
1556703600, 2019-05-01 11:40:00 CEST
1556700000, 2019-05-01 09:40:00 GMT <<< WRONG!
I reported the bug already to bugs.php.net: https://bugs.php.net/bug.php?id=77840
PHP docu tells: "%s
gives the same result as time()
". And this result is independent of the timezone (seconds since epoch). So strftime("%s",ANY_TIME)
must return ANY_TIME
. Same for gmstrftime()
.
Unix tool date works like expected:
date '+%s %F %T' -d@1556703600
date -u '+%s %F %T' -d@1556703600
TZ=UTC date '+%s %F %T' -d@1556703600
The result is:
1556703600 2019-05-01 11:40:00
1556703600 2019-05-01 09:40:00
1556703600 2019-05-01 09:40:00
So it is not an issue of the underlying C function!
Upvotes: 3
Views: 280
Reputation: 42743
The variance seems to be down to how the timezone is set. The following test will show you that strftime thinks there is a UTC offset no matter what is set using date_default_timezone_set
.
date_default_timezone_set("UTC");
echo strftime("%s %z", 1546303600);
date_default_timezone_set("America/Vancouver");
echo strftime("%s %z", 1546303600);
The code appears to apply an offset that's derived from the system timezone, so you could try this instead:
putenv("TZ=UTC");
echo strftime("%s %z", 1546303600);
And it should work. According to the documentation they've provided, this definitely appears to be incorrect behaviour.
Upvotes: 4