0

I'm calculating the offset between two timezones, but I'm seeing a result I don't expect (zero) with the following code:

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

If I flip the timezone strings, it works, but surely the above code should work too. What's happening?

2 Answers 2

2

getOffset() returns the offset to GMT in seconds, and London is currently on GMT, hence the return value is zero.

I believe what you need instead is:

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

This currently (in January) returns 39600 (11 hours). In July it returns 9 hours, and in mid October (where there's a short period when both Europe and Australia are in daylight saving) it returns 10 hours.

Sign up to request clarification or add additional context in comments.

5 Comments

I'd misread the documentation and expected different behavior from the example code on that page. Thanks
-1: That's actually wrong... DateTimeZone::getOffset calculates the difference between GMT and the DTZ object using the DST rules defined in the passed DT object.
@Alnitak: Passing a string as the second parameter to DateTime will throw an exception and your explanation is still wrong. The OP's code from Mid-April to Mid-October returns 36000.
@Alnitak: datetimezone.getoffset and I quote: "This function returns the offset to GMT for the date/time specified in the datetime parameter. The GMT offset is calculated with the timezone information contained in the DateTimeZone object being used."
Right, got it. That's a nasty gotcha.
1

DateTimeZone::getOffset() works a bit differently that what most people think. It calculates the offset to GMT of the instance DateTimeZone offset for the date passed as parameter. The date passed as parameter is then converted to the same timezone as the instance (DST and other rules applying) and the offset is calculated for that date.

So your code right now calculates the offset to GMT of the timezone Europe/London.. Since Europe/London is on GMT right now (versus BMT), you are getting 0. (Try a date in August, you'll get 36000).

If you want the current difference between two timezones, use this code...

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;
}

1 Comment

Thank you very much! PHP's documentation is really lacking and I'd have never knowing this otherwise.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.