Bug #79420 [Opn->Nab]: Time off by a microsecond

From: Date: Fri, 27 Mar 2020 17:35:00 +0000
Subject: Bug #79420 [Opn->Nab]: Time off by a microsecond
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-226286@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=79420&edit=1

 ID:                 79420
 Updated by:         danack@php.net
 Reported by:        danack@php.net
 Summary:            Time off by a microsecond
-Status:             Open
+Status:             Not a bug
 Type:               Bug
 Package:            Date/time related
 Operating System:   MacOS High Sierra 10.13.6
 PHP Version:        7.4.4
 Block user comment: N
 Private report:     N

 New Comment:

PEBKAC.


Previous Comments:
------------------------------------------------------------------------
[2020-03-27 17:13:28] danack@php.net

Description:
------------
Somehow, creating two DateTime objects from the same date input string, and then setting all of the
time values to be 0 manages to create one of them with the wrong microseconds.

I have a testsuite that includes a test for creating a datetime object from user input and comparing
them against a DateTime object created from set parameters. This test has worked for months, but
just now failed twice in a row, and the DateTimes were different.

-2002-10-02T00:00:00.000001+0000
+2002-10-02T00:00:00.000000+0000

The code below is _not_ a reproduce case, but shows what PHPUnit was doing to compare the DateTimes.


Not expecting this to be fixed as high chance it was something specific to my system, more just
creating the report for posterity

Test script:
---------------
<?php

declare(strict_types = 1);


$max = 1000000;
$formatString = \DateTimeInterface::RFC3339_EXTENDED;
$absDelta = 0.0;

for ($i = 0; $i < $max; $i += 1) {
    $actual = \DateTimeImmutable::createFromFormat('Y-m-d', '2002-10-02');
    if ($actual instanceof \DateTimeImmutable) {
        $actual = $actual->setTime(0, 0, 0, 0);
    }
    usleep(rand(0, 1000));

    $expected = \DateTime::createFromFormat('Y-m-d',
'2002-10-02')->setTime(0, 0, 0, 0);
    $delta    = new \DateInterval(\sprintf('PT%dS', $absDelta));
    $actualClone = (clone $actual)
        ->setTimezone(new \DateTimeZone('UTC'));

    usleep(rand(0, 1000));

    $expectedLower = (clone $expected)
        ->setTimezone(new \DateTimeZone('UTC'))
        ->sub($delta);

    usleep(rand(0, 1000));

    $expectedUpper = (clone $expected)
        ->setTimezone(new \DateTimeZone('UTC'))
        ->add($delta);

    if ($actualClone < $expectedLower || $actualClone > $expectedUpper) {
        $string1 = $expected->format($formatString);
        $string2 = $actual->format($formatString);

        echo "Odd\n";
        echo $string1 . "\n";
        echo $string2 . "\n";
        exit(0);
    }

    if ($i % ($max / 100) === 0) {
        echo ".";
    }
    if ($i % ($max / 10) === 0) {
        echo "\n";
    }
}

echo "fin";



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



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


Thread (2 messages)

« previous php.bugs (#226286) next »