Nanoseconds lost coming from MongoDB ISODate Object
Asked Answered
S

2

5

I'm losing the nanoseconds from the MongoDb interface for the ISODate object. All the nanoseconds are set to zero when I read them in perl.

First, my environment:

MongoDB version: 1.8.2 
perl v5.12.4 
MongoDB perl module version: 0.701.4 

I have a Mongo DB that has rtcTime coded as an ISODate, as follows:

"rtcTime" : ISODate("2013-05-13T18:54:55.918Z")

The code to extract the rtcTime looks something like this:

my @results = $db->get_collection( 'timings' )->find( )->all(); 
foreach my $record ( @results ) 
{ 
    print $record->{rtcTime}->nanoseconds()."\n"; 
}

Output is all 0's.

To fully reproduce the problem, create an ISODate object with arbitrary (non-zero) hires_epoch values in the MongoDB database. Then try to use the MongoDB / DateTime / DateTime::Format::ISO8061 modules to extract any kind of hires time data.

Q: Why can't I get my milliseconds, microseconds, or nanoseconds from the MongoDB ISODate data?

Shirt answered 4/7, 2013 at 18:13 Comment(1)
what kind of object does it have the time as in perl? print ref($record->{rtcTime})?Rhombic
S
7

MongoDB stores documents in BSON format and its specification says:

BSON Date is a 64-bit integer that represents the number of milliseconds since the Unix epoch (Jan 1, 1970).

So, date precision is limited to miliseconds. If you really need to store nanoseconds, you shouldn't use date type. You have to use a long and store the timestamp, so that you'll no lose precision.

Shroud answered 4/7, 2013 at 18:30 Comment(4)
but the question implies milliseconds are lost too, that they are just using nanoseconds() (though I believe that is a lie and it is really nanosecond()) to get the milliseconds.Rhombic
well, he/she said that are losing nanoseconds and the code is printing nanoseconds, so I assumed that the problem is with nanoseconds.Shroud
the code shows inserting a time with milliseconds and they claim it prints 0 nanoseconds. if it is being represented as a DateTime object in perl, it nanosecond() would give a non-zero value in this case.Rhombic
Thank you for your replies. And apologies for not being clear. I gave an example of one of the facets of this issue. None of the hires_epoch related time fields work. Not milliseconds, microseconds, or nanoseconds. The issue seems to be the MongoDB perl interface doesn't transfer the hires values.Shirt
W
3

This is a bug in the way that the MongoDB Perl driver interacts with DateTime. When ISODate values are retrieved from the database, the driver initializes the DateTime object using its from_epoch constructor. But the nanosecond portion is not passed to the constructor.

DateTime does support passing the full value including nanoseconds, and the driver should be updated to fix that.

I've created a ticket for this bug and I will fix it. But maybe not until after the holiday weekend. :)

Wulfila answered 4/7, 2013 at 19:5 Comment(4)
Thank you friedo! I suspected it was a bug in the DateTime MongoDB interface.Shirt
Freido, any luck yet? ( Maybe I should join the mongodb.org forum? )Shirt
@user2551436 sorry for the delay. I'm doing a new release today which should fix the problem. :)Wulfila
@user2551436 This bug is fixed in release 0.702.0.Wulfila

© 2022 - 2024 — McMap. All rights reserved.