Bug #52480 [Com]: Incorrect difference using DateInterval

From: Date: Mon, 20 Mar 2017 11:23:00 +0000
Subject: Bug #52480 [Com]: Incorrect difference using DateInterval
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-207960@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=52480&edit=1

 ID:                 52480
 Comment by:         tomasz dot majerski at o2 dot pl
 Reported by:        alex dot joyce at staff dot comcen dot com dot au
 Summary:            Incorrect difference using DateInterval
 Status:             Closed
 Type:               Bug
 Package:            Date/time related
 Operating System:   Debian 5.0.3
 PHP Version:        5.3.3
 Assigned To:        derick
 Block user comment: N
 Private report:     N

 New Comment:

Don't close this issue. PHP 7.0.6 still not getting expected results...

$date_start = '2017-03-01';
$date_end = '2017-03-31';

DateInterval Object
(
    [y] => 0
    [m] => 1
    [d] => 2
    [h] => 0
    [i] => 0
    [s] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 0
    [days] => 30
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
)


Previous Comments:
------------------------------------------------------------------------
[2017-03-19 09:58:41] heiglandreas@php.net

This seems to be fixed in supported versions of PHP. Therefore I'm closing this issue.

php > $date_start = new DateTime('2010-03-01');
php >   $date_end   = new DateTime('2010-07-29');
php >
php >   $interval = $date_start->diff($date_end);
php >
php >   print_r($interval);
DateInterval Object
(
    [y] => 0
    [m] => 4
    [d] => 28
    [h] => 0
    [i] => 0
    [s] => 0
    [f] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 0
    [days] => 150
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
)

------------------------------------------------------------------------
[2016-11-23 07:14:51] lebeker at gmail dot com

Still got a problems:

(new DateTime('2016-10-01'))->diff((new DateTime('2016-10-31'))) // 1 month
(new DateTime('2016-11-01'))->diff((new DateTime('2016-11-30'))) // 29 days
either first should be 30 days, or the second one 1 month

(new DateTime('2016-11-01'))->diff((new DateTime('2016-12-01'))) // 30 days
but that's definitely 1 whole month

and what's more interesting
(new DateTime('2016-11-01'))->diff((new DateTime('2016-11-31'))) // 30 days
but there is no such date as '2016-11-31', but that's probably another bug.


PHP 7.0.8-0ubuntu0.16.04.3

------------------------------------------------------------------------
[2016-02-12 01:56:26] pinballfan at outlook dot com

After trying Marcel's code I got the same 'problem' on PHP 5.6 on a 64bit Windows 10
machine.  However unexpected the result, I believe it is consistent with how PHP's datetime
rounds dates around.  Using this example:

$date1 = new DateTime('2011-08-31T00:00:00Z');
$date2 = new DateTime('2012-03-01T00:00:00Z');
$interval = $date1->diff($date2);
var_dump($interval);

$interval->m = 5
$interval->d = 30

The expectation might be 6 months and 1 day

What I'm guessing might be happening is that PHP starts adding 1 month like so:
2011-08-31 = starting date
2011-09-31 = starting date + 1 month (but there is no such thing as sept 31!)
2011-10-01 = date now wraps around to 2011-10-01 since
             2011-09-31 doesn't exist
2011-11-01 = + 1 month (2 total)
2011-12-01 = + 1 month (3 total)
2012-01-01 = + 1 month (4 total)
2012-02-01 = + 1 month (5 total)
2012-03-01 = When diff'ing PHP does NOT include the final date maybe like DatePeriod.

So that could be how it arrived at 5m and 30d

------------------------------------------------------------------------
[2015-01-12 09:43:52] marcel at berteler dot co dot za

I experience the same issue where the month is incorrectly calculated:

$Dob = new DateTime();
$Dob->setDate(2011, 8, 31);
$Dob->setTime(0,0,0);


$VisitDate = new DateTime();
$VisitDate->setDate(2012, 03, 01);
$VisitDate->setTime(0,0,0);

$interval = $Dob->diff($VisitDate);

echo $interval->m;
echo $interval->d;

Should return 6 & 1 but returns 5 & 30.

Changing the timezones still returns unexpected results:

$Dob = new DateTime();
$Dob->setTimezone(new DateTimeZone('UTC'));
$Dob->setDate(2011, 8, 30);
$Dob->setTime(0,0,0);


$VisitDate = new DateTime();
$VisitDate->setTimezone(new DateTimeZone('UTC'));
$VisitDate->setDate(2012, 2, 1);
$VisitDate->setTime(0,0,0);

$interval = $Dob->diff($VisitDate);

echo $interval->m; (returns 5)
echo $interval->d; (return 2)

2011-08-30 to 2012-03-01 return 6 months and 0 days.

Tried it in on both a Linux and Windows server and same result.

------------------------------------------------------------------------
[2014-11-19 10:00:52] ilantipov at gmail dot com

Had the same issue 
diff between 01-04-2014 and 01-07-2014
: 
DateTime Object
(
    [date] => 2014-04-01 00:00:00.000000
    [timezone_type] => 3
    [timezone] => Europe/Moscow
)
DateTime Object
(
    [date] => 2014-07-01 00:00:00.000000
    [timezone_type] => 3
    [timezone] => Europe/Moscow
)
DateInterval Object
(
    [y] => 0
    [m] => 2
    [d] => 30
    [h] => 0
    [i] => 0
    [s] => 0
    [weekday] => 0
    [weekday_behavior] => 0
    [first_last_day_of] => 0
    [invert] => 1
    [days] => 91
    [special_type] => 0
    [special_amount] => 0
    [have_weekday_relative] => 0
    [have_special_relative] => 0
)
The right interval is 3 month. Not 2 month 30 days. Both dates have same timezone. If I add
date_default_timezone_set('UTC') before diff - everything works fine;

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


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=52480


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


Thread (28 messages)

« previous php.bugs (#207960) next »