php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #80913 DateTime(Immutable)::sub around DST yield incorrect time
Submitted: 2021-03-29 07:43 UTC Modified: 2021-04-06 19:57 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: acm at tweakers dot net Assigned: derick (profile)
Status: Closed Package: Date/time related
PHP Version: 7.4 OS: all
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: acm at tweakers dot net
New email:
PHP Version: OS:

 

 [2021-03-29 07:43 UTC] acm at tweakers dot net
Description:
------------
DateTimeImmutable and DateTime with a time like '2021-03-28 03:00:00' in 'Europe/Amsterdam' (i.e. the moment of the DST-transition) will give the wrong time when substracting less than an hour. 

The same goes for all times that will give a result within an hour from 03:00+02:00.

I.e. when substracting 30 minutes, you get the same time as when _adding_ (+60-30 = ) 30 minutes.

And the same when using DateTimeImmutable. The before-output should be 01:30+01:00.

https://3v4l.org/ZZjvq (DateTimeImmutable)
https://3v4l.org/v3u2v (DateTime)

Btw substracting 60 minutes gives the exact same time again (03:00:00+02:00), while substracting 61 minutes correctly gives "2021-03-28T00:59:00+01:00".

Test script:
---------------
$date = new DateTime('2021-03-28 03:00:00', new DateTimeZone('Europe/Amsterdam'));
$_30mbefore = (clone $date)->sub(new DateInterval('PT30M'));
$_30mafter = (clone $date)->add(new DateInterval('PT30M'));

var_dump($date->format(DATE_ATOM));
var_dump($_30mbefore->format(DATE_ATOM));
var_dump($_30mafter->format(DATE_ATOM));



Expected result:
----------------
string(25) "2021-03-28T03:00:00+02:00"
string(25) "2021-03-28T01:30:00+01:00" (correct)
string(25) "2021-03-28T03:30:00+02:00"

Actual result:
--------------
string(25) "2021-03-28T03:00:00+02:00"
string(25) "2021-03-28T03:30:00+02:00" (incorrect)
string(25) "2021-03-28T03:30:00+02:00"

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2021-03-29 16:00 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2021-03-29 16:00 UTC] cmb@php.net
This affects older PHP versions as well[1].  Interestingly, there
is some code which is supposed to cater to that[2], but it is not
executed since t->dst==1.

[1] <https://3v4l.org/KKHlK>
[2] <https://github.com/php/php-src/blob/php-7.4.16/ext/date/lib/interval.c#L126>
 [2021-03-29 16:16 UTC] cmb@php.net
-PHP Version: 8.0.3 +PHP Version: 7.4
 [2021-03-31 16:34 UTC] cmb@php.net
This appears to be related to bug #60960, and might even have the
same root cause.
 [2021-03-31 17:38 UTC] cmb@php.net
Appears to be related to bug #73460 as well.
 [2021-04-06 19:57 UTC] derick@php.net
-Status: Verified +Status: Closed -Assigned To: +Assigned To: derick
 [2021-04-06 19:57 UTC] derick@php.net
The fix for this bug has been committed.
If you are still experiencing this bug, try to check out latest source from https://github.com/php/php-src and re-test.
Thank you for the report, and for helping us make PHP better.

Fixed for PHP 8.1.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 05 17:01:30 2024 UTC