[SERVER-7588] mongo shell ISODate return bug Created: 08/Nov/12  Updated: 11/Jul/16  Resolved: 18/Mar/13

Status: Closed
Project: Core Server
Component/s: JavaScript
Affects Version/s: 2.2.0
Fix Version/s: 2.2.6, 2.4.4, 2.5.0

Type: Bug Priority: Major - P3
Reporter: Samuel Ahn Assignee: Tad Marshall
Resolution: Done Votes: 0
Labels: neweng
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Ubuntu 10.04.3


Issue Links:
Related
Backwards Compatibility: Fully Compatible
Operating System: ALL
Participants:

 Description   

For some input strings, mongo shell ISODate() return value has 1 sec difference.
There are examples.

> ISODate("2012-10-02 19:28:16.926")
ISODate("2012-10-02T19:28:15.926Z")
> ISODate("2012-10-02 21:14:08.072")
ISODate("2012-10-02T21:14:07.072Z")
>



 Comments   
Comment by auto [ 01/Jul/13 ]

Author:

{u'username': u'monkey101', u'name': u'Dan Pasette', u'email': u'dan@10gen.com'}

Message: SERVER-7588 Improve logic for seconds and milliseconds in ISODate constructor

Do not use floating point for seconds, only for milliseconds. Adjust other
date components when milliseconds round up to 1000.

Code backported from Tad Marshall's master branch commit:
https://github.com/mongodb/mongo/commit/7cf042ff3e0c97a7fe701cd85f5cdd4c1519179b
Branch: v2.2
https://github.com/mongodb/mongo/commit/5540865628d166f88da833d7470fd3f792c8017d

Comment by auto [ 13/May/13 ]

Author:

{u'date': u'2013-03-18T14:13:45Z', u'name': u'Tad Marshall', u'email': u'tad@10gen.com'}

Message: SERVER-7588 Improve logic for seconds and milliseconds in ISODate constructor

Do not use floating point for seconds, only for milliseconds. Adjust other
date components when milliseconds round up to 1000.
Branch: v2.4
https://github.com/mongodb/mongo/commit/db625382d09b5eabf928ee0abb3de0851da38e9e

Comment by auto [ 18/Mar/13 ]

Author:

{u'date': u'2013-03-18T14:13:45Z', u'name': u'Tad Marshall', u'email': u'tad@10gen.com'}

Message: SERVER-7588 Improve logic for seconds and milliseconds in ISODate constructor

Do not use floating point for seconds, only for milliseconds. Adjust other
date components when milliseconds round up to 1000.
Branch: master
https://github.com/mongodb/mongo/commit/7cf042ff3e0c97a7fe701cd85f5cdd4c1519179b

Comment by Tad Marshall [ 17/Mar/13 ]

Hi Samuel,

Thanks for the great bug report! Yes, the parsing of certain time values in the ISODate() constructor is faulty.

The problem is some poor use of floating point. The JavaScript code in the ISODate constructor assumes that it can use integer math to compute the fractional number of seconds and then subtract that from the original number to get an integer. Depending on the value and its floating point representation, this doesn't work.

> seconds = 16.926;
16.926
> seconds.toPrecision(20);
16.925999999999998380
> var ms = Math.round( (seconds % 1) * 1000);
> ms
926
> ms.toPrecision(20)
926.00000000000000000
> seconds - (ms/1000);
15.999999999999998
>

When this calculated value is truncated to an integer, you lose a second.

Rewriting some of the calculation logic should fix this.

Tad

Generated at Thu Feb 08 03:14:59 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.