w3hello.com logo
Home PHP C# C++ Android Java Javascript Python IOS SQL HTML videos Categories
php giving wrong answer when using time zone Australia/Sydney

Why it says 5, and why this is technically correct

In Sydney, DST begins at 2013-10-06 02:00:00 - so you lose an hour in dates straddling that.

When you call strtime, it will interpret the time as a Sydney time, but return a Unix timestamp. If you converted the second set of timestamps to UTC, you'd get a range from 2013-09-30 14:00:00 to 2013-10-06 13:00:00, which isn't quite 6 days, so gets rounded down to 5.

How to get the time difference ignoring DST transitions

Try using DateTime objects instead, e.g.

$tz=new DateTimeZone('Australia/Sydney');
$start=new DateTime('2013-10-01', $tz);
$end=new DateTime('2013-10-07', $tz);

$diff=$end->diff($start);

//displays 6
echo "difference in days is ".$diff->d."
";

Why does DateTime::diff work differently?

You might ask "why does that work?" - after all, there really isn't 6 days between those times, it's 5 days and 23 hours.

The reason is that DateTime::diff actually corrects for DST transitions. I had to read the source to figure that out - the correction happens inside the internal timelib_diff function. This correction happens if all the following are true

  • each DateTime uses the same timezone
  • the timezone must be geographic id and not an abbreviation like GMT
  • each DateTime must have different DST offsets (i.e. one in DST and one not)

To illustrate this point, here's what happens if we use two times just a few hours either side of the switch to DST

$tz=new DateTimeZone('Australia/Sydney');
$start=new DateTime('2013-10-06 00:00:00', $tz);
$end=new DateTime('2013-10-06 04:00:00', $tz);

//diff will correct for the DST transition
$diffApparent=$end->diff($start);

//but timestamps represent the reality
$diffActual=($end->getTimestamp() - $start->getTimestamp()) / 3600;

echo "Apparent difference is {$diffApparent->h} hours
";
echo "Actual difference is {$diffActual} hours
";

This outputs

Apparent difference is 4 hours
Actual difference is 3 hours




© Copyright 2018 w3hello.com Publishing Limited. All rights reserved.