strftime()和gmstrftime()为“%s”返回错误的结果

问题描述 投票:3回答:1

PHP函数strftime()gmstrftime()返回(不同)格式"%s"的错误结果。我用PHP 5.5.14和PHP 7.2.5测试了它,包括CLI和Apache(OpenSuse)。我使用有和没有DST的时间戳。

我的问题:您能否确认其他版本/系统的错误?

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应该返回原始时间戳,但事实并非如此。结果差异是1小时(3600秒)。

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!

我已经将错误报告给bugs.php.net:https://bugs.php.net/bug.php?id=77840

Some Notes for clarification (edit)

PHP文档告诉:“%s给出与time()相同的结果”。而这个结果与时区(纪元以来的秒数)无关。所以strftime("%s",ANY_TIME)必须返回ANY_TIMEgmstrftime()也是如此。

Unix工具日期与预期的一样:

date '+%s %F %T' -d@1556703600
date -u '+%s %F %T' -d@1556703600
TZ=UTC date '+%s %F %T' -d@1556703600

结果是:

1556703600 2019-05-01 11:40:00
1556703600 2019-05-01 09:40:00
1556703600 2019-05-01 09:40:00

所以它不是底层C函数的问题!

php
1个回答
4
投票

方差似乎取决于时区的设定方式。以下测试将向您显示strftime认为无论使用date_default_timezone_set设置什么都有UTC偏移。

date_default_timezone_set("UTC");
echo strftime("%s %z", 1546303600);
date_default_timezone_set("America/Vancouver");
echo strftime("%s %z", 1546303600);

The code似乎应用了一个从系统时区派生的偏移量,所以你可以尝试这样做:

putenv("TZ=UTC");
echo strftime("%s %z", 1546303600);

它应该工作。根据the documentation they've provided,这肯定是不正确的行为。

© www.soinside.com 2019 - 2024. All rights reserved.