假设我们有一个日期1972-12-31 23:59:59
,如果我们从DateTimeImmutable
对象中获得它的Timestamp
,我们将得到以下结果:
$formattedDate = '1972-12-31 23:59:59';
$ts = (new DateTimeImmutable($formatedDate))->getTimestamp(); // <- 94690799
问题是,如果您尝试将转换反向,那么它就变成了从时间戳到格式化日期:
$ts = 94690799;
$formattedDate =
(new DateTimeImmutable(sprintf('@%s', $ts)))->format('Y-m-d H:i:s'); // <- 1972-12-31 22:59:59
第二种方式过去了一个小时。
那么最大的问题就是,哪一个时间是正确的呢? 这是虫子吗? 还是我搞砸了?
当您从格式化字符串创建DateTime对象时,它将在服务器的默认时区中创建(请参阅date_default_timezone_get
)。 但是Unix时间戳没有时区--它们总是UTC。 所以如果你写:
(new DateTimeImmutable('1972-12-31 23:59:59'))->getTimestamp();
那么您真正要问PHP的是“1970年后在UTC是多少秒,当时是我当前时区的那个日期+时间”。 在您的示例中,服务器看起来比UTC早一个小时运行,因此存在差异。
关键的是,当您进行反向操作并从时间戳创建DateTime对象时,对象的时区总是设置为UTC。 在这本手册上有一个简短的说明。
如果在运行代码之前将默认时区设置为UTC,您将看到输出匹配。 我在这里添加了一个示例:https://3v4L.org/2rfp3