格式化时的日期时区


DateTime timezone when format

这是我在时区和DateTime方面遇到的一个奇怪问题,我会简短地说:

var_dump($obj->getTime1());
var_dump($obj->getTime2());

给我以下(这是可以的,时区是好的等。):

object(DateTime)#379 (3) {
  ["date"]=>
  string(19) "2016-03-28 19:00:00"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(12) "Europe/Paris"
}
object(DateTime)#378 (3) {
  ["date"]=>
  string(19) "2016-03-13 19:00:00"
  ["timezone_type"]=>
  int(3)
  ["timezone"]=>
  string(12) "Europe/Paris"
}

但当我想将(在完全相同的行上)格式化为字符串时:

var_dump($obj->getTime1()->format(DateTime::ISO8601));
var_dump($obj->getTime2()->format(DateTime::ISO8601));

我得到:

string(24) "2016-03-28T19:00:00+0200"  <-- Noticed that it has a different timezone
string(24) "2016-03-13T19:00:00+0100"

我讨厌DateTime

p.S:当我创建第二个DateTime对象时,我克隆了第一个对象,并添加了一个DateInterval:

 $someTime = clone $obj->getTime1();
 $someTime ->sub(new 'DateInterval('P'.$days.'D'));
 $event->setTime2($someTime);

您获得额外一个小时的原因是,在三月的最后一个(完整的)周末,我们会"更改"时区,并跳过一个小时。

今年,这种情况发生在3月27日,这意味着我们实际上正处于另一个时区。DateTime对象会自动为您执行此操作,这就是为什么您有两个不同的时区。

它将与10月30日的最后一个(完整)周末相反。

自1999年以来,欧盟制定了以下从夏令时间切换到夏令时间的规则:

  • 开始时间:三月的最后一个星期日
  • 完:十月的最后一个星期天

这意味着国家之间不需要续约或事先达成协议。

你的例子恰好越过了第一个界限。在法国,这意味着从CET(+0100)转换到CEST(+0200)。PHP考虑到了这一点。