Edit report at https://bugs.php.net/bug.php?id=62326&edit=1
ID: 62326
Updated by: cmb@php.net
Reported by: ploeger dot private at googlemail dot com
Summary: date_diff() function returns false result
Status: Open
Type: Bug
Package: Date/time related
Operating System: Windows Server 2008 R2
PHP Version: 5.3Git-2012-06-14 (snap)
Block user comment: N
Private report: N
New Comment:
Yes, definitely DST issue, and I believe already reported
elsewhere in this bugtracker.
Previous Comments:
------------------------------------------------------------------------
[2020-07-09 19:53:52] didomak663 at nalafx dot com
My test script is:
<?php
printf("PHP: %s\nOS: %s\n", PHP_VERSION, php_uname("s")."
".php_uname("r")." ".php_uname("v")."
".php_uname("m"));
$dateBase = "1500-01-01"; // Base date should be less or equal 1919-07-01, buggy
behaviour depends on base date
$testsize = 200000;
$prev_shift = 0;
printf("First date: %s\n", date("Y-m-d", strtotime($dateBase." +0
days")));
for ($i=0; $i<$testsize; $i++) {
$date = date("Y-m-d", strtotime($dateBase." +$i days"));
$interval = date_diff(date_create($date), date_create($dateBase));
$j = $interval->days;
if ($i - $j != $prev_shift) {
printf("%s\t%d\t%d\t%s\n", $date, $i, $j, ($i == $j) ? "date_diff()
recoveres" : ($i - $j)." days shift happens");
$prev_shift = $i - $j;
}
}
printf("Last date: %s\n", date("Y-m-d", strtotime($dateBase."
+$testsize days")));
?>
Expected result:
PHP: 7.3.19-1~deb10u1
OS: Linux 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64
First date: 1500-01-01
Last date: 2047-08-01
Actual results:
PHP: 7.3.19-1~deb10u1
OS: Linux 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2 (2020-04-29) x86_64
First date: 1500-01-01
1916-07-04 152125 152124 1 days shift happens
1922-10-01 154405 154405 date_diff() recoveres
1930-06-22 157226 157225 1 days shift happens
1981-04-01 175772 175772 date_diff() recoveres
1981-04-02 175773 175772 1 days shift happens
1982-04-01 176137 176137 date_diff() recoveres
1982-04-02 176138 176137 1 days shift happens
1983-04-01 176502 176502 date_diff() recoveres
1983-04-02 176503 176502 1 days shift happens
1984-04-01 176868 176868 date_diff() recoveres
1984-04-02 176869 176868 1 days shift happens
1991-09-30 179606 179606 date_diff() recoveres
1992-01-20 179718 179717 1 days shift happens
Last date: 2047-08-01
PHP: 7.3.19-1+ubuntu16.04.1+deb.sury.org+1
OS: Linux 4.4.0-185-generic #215-Ubuntu SMP Mon Jun 8 21:53:19 UTC 2020 x86_64
First date: 1500-01-01
1916-07-04 152125 152124 1 days shift happens
1922-10-01 154405 154405 date_diff() recoveres
1930-06-22 157226 157225 1 days shift happens
1981-04-01 175772 175772 date_diff() recoveres
1981-04-02 175773 175772 1 days shift happens
1982-04-01 176137 176137 date_diff() recoveres
1982-04-02 176138 176137 1 days shift happens
1983-04-01 176502 176502 date_diff() recoveres
1983-04-02 176503 176502 1 days shift happens
1984-04-01 176868 176868 date_diff() recoveres
1984-04-02 176869 176868 1 days shift happens
1991-09-30 179606 179606 date_diff() recoveres
1992-01-20 179718 179717 1 days shift happens
Last date: 2047-08-01
PHP: 5.4.16
OS: Linux 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64
First date: 1500-01-01
1916-07-04 152125 152124 1 days shift happens
1922-10-01 154405 154405 date_diff() recoveres
1930-06-22 157226 157225 1 days shift happens
1981-04-01 175772 175772 date_diff() recoveres
1981-04-02 175773 175772 1 days shift happens
1982-04-01 176137 176137 date_diff() recoveres
1982-04-02 176138 176137 1 days shift happens
1983-04-01 176502 176502 date_diff() recoveres
1983-04-02 176503 176502 1 days shift happens
1984-04-01 176868 176868 date_diff() recoveres
1984-04-02 176869 176868 1 days shift happens
1991-09-30 179606 179606 date_diff() recoveres
1992-01-20 179718 179717 1 days shift happens
Last date: 2047-08-01
------------------------------------------------------------------------
[2019-01-14 16:26:08] esavichev at gmail dot com
Looks like the same issue on PHP 7.2.10-0ubuntu0.18.04.1
Code to reproduce:
-------------------------------------------------------
echo date_diff(
date_create('1921-05-02 00:00:00'),
date_create('1921-05-03 00:00:00')
)->days . "\n"; // 1 - it's correct
echo date_diff(
date_create('1921-05-01 00:00:00'),
date_create('1921-05-02 00:00:00')
)->days . "\n"; // 0 - why zero? expected 1!
echo date_diff(
date_create('1921-05-01 00:00:00'),
date_create('2019-01-01 00:00:00')
)->days . "\n"; // 35673
echo date_diff(
date_create('1921-05-02 00:00:00'),
date_create('2019-01-01 00:00:00')
)->days . "\n"; // 35673 - the same as previous?
-------------------------------------------------------
------------------------------------------------------------------------
[2013-10-30 02:20:15] cmbecker69 at gmx dot de
FWIW: this issue apparently is caused by the daylight saving time shift.
------------------------------------------------------------------------
[2012-06-15 11:17:59] ploeger dot private at googlemail dot com
Test script to show the behavior of the bug:
Test script:
---------------
<?php
const start_date = '2012-06-01 00:00:00';
const end_date = '2012-12-01 00:00:00';
$timezones = array('europe/Berlin', 'GMT', 'CET', 'UTC');
$possibleTimezones = DateTimeZone::listIdentifiers();
$possibleTimezones = array_map('strtolower', $possibleTimezones);
foreach ( $timezones as $testZone )
{
$cur = new DateTimeZone($testZone);
$start = date_create(start_date, $cur);
$end = date_create(end_date, $cur);
$info[] = join(array(
'Soll-TZ : '.$testZone.PHP_EOL,
'Differenz : '.( $start->diff($end)->format('%y Jahre %m Monate %d
Monatstage ( %a tage total )') ).PHP_EOL,
'gelisted : '.( in_array(strtolower($testZone), $possibleTimezones) ?
'Ja' : 'Nein' ).PHP_EOL,
'Alias : '.( strcasecmp($testZone, $cur->getName()) == 0 ? 'Nein'
:
'Ja' ).PHP_EOL,
'Ist-TZ : '.( $cur->getName() ).PHP_EOL,
'start OfS : '.( ( $cur->getOffset($start) / 60 / 60 ) ).'
Stunden'.PHP_EOL,
'end OfS : '.( ( $cur->getOffset($end) / 60 / 60 ) ).'
Stunden'.PHP_EOL
));
}
echo join('--- '.PHP_EOL, $info);
Result:
----------------
Soll-TZ : europe/Berlin
Differenz : 0 Jahre 5 Monate 30 Monatstage ( 183 tage total )
gelisted : Ja
Alias : Nein
Ist-TZ : Europe/Berlin
start OfS : 2 Stunden
end OfS : 1 Stunden
---
Soll-TZ : GMT
Differenz : 0 Jahre 6 Monate 0 Monatstage ( 183 tage total )
gelisted : Nein
Alias : Ja
Ist-TZ : UTC
start OfS : 0 Stunden
end OfS : 0 Stunden
---
Soll-TZ : CET
Differenz : 0 Jahre 5 Monate 30 Monatstage ( 183 tage total )
gelisted : Nein
Alias : Ja
Ist-TZ : Europe/Berlin
start OfS : 2 Stunden
end OfS : 1 Stunden
---
Soll-TZ : UTC
Differenz : 0 Jahre 6 Monate 0 Monatstage ( 183 tage total )
gelisted : Ja
Alias : Nein
Ist-TZ : UTC
start OfS : 0 Stunden
end OfS : 0 Stunden
------------------------------------------------------------------------
[2012-06-14 19:55:15] juergen78 at gmail dot com
My Hosters OS:
Linux alfa3025 2.6.32-bpo.5-amd64 #1 SMP Wed Jul 20 09:10:04 UTC 2011 x86_64
Code:
-----
date_default_timezone_set("Europe/Berlin");
$start_timestamp = date_create('2012-06-01');
$end_timestamp = date_create('2012-12-01');
$difference = date_diff($start_timestamp, $end_timestamp);
$difference = $difference->format('%M');
echo $difference;
Output:
05
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=62326
--
Edit this bug report at https://bugs.php.net/bug.php?id=62326&edit=1