Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to deal with the timezone issue when storing dates in utc using mongod?

I have a mongodb collection where each document has some attributes and a utc timestamp. I need to pull out data from the collection and use the aggregation framework because I use the data from the collection to display some charts on the user interface. However, I need to do the aggregation as per the user's timezone. Assuming I know the user's timezone(passed in the request from browser or in some other manner), is there any way to use the aggregation framework to aggregate based on the [client's] timezone?

like image 350
Hrishi Avatar asked Aug 17 '13 09:08

Hrishi


People also ask

Should dates be stored in UTC?

When storing dates in the database, they should always be in UTC. If you are not familiar with what UTC is, it is a primary time standard that all the major timezones are based on. The major timezones are just offsets from UTC.

Does MongoDB convert date to UTC?

MongoDB stores times in UTC by default, and will convert any local time representations into this form. Applications that must operate or report on some unmodified local time value may store the time zone alongside the UTC timestamp, and compute the original local time in their application logic.

What format does MongoDB store dates?

MongoDB will store date and time information using UTC internally, but can easily convert to other timezones at time of retrieval as needed.

How are dates stored in MongoDB?

Behavior. Internally, Date objects are stored as a signed 64-bit integer representing the number of milliseconds since the Unix epoch (Jan 1, 1970). Not all database operations and drivers support the full 64-bit range. You may safely work with dates with years within the inclusive range 0 through 9999 .


1 Answers

Aside from the SERVER-6310 mentioned by Matt Johnson, one other workaround is to use the $project operator to add or subtract from the UTC time zone to "shift the time" into the correct local zone. Turns out you can add or subtract time in milliseconds.

For example, assuming I have a Date field called orderTime. I'd like to query for EDT. That is -4 hours from UTC. That's 4 * 60 * 60 * 1000 milliseconds.

So I would then write the following projection to get day_ordered in local time for all my records:

db.table.aggregate(      { $project : { orderTimeLocal : { $subtract : [ "$orderTime", 14400000] } } },     { $project : { day_ordered : { $dayOfYear : "$orderTimeLocal" } } }) 
like image 96
Astral Avatar answered Sep 17 '22 18:09

Astral