php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #76374 Date difference varies according day time
Submitted: 2018-05-24 15:47 UTC Modified: 2021-04-06 19:55 UTC
Votes:5
Avg. Score:4.8 ± 0.4
Reproduced:4 of 5 (80.0%)
Same Version:1 (25.0%)
Same OS:2 (50.0%)
From: fcasadei at fcpartner dot com Assigned: derick (profile)
Status: Closed Package: Date/time related
PHP Version: 7.0.30 OS: linux & windows
Private report: No CVE-ID: None
 [2018-05-24 15:47 UTC] fcasadei at fcpartner dot com
Description:
------------
---
From manual page: http://www.php.net/datetime.diff
---

$objDateTo = new dateTime('2017-10-01');
$objDateFrom = new dateTime('2017-01-01');
$interval = $objDateTo->diff($objDateFrom);
echo $interval->m;

will display 8

$objDateTo = new dateTime('2017-10-01 12:00:00');
$objDateFrom = new dateTime('2017-01-01 12:00:00');
$interval = $objDateTo->diff($objDateFrom);
echo $interval->m;

will display 9

Expected result:
----------------
Should be 9 in both cases


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2018-05-26 12:35 UTC] a at b dot c dot de
I get 8 in both cases (more precisely, 8 months, 30 days - just shy of nine months).

When exactly does Daylight Saving start in your locale?
 [2018-05-26 13:18 UTC] fcasadei at fcpartner dot com
In France, I don't know exactly.
 [2018-05-26 14:15 UTC] rauljosesantos at gmail dot com
If you define your timezone:

ini_set("date.timezone", "GMT");

Both work nicely

https://3v4l.org/SuVe2

ini_set("date.timezone", "GMT");
$objDateTo = new dateTime('2017-10-01')
$objDateFrom = new dateTime('2017-01-01
$interval = $objDateTo->diff($objDateFr
echo "Date Only: " . $interval->m . "\r
$objDateTo = new dateTime('2017-10-01 1
$objDateFrom = new dateTime('2017-01-01
$interval = $objDateTo->diff($objDateFr
echo "Date and Time: " . $interval->m;
 [2018-05-28 13:41 UTC] fcasadei at fcpartner dot com
thanks
but with ("date.timezone", "Europe/Paris"), back to 8 and 9 !!
 
Is PHP another american centric stuff ?

ini_set("date.timezone", "Europe/Paris");
$objDateTo = new dateTime('2017-10-01');
$objDateFrom = new dateTime('2017-01-01');
$interval = $objDateTo->diff($objDateFrom);
echo $interval->m;
$objDateTo = new dateTime('2017-10-01 00:00:00');
$objDateFrom = new dateTime('2017-01-01 00:00:00');
$interval = $objDateTo->diff($objDateFrom);
echo $interval->m;
$objDateTo = new dateTime('2017-10-01 12:00:00');
$objDateFrom = new dateTime('2017-01-01 12:00:00');
$interval = $objDateTo->diff($objDateFrom);
echo $interval->m;

gives 889 !!
12 hours make a month ???
 [2018-05-28 17:38 UTC] derick@php.net
-Status: Open +Status: Assigned -Assigned To: +Assigned To: derick
 [2018-05-28 17:38 UTC] derick@php.net
Considering that the author is European (me), I can assure you there is nothing US centric here.

However, there does seem to be a bug, as it should indeed say 9 in each case.

Assigning to myself.
 [2018-05-30 12:21 UTC] a at b dot c dot de
Given that the interval changed when the time was specified, I did suspect that something happened sometime in the morning the start or the afternoon of the end that changed the length; but No, Europe/Paris doesn't have anything special to say about those dates.

I looked at a few other zones and intervals.
(a) Asia/Baghdad also displays varying results despite not crossing a DST boundary
(b) America/Denver is consistent, even though it does cross a DST boundary.
(c) The period from 1 January to 1 February gives consistent results for all zones
(d) The period from 1 July to 1 August does not; this time though the affected zones are Europe/Paris, Europe/Lisbon, Asia/Baghdad, and Pacific/Auckland.
(e) The number of days is always the same. For the January-October period, it is 273; the variation seen in Europe/Paris and Asia/Baghdad is that 273 days makes nine months when counting from midnight, but only eight months 30 days when counting from midday.

<?php

$zones_to_try = [
	"UTC",
	"Europe/Paris",
	"Europe/Lisbon",
	"Asia/Baghdad",
	"Pacific/Auckland",
	"America/Phoenix",
	"America/Denver",
];

foreach($zones_to_try as $zone)
{
	echo "$zone:\n";
	date_default_timezone_set($zone);
	$objDateTo = new dateTime('2017-10-01');
	$objDateFrom = new dateTime('2017-01-01');
	$interval = $objDateTo->diff($objDateFrom);
	echo "From {$objDateFrom->format('c')} to {$objDateTo->format('c')}: {$interval->m}m {$interval->d}d ({$interval->days} days)\n";
	$objDateTo = new dateTime('2017-10-01 12:00:00');
	$objDateFrom = new dateTime('2017-01-01 12:00:00');
	$interval = $objDateTo->diff($objDateFrom);
	echo "From {$objDateFrom->format('c')} to {$objDateTo->format('c')}: {$interval->m}m {$interval->d}d ({$interval->days} days)\n";
	echo "\n\n";
}
?>
 [2018-05-30 13:06 UTC] fcasadei at fcpartner dot com
Geee !! you are the author ??
Congrats Congrats congrats congrats !!!
Php is the coolest language I ever used (in 30 yars ... started with 8086 asembly, pascal, cobol, fortran, basic, ... list, ... and some I won't admit)
 [2018-05-30 15:15 UTC] derick@php.net
@a - it's not related to DST changeovers (for once). But what happens is that PHP converts it first to UTC time, which ends up comparing 2016-12-31 23:00 to 2017-09-30 22:00 - and then the algorithm gets even more confused and messes up.

This code is complex, and needs to be rewritten sadly. It's going to take some time.
 [2021-04-06 19:55 UTC] derick@php.net
-Status: Assigned +Status: Closed
 [2021-04-06 19:55 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: Tue Mar 19 03:01:29 2024 UTC