如何解释新 DateTime('0000-00-00 00:00:00')的结果


How do you explain the result for a new DateTime('0000-00-00 00:00:00')?

下面是一个测试代码:

<?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)

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

你在这里看到两个效果。第一个是你使用一种可以以多种形式书写日期的方式:

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

因此,通过日期本身,您已经指定了 30 月 -1 日。

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


我稍微修改了您的代码示例,并引入了欧洲/巴黎设置,这正在发挥作用。这段代码还说明了 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。

参考:巴黎的时钟变化 - 1911 年的时间变化日期以及 1900 年至 1924 年之间的时区更改和夏令时开始/结束日期。

看起来 DateTime 中的错误处理不完整。通常,其他 PHP 函数将"0000-00-00"处理为错误(无效日期(。

日期时间应遵循相同的准则,但事实并非如此。此代码不会引发异常,即使它应该

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在处理这种情况时总是遇到问题..示例:错误#30190,错误#60288

引用PHP错误跟踪器中的注释:

0000-00-00

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