Bug #80913 [Ver]: DateTime(Immutable)::sub around DST yield incorrect time

From: Date: Mon, 29 Mar 2021 16:00:34 +0000
Subject: Bug #80913 [Ver]: DateTime(Immutable)::sub around DST yield incorrect time
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-233044@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=80913&edit=1

 ID:                 80913
 Updated by:         cmb@php.net
 Reported by:        acm at tweakers dot net
 Summary:            DateTime(Immutable)::sub around DST yield incorrect
                     time
 Status:             Verified
 Type:               Bug
 Package:            Date/time related
 Operating System:   all
 PHP Version:        8.0.3
 Block user comment: N
 Private report:     N

 New Comment:

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>


Previous Comments:
------------------------------------------------------------------------
[2021-03-29 16:00:21] 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 07:43:44] 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"


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=80913&edit=1


Thread (6 messages)

« previous php.bugs (#233044) next »