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 转换给出不同的值并且只限于特定的日期?的主要内容,如果未能解决你的问题,请参考以下文章

PHP 时间转换

PHP strtotime() 函数

Ruby:为啥 unpack('Q') 给出的结果与手动转换不同?

为啥 cv2.NORM_HAMMING 给出的值与实际汉明距离不同?

以不同格式PHP转换日期格式[重复]

php时间格式转换