My users could create some objects that have specific time and search them by query for specific startTime and endTime.
My question is how should I store these objects in my database (MongoDB)? Should I store them in UTC or with specific timezone that relates to user that create object?
Use UTC date format, and convert all data to UTC: when create, update, delete objects or filter them. Use one UTC time zone helps you avoid a lot of problems, and simplify you code.
example
> var now = new Date();
> Mon May 26 2014 10:55:34 GMT+0300 (Kaliningrad Standard Time)
> now.toUTCString();
> Mon, 26 May 2014 07:55:34 GMT
> new Date(now.toUTCString())
> Mon May 26 2014 10:55:34 GMT+0300 (Kaliningrad Standard Time)
When you create a new Javascript date object and assign it to a Mongo date field, it will automatically be usable with any timezone. If all you need is the current time, you can just use new Date(). But if you need to take a string and have it be interpreted in a specific timezone, or you are going to be presenting a time to a user in a specific timezone, I highly recommend checking out Moment Timezone.
This code will take a date object stored in a Mongo model (which could be 1AM on January 1, 2014 in Sydney, Australia) and present it formatted to a Los Angeles timezone (which would still be December 31, 2013).
collection.find({_id: 123}, function(err, model) {
userDate = moment(model.date).tz("America/Los_Angeles").format("MM/DD/YYYY");
});
And if you ever need to parse a string that doesn't specify a UTC offset as a specific timezone, you can use the constructor:
moment.tz("2013-11-18 11:55", "America/Toronto")
Related
Without using momentjs on client-side. I need to properly save the date/time to the db and pull it back, followed by converting it to local.
I noticed the material-ui datepicker took care of this before but now I need to do it myself.
The html input 'datetime-local' doesn't like receiving timezone so I'm not sure how to do the whole flow.
I think I need to get UTC date on the client side like this for the db (?)
2021-10-26T01:14:27.920+00:00
And somehow on turn it into something input 'datetime-local' will accept.
Any help appreciated
You can achive in the folllowing ways
// Create date object from datetime string
var date = new Date('2021-10-26T01:14:27.920+00:00');
// Coverting local datetime back to UTC
console.log(date.toUTCString()); // Output "Tue, 26 Oct 2021 01:14:27 GMT"
// Coverting to local datetime
console.log(date.toString()); // Output "Tue Oct 26 2021 06:44:27 GMT+0530 (India Standard Time)"
// Coverting to local timezone
console.log(date.toLocaleString()); // Output "10/26/2021, 6:44:27 AM"
After receiving idToken from Google and verified, I noticed its exp: 1623186214 is always set to 1970 which will always expire itself. For example var when=new Date(1623186214); resulting Mon Jan 19 1970 10:53:06 GMT-0800 (Pacific Standard Time).
How to address it? Thank you in advance.
Okay, the exp is in seconds since midnight 01 January 1970 GMT.
So the correct way to check expiration is
var d=new Date('1970-01-01T00:00:00Z'); // 1970-01-01 GMT
d.setUTCSeconds(1623259934); // the value of 'exp', note use UTC not setSeconds().
Now it's Wed Jun 09 2021 10:32:14 GMT-0700 (Pacific Daylight Time), one hour after log in.
However, some better ways to validate it:
use Google's public endpoint
use Google's client library google-auth-library
Details on Authenticate with a backend server
JWT timestamp in seconds, but Javascript Date requiring milliseconds. But both JWT and Javascript Date constructor use the idea “since the epoch”. So just multiple exp by 1000.
new Date(exp * 1000)

