PHP:为啥 strtotime 转换给出不同的值并且只限于特定的日期?
Posted
技术标签:
【中文标题】PHP:为啥 strtotime 转换给出不同的值并且只限于特定的日期?【英文标题】:PHP: Why strtotime conversion give different values and only limited to a particular date?PHP:为什么 strtotime 转换给出不同的值并且只限于特定的日期? 【发布时间】:2013-04-03 04:25:06 【问题描述】:我有两个不同操作系统的网络服务器。
SERVER 1 在带有 LAMP Server 的 Centos 5 中运行。 php 版本 5.3.21
SERVER 2 在带有 LAMP 服务器的 openSUSE 11.3 中运行。 PHP 版本 5.3.5
两个 PHP 配置是相同的。有些是默认设置。
我有一个 php 文件,代码如下:
<?php
/* TEST STRTOTIME */
echo "<br /><br />".strtotime("2038-01-01");
echo "<br /><br />".strtotime("2039-01-01");
?>
当我在 SERVER 1 中运行这个文件时,结果是:
2145934800
2177470800
但当我在 SERVER 2 中运行此文件时,第二次转换不会产生任何结果。只显示结果是:
2145891600
为什么两台服务器上的转换结果给出的值不同而同一个文件。为什么 SERVER 2 在上述日期 2038-01-01 上无法转换?这个问题有解决办法吗?
【问题讨论】:
如果你也提供时间会发生什么......可能是操作系统的默认时间设置。为什么第二个论点失败了我不知道...... ...可能是时区设置?我知道如果 2 台服务器有不同的 php.ini 时区设置,有时会造成很大的破坏。 php.net/manual/en/datetime.configuration.php 【参考方案1】:您的远程服务器可能是 32 位的。您将需要一个 64 位服务器来处理日期after roughly 2038。
原因是您的远程服务器将其整数存储为带符号的 32 位整数。可以存储为有符号 32 位整数的最大数是 2,147,483,647
(2^31 - 1
)。由于这个数字是 1970 年 1 月 1 日(Unix 纪元)之后的秒数,你可以看到这个数字最终会用完(如果不检查边界,可能会溢出)。
图片来源:Wikipedia
【讨论】:
也就是说我需要把openSUSE 32位换成64位?可以不重新安装直接从32位升级到64位吗? @Fredy 不确定。或者,您可以使用 BC 数学函数。 这很可能是原因,但解决方案不一定涉及安装新操作系统 @Phil 是的,更换操作系统并不是一项轻量级的工作;) @Fredy 如果Phil's answer 适合您,请考虑这样做。这比更改操作系统要容易得多。【参考方案2】:来自manual for DateTime
日期和时间信息在内部存储为 64 位数字,因此支持所有可能有用的日期(包括负年份)。范围从过去大约 2920 亿年到未来相同。
另外,strtotime()
有太多不可靠的不一致之处。我总是推荐使用DateTime
。
$dt = DateTime::createFromFormat('Y-m-d', '2039-01-01');
echo $dt->getTimestamp();
【讨论】:
路过的投票者,想发表评论吗?DateTime
对象使用内部 64 位数字,从而避免任何操作系统限制【参考方案3】:
您可以检查服务器的时区。
您还可以使用date_default_timezone_set('UTC');
命令设置默认时区。
希望这会有所帮助。
【讨论】:
以上是关于PHP:为啥 strtotime 转换给出不同的值并且只限于特定的日期?的主要内容,如果未能解决你的问题,请参考以下文章
Ruby:为啥 unpack('Q') 给出的结果与手动转换不同?