简体   繁体   中英

DateTime::getTimezone doesn't return timezone name, but offset

<?php
$first = '2011-04-27';
$second = '2011-04-27 16:20:12';
$third = '2011-04-27 16:20:12+00';

$dt = new DateTime($first);
$dt->setTimeZone(new DateTimeZone($dt->getTimeZone()->getName()));
echo $dt->getTimezone()->getName().'<br />';
// OK
$dt = new DateTime($second);
$dt->setTimeZone(new DateTimeZone($dt->getTimeZone()->getName()));
echo $dt->getTimezone()->getName().'<br />';
// OK
$dt = new DateTime($third);
$dt->setTimeZone(new DateTimeZone($dt->getTimeZone()->getName()));
echo $dt->getTimezone()->getName().'<br />';
// Error
// ->getName() returns unexpectedly +00, which is not a name, but offset

DateTime extracts from the last string timezone name +00 , which is really not name , but offset and therefore cannot be set as timezone...

This behavior is causing troubles when (de)serializing DateTime object...

public function __sleep()
{
    $this->fix = array($this->format('Y-m-d H:i:s'), $this->getTimezone()->getName());
    return array('fix');
}

public function __wakeup()
{
    $this->__construct($this->fix[0], new DateTimeZone($this->fix[1]));
    unset($this->fix);
}

I know it would be better to get eg this string: 2011-04-27 16:20:12 UTC , anyway as far as the metod is called getName() , it shouldn't return +00 as a name, or should?

You have tried to create DateTime object with timezone offset +00 , that's why it returned offset instead of valid timezone identifier and actually that means GMT+0000 . Using datetime string without offset you'll get PHP timezone identifier according to current timezone setting in DateTime object (or system).

With $third = '2011-04-27 16:20:12+00'; you have set +00:00 offset in DateTime object instead of PHP identifier and DateTime just returns that back with ->getName() method.

Fixed offset doesn't provide information about DST rules so it can't be used to get back PHP TimeZone identifier. Example: In my zone it's GMT+2 at the moment (active DST) but if I put it in datetime string, DateTime object can't know when my offset changes to +1 , simply, it's always GMT+0200... that's all.

Offset +00 in your case matches a lot of different timezone identifiers like Atlantic/Reykjavík , Africa/Casablanca , Africa/Nouakchott , etc.

That's why getName() method returns time offset instead of timezone!

This is not official explanation, but that's it in short version.

Of course, 2011-04-27 16:20:12+00 is not valid datetime string.

When I run that code, PHP says it doesn't recognize that format (formats are defined here ) so the output is as a result of an error. However, I was able to run it like so:

$third = '2011-04-27 16:20:12 GMT';

$dt = new DateTime($third);
$dt->setTimeZone(new DateTimeZone($dt->getTimeZone()->getName()));
echo $dt->getTimezone()->getName().'<br />';

I think you can just replace +00 with just GMT .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM