Elliot B. Elliot B. - 2 months ago 12
PHP Question

Using PHP DateTime to parse and convert timezone PST to PDT (GMT -8 to GMT -7)

I am having difficulty using PHP

DateTime
to convert a date received with a GMT -8 timezone (PST) to a human readable format with timezone GMT -7 (PDT).

Here's an example:

$tz = new DateTimeZone('America/Los_Angeles');
$saleEndDate = new DateTime("2016-11-07T17:30:00-08:00");
$saleEndDate->setTimezone($tz);
echo $saleEndDate->format('Y-m-d H:i:s');


The output of the above code is: 2016-11-07 17:30:00. However, it should display 2016-11-07 18:30:00 because
America/Los_Angeles
is now in daylight savings (GMT -7, PDT).

From what I've read in the DateTime docs, the
new DateTime
command should be able to interpret that the string
2016-11-07T17:30:00-08:00
has a GMT -8 timezone:


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


Even so, I do not think
DateTime
is recognizing GMT -8 correctly.

Does anyone know what approach is necessary to convert between timezones correctly?

Update:

I've also tried passing in a
DateTimeZone
as the second parameter to the
DateTime
constructor, but also to no avail:

$tz = new DateTimeZone('America/Los_Angeles');
$saleEndDate = new DateTime("2016-11-07T17:30:00-08:00", new DateTimeZone("America/Los_Angeles"));
$saleEndDate->setTimezone($tz);
echo $saleEndDate->format('Y-m-d H:i:s');


Also does not work:

$tz = new DateTimeZone('America/Los_Angeles');
$saleEndDate = new DateTime("2016-11-07T17:30:00", new DateTimeZone("PST"));
$saleEndDate->setTimezone($tz);
echo $saleEndDate->format('Y-m-d H:i:s');


Also does not work:

$tz = new DateTimeZone("PDT");
$saleEndDate = new DateTime("2016-11-07T17:30:00", new DateTimeZone("PST"));
$saleEndDate->setTimezone($tz);
echo $saleEndDate->format('Y-m-d H:i:s');

Answer

Not the greatest but it's the only way I can think of to do this

$tz = new DateTimeZone('America/Los_Angeles');  
$saleEndDate = new DateTime("2016-11-07T17:30:00-08:00");
$saleEndDate->setTimezone($tz);
$stamp = $saleEndDate->format('U');
$zone = $tz->getTransitions($stamp, $stamp);
if(!$zone[0]['isdst']) $saleEndDate->modify('+1 hour');
echo $saleEndDate->format('Y-m-d H:i:s');

What I'm doing here is using the DateTimeZone::getTransitions function to determine if the date you provided is DST or not. If it isn't, we add one hour. Note that this does not change the time zone, it just corrects for the DST shift

You can see it in action here