I had an issue the last day in our report tool, which is very strange. There are a bunch of entries about DateTime, diff and timezones on stackoverflow. But I haven't found an explanation why this is happening.
Specs
- PHP 7.4.13
- System timezone CET +0100 ->
date +"%Z %z"
Issue
To bulk create reports, I need the interval in days, months and years between two dates. For this purpose I'm using DateTime->diff().
But the result is different, if the system timezone is different:
date_default_timezone_set('UTC');
$dateA1 = new \DateTime('2020-12-01 00:00:00');
$dateA2 = new \DateTime('2020-12-31 23:59:59');
$diffA = $dateA1->diff($dateA2);
print($diffA->format("Year: %Y Month: %M Day: %D"). PHP_EOL);
// Outputs: Year: 00 Month: 00 Day: 30
date_default_timezone_set('CET');
$dateA1 = new \DateTime('2020-12-01 00:00:00');
$dateA2 = new \DateTime('2020-12-31 23:59:59');
$diffA = $dateA1->diff($dateA2);
print($diffA->format("Year: %Y Month: %M Day: %D"). PHP_EOL);
// Outputs: Year: 00 Month: 01 Day: 00
Why? I'm comparing two dates of the same timezone. If I calculate the difference between a dateA and dateB in the same timezone I expect the same result if the two dates are in another timezone. I feel like I'm missing something?
If I check another date 2021-01-01 00:00:00 & 2021-01-31 23:59:59, the issue gets weirder (See full example).
Full Example
# UTC
date_default_timezone_set('UTC');
$dateA1 = new \DateTime('2020-12-01 00:00:00'); // Tue, 01 Dec 2020 00:00:00 +0000
$dateA2 = new \DateTime('2020-12-31 23:59:59'); // Thu, 31 Dec 2020 23:59:59 +0000
$diffA = $dateA1->diff($dateA2);
print($diffA->format("Year: %Y Month: %M Day: %D"). PHP_EOL); // Outputs: Year: 00 Month: 00 Day: 30
$dateB1 = new \DateTime('2021-01-01 00:00:00'); // Fri, 01 Jan 2021 00:00:00 +0000
$dateB2 = new \DateTime('2021-01-31 23:59:59'); // Sun, 31 Jan 2021 23:59:59 +0000
$diffB = $dateB1->diff($dateB2);
print($diffB->format("Year: %Y Month: %M Day: %D"). PHP_EOL); // Outputs: Year: 00 Month: 00 Day: 30
# CET
date_default_timezone_set('CET');
$dateC1 = new \DateTime('2020-12-01 00:00:00'); // Tue, 01 Dec 2020 00:00:00 +0100
$dateC2 = new \DateTime('2020-12-31 23:59:59'); // Thu, 31 Dec 2020 23:59:59 +0100
$diffC = $dateC1->diff($dateC2);
print($diffC->format("Year: %Y Month: %M Day: %D"). PHP_EOL); // Outputs: Year: 00 Month: 01 Day: 00 <-- Why?
$dateD1 = new \DateTime('2021-01-01 00:00:00'); // Fri, 01 Jan 2021 00:00:00 +0100
$dateD2 = new \DateTime('2021-01-31 23:59:59'); // Sun, 31 Jan 2021 23:59:59 +0100
$diffD = $dateD1->diff($dateD2);
print($diffD->format("Year: %Y Month: %M Day: %D"). PHP_EOL); // Outputs: Year: 00 Month: 00 Day: 30
Thanks for your help & best regards Roman