[php-src] Issue #18875: "Same" DateInterval instances lead to different results, depending on the origin (in combination with DST-switches)

From: Date: Thu, 19 Jun 2025 08:57:02 +0000
Subject: [php-src] Issue #18875: "Same" DateInterval instances lead to different results, depending on the origin (in combination with DST-switches)
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-250279@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/18875 Author: cziegenberg ### Description The following code: ```php <?php function getIntervalSpecificationFromDateInterval(DateInterval $interval): string { $specification = ''; if ($interval->invert) { $specification .= '-'; } $specification .= 'P'; $specification .= $interval->y ? $interval->y . 'Y' : ''; $specification .= $interval->m ? $interval->m . 'M' : ''; $specification .= $interval->d ? $interval->d . 'D' : ''; if ($interval->h + $interval->i + $interval->s) { $specification .= 'T'; $specification .= $interval->h ? $interval->h . 'H' : ''; $specification .= $interval->i ? $interval->i . 'M' : ''; $specification .= $interval->s ? $interval->s . 'S' : ''; } if ($specification === 'P' || $specification === '-P') { $specification = 'PT0S'; } return $specification; } $timezone = new DateTimeZone('Europe/Berlin'); $dstSwitchA = new DateTimeImmutable('2025-03-30 01:00:00', $timezone); $dstSwitchB = new DateTimeImmutable('2025-10-26 01:00:00', $timezone); $durationA = new DateInterval('PT3H'); $durationB = (new DateTimeImmutable('2025-03-28 01:00:00', $timezone))->diff( new DateTimeImmutable('2025-03-28 04:00:00', $timezone), true ); $durationC = (new DateTimeImmutable('2025-03-28 01:00:00', $timezone))->diff( new DateTimeImmutable('2025-03-28 04:00:00', $timezone), ); $durationD = (new DateTimeImmutable('2025-03-28 01:00:00', $timezone))->diff( new DateTimeImmutable('2025-03-28 04:00:00', $timezone), ); $durationD = new DateInterval(getIntervalSpecificationFromDateInterval($durationD)); // Test 1st DST-switch (+1 hour) echo 'TEST 1 (DST-switch +1 hour)' . PHP_EOL; $datetimeA = $dstSwitchA->setTimezone($timezone)->add($durationA); echo 'Constructed: ' . $datetimeA->format('Y-m-d H:i:s') . PHP_EOL; // expected: 2025-03-30 05:00:00 $datetimeB = $dstSwitchA->setTimezone($timezone)->add($durationB); echo 'Diff (absolute): ' . $datetimeB->format('Y-m-d H:i:s') . PHP_EOL; // expected: 2025-03-30 05:00:00 $datetimeC = $dstSwitchA->setTimezone($timezone)->add($durationC); echo 'Diff (relative): ' . $datetimeC->format('Y-m-d H:i:s') . PHP_EOL; // expected: 2025-03-30 05:00:00 $datetimeD = $dstSwitchA->setTimezone($timezone)->add($durationD); echo 'Workaround: ' . $datetimeD->format('Y-m-d H:i:s') . PHP_EOL; // expected: 2025-03-30 05:00:00 echo PHP_EOL; echo 'TEST 2 (DST-switch -1 hour)' . PHP_EOL; // Test 2nd DST-switch (-1 hour) // Expected value: 2025-10-26 03:00:00 $datetimeA = $dstSwitchB->setTimezone($timezone)->add($durationA); echo 'Constructed: ' . $datetimeA->format('Y-m-d H:i:s') . PHP_EOL; $datetimeB = $dstSwitchB->setTimezone($timezone)->add($durationB); echo 'Diff (absolute): ' . $datetimeB->format('Y-m-d H:i:s') . PHP_EOL; $datetimeC = $dstSwitchB->setTimezone($timezone)->add($durationC); echo 'Diff (relative): ' . $datetimeC->format('Y-m-d H:i:s') . PHP_EOL; $datetimeD = $dstSwitchB->setTimezone($timezone)->add($durationD); echo 'Workaround: ' . $datetimeD->format('Y-m-d H:i:s') . PHP_EOL; ``` Resulted in this output: ``` TEST 1 (DST-switch +1 hour) Constructed: 2025-03-30 05:00:00 Diff (absolute): 2025-03-30 04:00:00 Diff (relative): 2025-03-30 04:00:00 Workaround: 2025-03-30 05:00:00 TEST 2 (DST-switch -1 hour) Constructed: 2025-10-26 03:00:00 Diff (absolute): 2025-10-26 04:00:00 Diff (relative): 2025-10-26 04:00:00 Workaround: 2025-10-26 03:00:00 ``` But I expected this output instead: ``` TEST 1 (DST-switch +1 hour) Constructed: 2025-03-30 05:00:00 Diff (absolute): 2025-03-30 05:00:00 Diff (relative): 2025-03-30 05:00:00 Workaround: 2025-03-30 05:00:00 TEST 2 (DST-switch -1 hour) Constructed: 2025-10-26 03:00:00 Diff (absolute): 2025-10-26 03:00:00 Diff (relative): 2025-10-26 03:00:00 Workaround: 2025-10-26 03:00:00 ``` ### PHP Version ```plain PHP 8.3.16 (cli) (built: Jan 14 2025 20:07:09) (NTS Visual C++ 2019 x64) Copyright (c) The PHP Group Zend Engine v4.3.16, Copyright (c) Zend Technologies with Zend OPcache v8.3.16, Copyright (c), by Zend Technologies with Xdebug v3.4.1, Copyright (c) 2002-2025, by Derick Rethans Tested with PHP 8.1.0 to 8.4.8 ``` ### Operating System _No response_

« previous php.bugs (#250279) next »