Question

I have an object, and in the constructor for said object I pass another object that is posted from an API. The relevant constructor code is:

    $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');

The $location object's timeStamp propery is formatted like so: "2013-10-28T16:30:55.000Z". Most of the time, the passed dates get formatted correctly in the end, something like: "11/12/2013 9:36AM CST". Occasionally, though, I get this: "11/18/2013 7:47PM +00:00"

In those cases, I can see that the timezone did not correctly get converted (we typically don't want UTC, and in the case of this constructor, we are always passing a new DateTimeZone instance and passing to that class "US/Central" or whatever timezone the user happens to be in). Any ideas as to what may be causing this behavior?

Was it helpful?

Solution

See note for the 2nd parameter of DateTime::__construct($time, $timezone) method:

The $timezone parameter and the current timezone are ignored when the $time parameter either is a UNIX timestamp (e.g. @946684800) or specifies a timezone (e.g. 2010-01-28T15:00:00+02:00).

That means, if you enter $time in format like yours: 2013-10-28T16:30:55.000Z, given timezone as 2nd parameter to DateTime constructor will be ignored. See examples where all given timezones are ignored, and timezone from input is used (Z = Zulu = UTC = +00:00).

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

If you wish to change timezone for given DateTime object, you can use setTimezone() method, after you created the DateTime object (demo):

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

Try something like this:

$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');
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top