Wiimm
Wiimm

Reputation: 3572

strftime() and gmstrftime() return wrong results for "%s"

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?

Test Script

<?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) );
}

?>

Wrong result

%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

Some Notes for clarification (edit)

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

Answers (1)

miken32
miken32

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

Related Questions