[SERVER-39600] Server-Updated Timestamp Does Not Follow Local Time Created: 15/Feb/19  Updated: 25/Feb/19  Resolved: 25/Feb/19

Status: Closed
Project: Core Server
Component/s: JavaScript
Affects Version/s: 3.6.2
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Simon Yarde Assignee: Gabriel Russell (Inactive)
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Operating System: ALL
Sprint: Dev Tools 2019-03-11
Participants:

 Description   

Something strange with server-updated Timestamps.  Unsure if this is a bug or expected behaviour that is not documented re interaction with timezones.

Observed in NodeJS driver and confirmed in shell (e.g. below).

Timestamps are being created +1 hour ahead of system localtime.

I believe mongod should always use UTC. Otherwise, daylight saving time zones would break ordering guarantees.

Why is mongod creating timestamps using UTC+1 instead of UTC?

 

$ mongo
MongoDB shell version v3.6.2
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.2
Server has startup warnings:
2019-02-11T09:00:56.005+0000 I CONTROL  [initandlisten]
2019-02-11T09:00:56.005+0000 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2019-02-11T09:00:56.005+0000 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2019-02-11T09:00:56.005+0000 I CONTROL  [initandlisten]
2019-02-11T09:00:56.005+0000 I CONTROL  [initandlisten] ** WARNING: This server is bound to localhost.
2019-02-11T09:00:56.005+0000 I CONTROL  [initandlisten] **          Remote systems will be unable to connect to this server.
2019-02-11T09:00:56.005+0000 I CONTROL  [initandlisten] **          Start the server with --bind_ip <address> to specify which IP
2019-02-11T09:00:56.005+0000 I CONTROL  [initandlisten] **          addresses it should serve responses from, or with --bind_ip_all to
2019-02-11T09:00:56.005+0000 I CONTROL  [initandlisten] **          bind to all interfaces. If this behavior is desired, start the
2019-02-11T09:00:56.005+0000 I CONTROL  [initandlisten] **          server with --bind_ip 127.0.0.1 to disable this warning.
2019-02-11T09:00:56.005+0000 I CONTROL  [initandlisten]
 
> db.test_time.insert({ _id: 1, ts: new Timestamp(0,0) });
WriteResult({ "nInserted" : 1 })
 
> let r = db.test_time.findOne({_id: 1});
 
> let d = new Date(0);
 
> d.setSeconds(r.ts.toJSON().$timestamp.t)
1550242948000
 
> d
ISODate("2019-02-15T15:02:28Z")
 
> ^C
bye
 
$ zdump /etc/localtime
/etc/localtime  Fri Feb 15 14:03:49 2019 GMT
 
$ ls -l /etc/localtime
lrwxr-xr-x  1 root  wheel  39 17 Oct 15:13 /etc/localtime -> /var/db/timezone/zoneinfo/Europe/London



 Comments   
Comment by Gabriel Russell (Inactive) [ 25/Feb/19 ]

simony This does indeed appear to be an upstream spidermonkey bug. I've filed a ticket against their project, https://bugzilla.mozilla.org/show_bug.cgi?id=1530538 .

Besides the workaround that Kelsey recommended, I can offer another alternative. setTime() looks like the more correct way to set the time on a date object, and appears to work correctly. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setTime

Comment by Simon Yarde [ 16/Feb/19 ]

Hi Kelsey

Thanks for your quick reply and workaround. This is really helpful to our current project.

To confirm MongoDB is correctly storing UTC/GMT time on my system:

$ mongo
...
> db.test_time.insert({ _id: 1, ts: new Timestamp(0,0) });
WriteResult({ "nInserted" : 1 })
> db.test_time.find()
{ "_id" : 1, "ts" : Timestamp(1550320429, 1) }
> ^C
bye
$ date -r 1550320429
Sat 16 Feb 2019 12:33:49 GMT
$ date
Sat 16 Feb 2019 12:34:19 GMT

Best Regards

Simon

Comment by Kelsey Schubert [ 16/Feb/19 ]

Hi simony,

Thanks for the report and repro. After changing my local timezone to Europe/London, I was able to reproduce this behavior on my linux machine. The issue appears to be upstream of MongoDB, most likely in SpiderMonkey.

Consider this simplified repro in the mongo shell that does no writes to the database:

> new Date(1550283154915)
ISODate("2019-02-16T02:12:34.915Z")
> let d = new Date(0)
> d.setSeconds(1550283154915 / 1000)
1550286754000
> d
ISODate("2019-02-16T03:12:34Z")

Note that in your case, MongoDB is storing and returning the correct values in UTC, and using the setUTCSeconds method in your repro will confirm the correct result.

> let workaround = new Date(0)
> workaround.setUTCSeconds(1550283154915 / 1000)
1550283154000
> workaround
ISODate("2019-02-16T02:12:34Z")

I'm assigning this to the Dev Tools team to schedule a deeper investigation of the root cause of this issue to open a bug report upstream and apply the fix.

Kind regards,
Kelsey

Generated at Thu Feb 08 04:52:32 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.