【发布时间】:2019-04-03 18:54:32
【问题描述】:
PHP 函数 strftime() 和 gmstrftime() 返回(不同的)格式 "%s" 的错误结果。我使用 PHP 5.5.14 和 PHP 7.2.5 对它进行了测试,包括 CLI 和 Apache (OpenSuse)。我使用了带和不带 DST 的时间戳。
我的问题:你能确认其他版本/系统的错误吗?
测试脚本
<?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 应该返回原始时间戳,但它没有。结果相差 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
一些说明(编辑)
PHP 文档告诉:“%s 给出与time() 相同的结果”。这个结果与时区无关(自纪元以来的秒数)。所以strftime("%s",ANY_TIME) 必须返回ANY_TIME。 gmstrftime() 也一样。
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函数的问题!
【问题讨论】:
-
我怀疑这归结为
date_default_timezone_set没有按您的预期工作,而不是与strftime有任何关系。 -
%s必须始终提供独立于时区的时间戳。来自php.net/manual/en/function.strftime.php : "%s : Unix Epoch Time timestamp (same as the time() function)" -
一个有趣的旁注,
%s在 Windows 上的strftime或gmstrftime中单独使用会导致根本没有输出,因此很难测试!
标签: php