1

I would like to get the date time interval between two dates in a time zone that uses daylight savings time.

The following snipet shows the problem.

$timezone = new DateTimeZone('UTC');
$from_date_obj = DateTime::createFromFormat('Y-m-d H:i:s', '2014-10-31 23:59:59',$timezone);
$to_date_obj = DateTime::createFromFormat('Y-m-d H:i:s', '2014-11-20 23:47:02',$timezone);
$interval = $from_date_obj->diff($to_date_obj, TRUE);
print_r($interval);

For UTC timezone this shows:

DateInterval Object
(
[y] => 0
[m] => 0
[d] => 19
[h] => 23
[i] => 47
[s] => 3
[weekday] => 0
[weekday_behavior] => 0
[first_last_day_of] => 0
[invert] => 0
[days] => 19
[special_type] => 0
[special_amount] => 0
[have_weekday_relative] => 0
[have_special_relative] => 0
)

Now this one:

$timezone = new DateTimeZone('America/Los_Angeles');
$from_date_obj = DateTime::createFromFormat('Y-m-d H:i:s', '2014-10-31 23:59:59',$timezone);
$to_date_obj = DateTime::createFromFormat('Y-m-d H:i:s', '2014-11-20 23:47:02',$timezone);
$interval = $from_date_obj->diff($to_date_obj, TRUE);
print_r($interval);

shows:

DateInterval Object 
(
[y] => 0
[m] => 0
[d] => 20
[h] => -1
[i] => 47
[s] => 3
[weekday] => 0
[weekday_behavior] => 0
[first_last_day_of] => 0
[invert] => 0
[days] => 19
[special_type] => 0
[special_amount] => 0
[have_weekday_relative] => 0
[have_special_relative] => 0
)

the one in UTC shows 19 days/23 hours/47 minutes and 3 seconds. The one for PT shows 20 days/-1 hours/47 minutes and 3 seconds. I think the right answer for PT should be 20 days/0 hours/47 minutes and 3 seconds.

Is there any way to do a diff in the pacific time zone and not end up with the negative hour? Is the -1 hours indication the desired result and what does it mean exactly?


update: I found out that indeed PHP doesn't seem to handle the diff with respect to DST which is discussed here:

PHP's DateTime::Diff gets it wrong?

As far as the results I was getting it appears to be a PHP bug as indicated in the above link.

Community
  • 1
  • 1
macmiller
  • 325
  • 1
  • 4
  • 15

3 Answers3

1

There are two issues raised here: One has to do with the difference between two dates and times when there is a clock change due to DST (Daylight Savings Time). In reality the difference between two dates and times should take into account the clock change, but apparently it does not.

That is documented pretty well in the following link:

PHP's DateTime::Diff gets it wrong?

Further I am chalking up the -1 problem as a php bug. Since PHP doesn't handle the DST changes between two date times anyway, and in my case the difference without taking DST into effect is close enough anyway, I will just do the diff calculation in UTC.

Community
  • 1
  • 1
macmiller
  • 325
  • 1
  • 4
  • 15
0

What php version are you using ? Im getting this result for 2nd code block -

DateInterval Object ( 
[y] => 0 
[m] => 0 
[d] => 19 
[h] => 23 
[i] => 47 
[s] => 3 
[weekday] => 0 
[weekday_behavior] => 0 
[first_last_day_of] => 0 
[invert] => 0 
[days] => 19 
[special_type] => 0 
[special_amount] => 0 
[have_weekday_relative] => 0 
[have_special_relative] => 0 
)

both of the codes should display the same result as your comparing the same date with just different timezone each time

Gal Sisso
  • 1,939
  • 19
  • 20
  • hmmm... version 5.4.29 – macmiller Feb 21 '15 at 11:31
  • I got the 20 days 0 hours from a duration calculator. I think the diff between two days is not the same because in PT the clock changes one hour. eg. the diff between 2014-11-01 23:59 and 2014-11-02 23:59 I think is 1 day, 1 hour because the clock changes 1 hour. – macmiller Feb 21 '15 at 11:36
  • but if they are in the same timezone theres no 1 hour change between them... Lets take for example NY ,one person in NY has the same time as a different person in NY ,right ? so if they will compare times between them self they wont be needed to have clock changes. the only issue you might have between two dates is DST part and thats why all your times should be saved as UTC and then its easier to convert dates – Gal Sisso Feb 21 '15 at 12:06
0

Even after 8 years it is still not supported:

    $day = \DateTime::createFromFormat('Y-m-d', '2023-03-26', new \DateTimeZone('Europe/Budapest'));
    $followingDay = \DateTime::createFromFormat('Y-m-d', $day->format('Y-m-d'), new \DateTimeZone('Europe/Budapest'));
    $followingDay->add(new \DateInterval('P1D'));
    $day2 = \DateTime::createFromFormat('Y-m-d', '2023-03-27', new \DateTimeZone('Europe/Budapest'));
    var_dump($day->getTimestamp(), $followingDay->getTimeStamp(), $day2->getTimeStamp());
    var_dump($day, $followingDay, $day2);

Not to mention that it adds current time instead of 00:00:00 which I read in the documentation, so better to be careful. Though I generally hate PHP because of the low quality documentation, so I almost always write automated tests when I use a built-in function. It is full of bugs or undocumented behavior.

int(1679794696)
int(1679881096)
int(1679877496)

class DateTime#397 (3) {
  public $date =>
  string(26) "2023-03-26 03:38:16.000000"
  public $timezone_type =>
  int(3)
  public $timezone =>
  string(15) "Europe/Budapest"
}
class DateTime#404 (3) {
  public $date =>
  string(26) "2023-03-27 03:38:16.000000"
  public $timezone_type =>
  int(3)
  public $timezone =>
  string(15) "Europe/Budapest"
}
class DateTime#399 (3) {
  public $date =>
  string(26) "2023-03-27 02:38:16.000000"
  public $timezone_type =>
  int(3)
  public $timezone =>
  string(15) "Europe/Budapest"
}
inf3rno
  • 24,976
  • 11
  • 115
  • 197