这是一个测试代码:
<?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)
这不是有效日期。我不明白返回的价值,特别是月份......你能解释一下吗?
答案 0 :(得分:26)
你在这里看到两种效果。第一个是你使用一种写作方式来写一个可以用多种形式写的日期:
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秒时有所不同。这是因为与巴黎/法国的UTC相比,时钟的变化发生在1911年3月10日23:51:38/39当地时间。
我稍微修改了你的代码示例并引入了 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 1911和Time zone changes and daylight saving time start/end dates between year 1900 and 1924。
答案 1 :(得分:5)
看起来DateTime
中的错误处理不完整。通常,其他PHP函数处理&#39; 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 #30190,Bug #60288
引用PHP bug跟踪器中的评论:
0000-00-00是一个不存在的日期(01-01-0001之前的那一天是31/12 / -0001)