27

这是一个测试代码:

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

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

4

2 回答 2

30

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

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秒。参考:巴黎的时钟变化 - 1911 年的时间变化日期1900 年至 1924 年之间的时区变化和夏令时开始/结束日期

于 2012-05-04T14:21:47.957 回答
6

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

引用 PHP bug tracker 中的评论:

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

于 2012-05-04T14:56:13.177 回答