2014-10-22 5 views
0

Следующий PHP код:PHP смещение часового пояса некорректный

function serverTimeZone_offset($userTimeZone) 
{ 
    $userDateTimeZone = new DateTimeZone($userTimeZone); 
    $userDateTime  = new DateTime("now", $userDateTimeZone); 

    $serverTimeZone  = date_default_timezone_get(); 
    $serverDateTimeZone = new DateTimeZone($serverTimeZone); 
    $serverDateTime  = new DateTime("now", $serverDateTimeZone); 

    return $serverDateTimeZone->getOffset($userDateTime); 
} 

function getDefineTimeZone($timezone) 
{ 
    $userDateTimeZone = new DateTimeZone($timezone); 
       return new DateTime("now", $userDateTimeZone); 
} 

function getServerTimeZone() 
{ 
    $serverTimeZone  = date_default_timezone_get(); 
    $serverDateTimeZone = new DateTimeZone($serverTimeZone); 

    return new DateTime("now", $serverDateTimeZone); 
} 

$userDateTime = getDefineTimeZone('America/Curacao'); 
$serverDateTime = getServerTimeZone(); 
$timeOffset  = serverTimeZone_offset('America/Curacao'); 

var_dump($userDateTime); 
var_dump($serverDateTime); 
var_dump($timeOffset); // the seconds is incorrect ?!?! 

// adding the timezone difference 
$userDateTime->add(new DateInterval('PT'.$timeOffset.'S')); 

var_dump($userDateTime); 

Выведет:

object(DateTime)[2] 
    public 'date' => string '2014-10-22 17:36:39' (length=19) 
    public 'timezone_type' => int 3 
    public 'timezone' => string 'America/Curacao' (length=15) 

object(DateTime)[3] 
    public 'date' => string '2014-10-22 23:36:39' (length=19) 
    public 'timezone_type' => int 3 
    public 'timezone' => string 'Europe/Paris' (length=12) 

int 7200 

object(DateTime)[2] 
    public 'date' => string '2014-10-22 19:36:39' (length=19) 
    public 'timezone_type' => int 3 
    public 'timezone' => string 'America/Curacao' (length=15) 

Что, очевидно, неверно. Смещение возвращается назад 7200 секунд (всего 2 часа), а не 21600 секунд (6 часов). Зачем?

ответ

1

Я думаю, что вы неправильно интерпретируете поведение DateTimeZone::getOffset(). Как указано в DateTimeZone php docs:

Эта функция возвращает смещение в GMT для даты/времени, указанного в параметре datetime. Смещение GMT ​​рассчитывается с информацией о часовом поясе, содержащемся в используемом объекте DateTimeZone.

Таким образом, если сервер часовой пояс является Europe/Paris, то getOffset() вернет 7200 секунд, а Европа/Париж GMT + 01: 00, и это летнее время прямо сейчас, поэтому GMT + 02: 00 ,

Попробуйте использовать этот код вместо:

function serverTimeZone_offset($userTimeZone) 
{ 
    $userDateTimeZone = new DateTimeZone($userTimeZone); 
    $userDateTime  = new DateTime("now", $userDateTimeZone); 

    $serverTimeZone  = date_default_timezone_get(); 
    $serverDateTimeZone = new DateTimeZone($serverTimeZone); 
    $serverDateTime  = new DateTime("now", $serverDateTimeZone); 

    return $serverDateTimeZone->getOffset($userDateTime) - $userDateTimeZone->getOffset($userDateTime); 
} 
+0

Awesome! Я действительно полностью неверно истолковал поведение getOffset. Спасибо за упрощенное разъяснение. – tfont

Смежные вопросы