日期时区偶尔转换为UTC并且格式不正确


Datetime zone occasionally converting to UTC and formatting incorrectly

我有一个对象,在该对象的构造函数中,我传递另一个从API发布的对象。相关构造函数代码为:

    $this->timeStamp = new 'DateTime($location->timeStamp, new 'DateTimeZone('UTC'));
    if ($apiTime instanceof 'DateTimeZone) {
        $timeZone = $apiTime;
    } else {
        $timeZone = new 'DateTimeZone('UTC');
    }
    $this->localTimeStamp = date_create($location->timeStamp, new 'DateTimeZone('UTC'))->setTimeZone($timeZone);
    $this->localTimeStampFake = $this->localTimeStamp;
    $this->localTimeStampFormatted = date_create($this->localTimeStamp->format('Y-m-d H:i:s'), $timeZone)->format('m/d/Y g:iA T');

$location对象的timeStamp属性的格式如下:"2013-10-28T16:30:55.000Z"。大多数情况下,传递的日期最终都会得到正确的格式,类似于:"11/12/2013 9:36AM CST"。不过,偶尔我会收到这样的消息:"2013年11月18日7:47PM+00:00"

在这些情况下,我可以看到时区没有正确转换(我们通常不想要UTC,在这个构造函数的情况下,我们总是传递一个新的DateTimeZone实例,并传递给类"US/Central"或用户所在的任何时区)。关于是什么原因导致了这种行为,有什么想法吗?

参见DateTime::__construct($time, $timezone)方法的第二个参数的注释:

当$time参数是UNIX时间戳(例如@946684800)或指定时区(例如2010-01-28T15:00:00+02:00)时,将忽略$timezone参数和当前时区

这意味着,如果您以类似于您的格式输入$time2013-10-28T16:30:55.000Z,则DateTime构造函数的第二个参数给定的时区将被忽略。请参阅忽略所有给定时区并使用输入时区的示例(Z=Zulu=UTC=+000:00)。

$dt = new DateTime('2013-10-28T16:30:55.000Z', new DateTimezone('Africa/Dakar'));
//                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
//                                             this parameter is ignored

如果您希望更改给定DateTime对象的时区,您可以在创建DateTime对象(演示)后使用setTimezone()方法:

$dt = new DateTime('2013-10-28T16:30:55.000Z');
$dt->setTimezone(new DateTimezone('Africa/Dakar'));

试试这样的东西:

$this->timeStamp = new 'DateTime($location->timeStamp);
$local = clone $this->timeStamp;
if ($apiTime instanceof 'DateTimeZone) $local->setTimezone($apiTime);
$this->localTimeStamp = $local;
$this->localTimeStampFormatted = $local->format('m/d/Y g:iA T');