Issues

ZF-3300: Wrong comparison operator used in Zend_Date addMillisecond method results in an inaccurate timestamp

Issue Type: Bug Created: 2008-05-20T10:56:47.000+0000 Last Updated: 2008-09-02T10:39:26.000+0000 Status: Resolved Fix version(s): - 1.6.0 (02/Sep/08)

Reporter: Metagamer (metagaming) Assignee: Thomas Weidner (thomas) Tags: - Zend_Date

Related issues: Attachments:

Description

If the current millisecond precision of the Zend_Date class is set to 3 the local $max variable will evaluate to 1000, but you will need to add 1001 millisecond to get it to add a whole second to the timestamp instead of 1000.

Instead of the $this->_Fractional > $max condition, it should be changed to $this->_Fractional >= $max

Between lines 4420 and 4427 of Zend/Date.php

    $max = pow(10, $this->_Precision);
    // milli includes seconds
    if ($this->_Fractional > $max) {
        while ($this->_Fractional > $max) {
            $this->addSecond(1);
            $this->_Fractional -= $max;
        }
    }

should be

    $max = pow(10, $this->_Precision);
    // milli includes seconds
    if ($this->_Fractional >= $max) {
        while ($this->_Fractional >= $max) {
            $this->addSecond(1);
            $this->_Fractional -= $max;
        }
    }

Comments

Posted by Thomas Weidner (thomas) on 2008-05-20T11:39:15.000+0000

Please give example code for reproduction

Posted by Metagamer (metagaming) on 2008-05-20T12:11:42.000+0000

Quick sample code and you can see the improper seconds. Changing the (>) to (>=) fixes the issue

<pre class="highlight">
<?php

set_include_path(get_include_path() . PATH_SEPARATOR . '../library/Zend');

require_once 'Zend/Date.php';

$date = new Zend_Date();


// pick a timestamp any time stamp will do
$date->setTimestamp(1234567890);
// Have a look at the date and note how many seconds
echo "Date set: " . $date->getTime() . "<br></br>\n";
// Zend_Date defaults to 0 milliseconds
echo "Milliseconds: " . $date->getMillisecond() . "<br></br>\n";
// Get the current millisecond precision
echo "Millisecond Precison: " . $date->getFractionalPrecision() . "<br></br>\n";
// By default Zend_Date has 3 digit precison for milliseconds
// which would mean 1000 = 1 second so lets add 1000 and check the date
$date->addMilliSecond(1000);
echo "New Date set: " . $date->getTime() . "<br></br>\n";
// Zend_Date defaults to 0 milliseconds
echo "New Milliseconds: " . $date->getMillisecond() . "<br></br>\n";
// Oops! we have 1000 milliseconds but havent added a new second to the timestamp
// lets add 1 more millisecond for a total of 1001 milliseconds
$date->addMilliSecond(1);
echo "New Date set: " . $date->getTime() . "<br></br>\n";
// Zend_Date defaults to 0 milliseconds
echo "New Milliseconds: " . $date->getMillisecond() . "<br></br>\n";
// Now it rolled over and added a new second
?>

Posted by Metagamer (metagaming) on 2008-05-20T12:19:55.000+0000

Please forgive the extra comment lines and typos. First bug in a major project I've been the first to find and fix :)

Posted by Metagamer (metagaming) on 2008-05-20T12:26:31.000+0000

typo fix...

precision of the Zend_Date class is set to 2 changed to precision of the Zend_Date class is set to 3

since precision of 2 would evaluate to 100 not 1000

Posted by Thomas Weidner (thomas) on 2008-05-25T07:54:34.000+0000

Fixed with r9523.

Thanks for the example code and the outlined patch.

Posted by Wil Sinclair (wil) on 2008-09-02T10:39:26.000+0000

Updating for the 1.6.0 release.

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts