【问题标题】:How do you explain the result for a new \DateTime('0000-00-00 00:00:00')?您如何解释新的 \DateTime('0000-00-00 00:00:00') 的结果?
【发布时间】:2012-05-10 20:37:09
【问题描述】:

这是一个测试代码:

<?php

ini_set('date.timezone', 'Europe/London');    
$dt = new \DateTime('0000-00-00 00:00:00');

var_dump($dt);

这提供了:

object(DateTime)[1]
  public 'date' => string '-0001-11-30 00:00:00' (length=20)
  public 'timezone_type' => int 3
  public 'timezone' => string 'Europe/London' (length=13)

而这不是一个有效的日期。我不明白返回的值,尤其是月份...你能解释一下吗?

【问题讨论】:

  • 我在更新后得到了同样的结果。但我仍然不明白结果:/我在 PHP 5.3.5-1ubuntu7.7
  • new \DateTime 中的斜线是什么意思?
  • 其实自己已经找到答案了。在这种情况下它很聪明,但似乎毫无意义,因为我怀疑有人会创建一个名为 DateTime 的类。 stackoverflow.com/a/4790031/882371
  • 但是任何人都可以扩展它......
  • 是的,Andrew,不适用于这个示例,但是如果你总是在官方 PHP 类前面加上命名空间的根,那么当你使用命名空间时,你不需要重构任何东西。

标签: php datetime date


【解决方案1】:

您在这里看到了两种效果。第一个是你用一种写法来写一个日期,可以写成多种形式:

0000-01-01 same as  0000-01-01
0000-01-00 same as -0001-12-31
0000-00-01 same as -0001-12-01
0000-00-00 same as -0001-11-30

因此,就日期本身而言,您已经指定了 11 月 30 日 -1 日。

现在剩下的时间偏移量大约为 9 分 21 秒。这是因为与当地时间 1911 年 3 月 10 日 23:51:38/39 巴黎/法国的 UTC 相比,时钟发生了变化。


我稍微修改了您的代码示例并引入了 Europe/Paris 设置,因为它正在发挥作用。此代码还告诉您与 UTC (Z) 的秒数偏移量,这正是您要查找的:

$dt = new DateTime('0000-00-00 00:00:00', new DateTimeZone('Europe/Paris'));
printf("%s secs offset from UTC\n", $dt->format('r T (e) Z'));

我稍微改了一下日期

Fri, 10 Mar 1911 23:51:38 +0009 PMT (Europe/Paris) 561 secs offset from UTC
                                                   ^^^

一秒钟后:

Fri, 10 Mar 1911 23:51:39 +0000 WET (Europe/Paris) 0 secs offset from UTC

当地标准时间快到的时候 1911 年 3 月 11 日星期六,00:01:00 时钟被调回 0:09:21 时 改为 1911 年 3 月 10 日星期五,当地时间 23:51:39。

那是 561 秒。参考:Clock changes in Paris - Time change dates in 1911Time zone changes and daylight saving time start/end dates between year 1900 and 1924

【讨论】:

  • 我知道这不是一个有效的日期,我知道它无法提供有效的输出,但我的问题是“有人知道为什么会这样吗?”
  • 之前的时区是什么时候?通常,您看到的两者之间存在差异(此处为负增量)。
  • @hakre 有趣的是,只有 30 分钟步长的时区,没有解释 09 分 21 秒的奇怪偏移量。更有趣的是 -1 年 11 个月 29 天的偏移量。这很奇怪 - 无论0000-00-00 00:00:00 是否被视为有效日期......
  • 我已经更新了我的问题,没有更改时区(即使我想知道 09 分 21 秒的偏移量......)
  • @hakre :我得到和你一样的结果。为什么是 11 月 30 日?
【解决方案2】:

DateTime 中的错误处理似乎不完整。通常,其他 PHP 函数将 '0000-00-00' 处理为错误(无效日期)。

DateTime 应该遵循相同的准则,但事实并非如此。这段代码不会抛出异常,即使它应该

try { $dt = new \DateTime('0000-00-00 00:00:00'); } 
catch (Exception $e) { var_dump($e); }
var_dump($dt); 
/* result:
object(DateTime)#1 (3) {
  ["date"]=>
  string(20) "-0001-11-30 00:00:00"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(13) "Europe/Berlin"
*/

其他函数确实将该输入视为错误:

var_dump(strtotime('0000-00-00 00:00:00'));  // returns: bool(false)

似乎 PHP 在处理这种情况时总是遇到问题。示例:Bug #30190Bug #60288

引用来自 PHP 错误跟踪器中的 cmets:

0000-00-00 是不存在的日期(01-01-0001 的前一天是 31/12/-0001)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    • 2017-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多