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

From: Date: Sun, 09 Jul 2017 15:49:53 +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-209942@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:

I can't understand why it's internally stored as float, neither why DateInverval exposes
the f property as float, once microseconds cannot be expressed as a fraction in PHP.


Previous Comments:
------------------------------------------------------------------------
[2017-07-09 15:30:35] requinix@php.net

That may work for your example but it does not work in the general case.
https://3v4l.org/c54Dt

The problem is not in how the DateTime is modified but in how it is compared. Specifically, in how
the microseconds values are compared. As things stand, if you require microsecond-level precision
then you must use your own custom comparison strategy.

------------------------------------------------------------------------
[2017-07-09 15:14:12] marcospassos dot com at gmail dot com

@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)
);

------------------------------------------------------------------------
[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

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


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


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


Thread (10 messages)

« previous php.bugs (#209942) next »