Bug #74885 [Asn->Csd]: Wrong behaviour when comparing dates with microseconds

From: Date: Thu, 17 Aug 2017 09:05:24 +0000
Subject: Bug #74885 [Asn->Csd]: Wrong behaviour when comparing dates with microseconds
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-210703@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
 Updated by:         derick@php.net
 Reported by:        marcospassos dot com at gmail dot com
 Summary:            Wrong behaviour when comparing dates with
                     microseconds
-Status:             Assigned
+Status:             Closed
 Type:               Bug
 Package:            Date/time related
 PHP Version:        7.1.7
 Assigned To:        derick
 Block user comment: N
 Private report:     N

 New Comment:

The fix for this bug has been committed.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.

This is fixed for PHP 7.2(beta3):

derick@singlemalt:~ $ php -v
PHP 7.2.0beta3 (cli) (built: Aug 17 2017 09:57:54) ( NTS DEBUG )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.2.0-dev, Copyright (c) 1998-2017 Zend Technologies

[PHP: 7.2.0-beta3] derick@singlemalt:~ $ cat /tmp/74885.phpt 
<?php
$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
var_dump($expected > $date || $expected < $date);
?>

[PHP: 7.2.0-beta3] derick@singlemalt:~ $ php /tmp/74885.phpt
bool(false)


As I said before, it breaks API/ABI for existing PHP versions, so it won't be fixed there.


Previous Comments:
------------------------------------------------------------------------
[2017-07-10 09:56:10] derick@php.net

@nikic - Why? That's a good question that I don't have an answer to. The problem with
changing it now is that it is an API break in the library :-/

------------------------------------------------------------------------
[2017-07-09 16:00:25] requinix@php.net

Because most of the code supporting DateTime is actually a library.
https://github.com/derickr/timelib

If you missed it, @nikic had just asked @derick about why microseconds are floating-point, so
let's step back and let them work.

------------------------------------------------------------------------
[2017-07-09 15:49:52] marcospassos dot com at gmail dot com

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.

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

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


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 (#210703) next »