just wondering why and how when I save some date() in mongoose model:
renovate: {
type: Date
}
it is storage in mongodb as:
ISODate("2020-04-12T11:54:54.568Z"
but if I fetch this data into my front end looks like current (correct) time?
Sun Apr 12 2020 13:54:54 GMT+0200 (Central European Summer Time)
MongoDB can only store times in UTC. Mongoose appears to translate UTC timestamps into local time, presumably for convenience.
The first answer of this question suggests that mongoose would adapt the date according to server timezone when retrieving data.
However, I don't have this comportement.
I set the (node) server timezone with :
process.env.TZ='Europe/Paris'
For exemple if I create a simple model like :
const mongoose = require("mongoose");
const testSchema = new mongoose.Schema({
myDate: { type: Date, required: true },
}, { timestamps: true });
exports.Comment = mongoose.default.model('TestSchema', testSchema);
But if I create a date with 2020-01-01 20:20:20, when doing TestSchema.find() the date will be: 2020-01-01T19:20:20.000Z so there are two things that I don't understand :
Europe/Paris is actually UTC +2, so I would expect the date to be either 2020-01-01T18:20:20.000Z in UTC or 2020-01-01T20:20:20.000Z with the server timezone
How to have mongoose automatically set the date to the correct timezone?
I know that myDate is a Date object, so I can convert it manually but I'd rather not have to do it myself for simple reasons like forgetting to convert one of the dates in the application or not having to do it every time a Date field is added
An easy solution that I can think of would be to register a global plugin for mongoose which would use schema.set('toJSON', ... and schema.set('toObject', ...) with the transform method so I can loop through schema fields and if the field is a Date, update it to my timezone.
But I see two problems with this approch :
It doesn't sound very good performance-wise if I am querying a lot of documents each with a lot of fields
As you can see here I am currently not able to register global plugins...
What would be the best method to get the date in the server timezone format? I would rather still store them in UTC but set the hour according to the server timezone.
EDIT :
I just saw that while console.log(myDate) outputs 2018-01-01T19:20:20.000Z console.log(myDate.toString() outputs Mon Jan 01 2018 20:20:20 GMT+0100 (Central European Standard Time) so it seems likes this could be used, even tho I'd rather still have a Date object and converting it to string just before sending it to the client (would need some formatting tho since this format is not very user friendly). But then again, how would I do this globally and not for every date
A few things:
Europe/Paris at 2020-01-01T20:20:20 is UTC+1. It doesn't switch to UTC+2 until Summer Time kicks in on March 29th. Reference here. Thus the conversion to 2020-01-01T19:20:20Z is correct.
The output of console.log when passed a Date object is implementation specific. Some implementations will emit the output of .toString() (which is in local time in RFC 2822 format), and some will emit the output of .toISOString() (which is in UTC in ISO 8601 extended format). That is why you see the difference.
In general, it is not good to send a local time without also sending a time zone offset. ISO 8601 format is ideal, but you should send either 2020-01-01T19:20:20Z, or 2020-01-01T20:20:20+01:00. Don't just send the date and time without an offset to the client. Otherwise, if your client could be in a different time zone then they would interpret the value incorrectly.
Keep in mind that Date objects are not time zone aware. They contain only a Unix timestamp internally, and they convert only to the system's local time zone for the functions that work in local time. They cannot work in any other time zone.
Relying on the system local time zone is bad for portability. One doesn't always have the ability to change it, and it doesn't do well when you have to work in multiple time zones. It would be better to not rely on setting a local time zone from Node's TZ variable. Instead, consider writing your code to be independent of any local time zone setting.
A time zone aware date library can help with most of your concerns. I can recommend Luxon, js-Joda, Moment + Moment-Timezone, or date-fns + date-fns-timezone.
"how would I do this globally" is something I'm not following in your question. Try the approach I described, and if you still have issues then open a new question. Try to be specific and ask a single question. You're likely to get better results that way. Please read How do I ask a good question? and How to create a Minimal, Complete, and Verifiable example. Thanks.
To solve the issue:
npm i mongoose-timezone
In your schema file:
import timeZone from "mongoose-timezone";
const testSchema = new mongoose.Schema({
myDate: { type: Date, required: true },
}, { timestamps: true });
// mongoose will save the dates based on user's timezone
testSchema.plugin(timeZone)
mongoose-timezone basically adds the current timezone offset to the
date before store and removes the offset when retrieving data. This
way dates are kept proportional in the database and in the app.
I am using flatpickr in order to set a date,
onChange: function(selectedDates, dateStr, instance) {
var myDate = selectedDates[0];
First I am tracing selecteDate[0] and gives me a string
Thu Dec 20 2018 00:00:00 GMT-0500 (GMT-05:00)
Then I am tracing myDate and seems that is been converted to GMT+0000 ISO string.
2018-12-20T05:00:00.000Z
So my question is where does the flatpickr picks the GMT-0500 from?
Is it possible to change it?
Unfortunately, it doesn't seem to be possible to do that (currently).
https://github.com/flatpickr/flatpickr/issues/1532
Apparently, flatpickr uses, by default, the timezone of the computer.