Bug #74885 [Com]: Wrong behaviour when comparing dates with microseconds

From: Date: Sun, 09 Jul 2017 15:14:14 +0000
Subject: Bug #74885 [Com]: Wrong behaviour when comparing dates with microseconds
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-209939@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=74885&edit=1

 ID:                 74885
 Comment by:         marcospassos dot com at gmail dot com
 Reported by:        marcospassos dot com at gmail dot com
 Summary:            Wrong behaviour when comparing dates with
                     microseconds
 Status:             Assigned
 Type:               Bug
 Package:            Date/time related
 PHP Version:        7.1.7
 Assigned To:        derick
 Block user comment: N
 Private report:     N

 New Comment:

@requinix yes, sure. However, this is so because it's how PHPUnit handles DateTime comparison,
and how I came up with this issue.

A better workaround for those facing the same issue:

// 1000000 microseconds (1 second):
// https://bugs.php.net/bug.php?id=74885
// @todo Remove it when this bug get fixed
$microseconds = $this->microseconds % 1000000;
$seconds = intval($this->microseconds / 1000000);

return $date->modify(
    sprintf('%d seconds %d microseconds', $seconds, $microseconds)
);


Previous Comments:
------------------------------------------------------------------------
[2017-07-09 15:04:09] nikic@php.net

@derick: Why are the microseconds being stored as a floating point fraction? Can we store them as
integer microseconds instead? I remember seeing some other bug reports also relating to float
precision issues with the microseconds.

------------------------------------------------------------------------
[2017-07-09 15:01:49] derick@php.net

I'm pretty sure that this is due to floating point rounding, but perhaps there is a way to
"fix" this (although I doubt it).

------------------------------------------------------------------------
[2017-07-09 14:57:54] requinix@php.net

Surely assertTrue($expected == $date) is simpler?

Anyway, it's a floating-point issue where 0.456789 + .000001 != 0.456790
@derick can say whether this is a bug to fix or not.

As a workaround you can compare YmdHisu strings, which will have the 'u' part rounded to 6
places. https://3v4l.org/YlCDm

------------------------------------------------------------------------
[2017-07-09 14:30:45] marcospassos dot com at gmail dot com

Description:
------------
Modifying the microsecond part of a DateTime leads to wrong behavior in comparison operators.

Test script:
---------------
$expected = new DateTimeImmutable('2015-08-31 01:02:04.456790');
$date = (new DateTimeImmutable('2015-08-31 01:02:03.456789'))->modify('+1000001
microseconds');

// Expected false, but it's actually true
assertFalse($expected > $date || $expected < $date);

Expected result:
----------------
True

Actual result:
--------------
False


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



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


Thread (10 messages)

« previous php.bugs (#209939) next »