Why does it say 5, and why is it technically correct
In Sydney , DST starts on 2013-10-06 02:00:00 - so you lose an hour in the dates covering this.
When you call strtime, it will interpret time as time in Sydney, but will return a Unix timestamp. If you converted the second set of timestamps to UTC, you will get a range from 2013-09-30 from 14:00 to 2013-10-06 13:00:00, which is not quite after 6 days, so it gets rounded to 5.
How to get time difference ignoring DST transitions
Try instead of DateTime 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);
Why does DateTime :: diff work differently?
You may ask, "Why does this work?" - In the end, there really is no 6 days between these times, it is 5 days and 23 hours.
The reason is that DateTime :: diff actually fixes DST transitions. I had to read the source to understand this - the correction occurs inside the internal function timelib_diff . This correction occurs if everything is correct:
- each datetime uses the same timezone
- the time zone must be a geographic identifier, not an acronym 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 only a few hours twice on one 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\n"; echo "Actual difference is {$diffActual} hours\n";
Displays
Apparent difference is 4 hours Actual difference is 3 hours
source share