2011-01-23 3 views
0

Я вычисление смещения между двумя часовыми поясами, но я вижу результат, я не ожидал (ноль) со следующим кодом:PHP: Почему этот код ошибочно возвращает ноль?

$datetimezone_london = new DateTimeZone('Europe/London'); 
$datetimezone_client = new DateTimeZone('Australia/Canberra'); 
$now_client = new DateTime("now", $datetimezone_client); 
$offset = $datetimezone_london->getOffset($now_client); 
echo $offset; 

Если я переворачивать строки часового пояса, она работает, но конечно, вышеуказанный код тоже должен работать. Что происходит?

ответ

1

DateTimeZone::getOffset() работает немного по-другому, что большинство людей думает. Он вычисляет смещение к GMT экземпляра DateTimeZone смещения для даты, прошедшей как параметр. Дата, переданная как параметр, затем преобразуется в тот же часовой пояс, что и экземпляр (применяется DST и другие правила), и смещение рассчитывается для этой даты.

Так что ваш код прямо сейчас вычисляет смещение по Гринвичу в часовом поясе Europe/London .. Так как Europe/London на GMT сейчас (по сравнению с BMT), вы получаете 0. (Попробуйте дату в августе, вы получите 36000) ,

Если вы хотите текущую разницу между двумя часовыми поясами, используйте этот код ...

function timezone_diff($origin, $compareTo, $forDate = "now") { 
    $dtzOrigin = new DateTimeZone($origin); 
    $dtzCompareTo = new DateTimeZone($compareTo); 

    $compareDate = new DateTime($forDate); 

    $offsetOrigin = $dtzOrigin->getOffset($compareDate); 
    $offsetCompareTo = $dtzCompareTo->getOffset($compareDate); 

    return $offsetCompareTo - $offsetOrigin; 
} 
+0

Большое спасибо! Документация PHP действительно отсутствует, и я бы никогда не знал об этом в противном случае. – Matty

2

getOffset()returns the offset to GMT в секундах, а Лондон в настоящее время находится в режиме GMT, поэтому возвращаемое значение равно нулю.

Я считаю, что вам нужно вместо этого:

$tz_london = new DateTimeZone('Europe/London'); 
$tz_client = new DateTimeZone('Australia/Canberra'); 
$time_london = new DateTime('now', $tz_london); 
$time_client = new DateTime('now', $tz_client); 
$offset = $time_client->getOffset() - $time_london->getOffset(); 
echo $offset; 

Это в настоящее время (в январе) возвращает 39600 (11 часов). В июле он возвращается 9 часов, а в середине октября (где есть короткий период, когда и Европа, и Австралия находятся в летнее время), он возвращает 10 часов.

+0

я неправильно понял документацию и ожидать другое поведение от примера кода на этой странице. Спасибо – Matty

+1

-1: Это на самом деле неправильно ... DateTimeZone :: getOffset вычисляет разницу между GMT и DTZ-объектом, используя правила DST, определенные в переданном объекте DT. –

+1

I (уже) изменил код использования DateTime вместо DTZ – Alnitak