Php gives wrong answer when using Australia / Sydney time zone

I am developing a website to work in Australia.

so I set the time zone as follows.

date_default_timezone_set('Australia/Sydney'); 

I need to calculate the number of days between two dates.

In October, I discovered strange behavior.

  $now = strtotime('2013-10-06'); // or your date as well $your_date = strtotime('2013-10-01'); $datediff = $now - $your_date; echo floor($datediff/(60*60*24));//gives output 5, this is right $now = strtotime('2013-10-07'); // or your date as well $your_date = strtotime('2013-10-01'); $datediff = $now - $your_date; echo floor($datediff/(60*60*24));//gives output 5, this is wrong, but it should be 6 here 

after 2013-10-07 he always gives one day less answer. Its excellent with other time zones. Perhaps this is due to summer time. But what is the solution for.

Please, help.

thanks

+4
source share
1 answer

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); //displays 6 echo "difference in days is ".$diff->d."\n"; 

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 
+3
source

Source: https://habr.com/ru/post/1486982/


All Articles