Home > Net >  Avoid timezone correction for JavaScript Date
Avoid timezone correction for JavaScript Date

Time:04-07

I have a JavaScript function that takes a number (1-31), creates a Date and sends it to a server via an AJAX request:

sendDate(d) {
    let date = new Date(this.year, this.month, d);
    htmx.ajax("GET", "/some/url", { values: { "date": date.toISOString() } });
}

The problem is, that JavaScript is doing some timezone correction which has the effect, that if I create a date like new Date(2022, 09, 14) I get a date Wed Sep 14 2022 00:00:00 GMT 0200 (Central European Summer Time) which when converted to ISO format becomes 2022-09-13T22:00:00.000Z, ie. the previous day.

I know I can use .toLocaleDateString(), but I would like to stick to the ISO-format and I would also like to avoid hacky solutions such as always creating the date with some specified time at the middle of the day or whatever.

Is there a simple way to create a regular date object and pass it on to a server without timezone shenanigans?

CodePudding user response:

Values passed to the Date constructor are treated as local, toISOString uses UTC. Unfortunately ECMAScript doesn't have a timezone–free, date–only form.

If you want to use toISOString to format the timestamp, then one solution is to parse the values as UTC initially, e.g.

sendDate(d) {
    let date = new Date(Date.UTC(this.year, this.month, d));
    htmx.ajax("GET", "/some/url", { values: { "date": date.toISOString() } });
}

Example:

let d = new Date()
let year = d.getFullYear();
let month = d.getMonth()
let day = d.getDate();
let date = new Date(Date.UTC(year, month, day))
// Always shows the current local date as 00:00:00Z
console.log( date.toISOString() );

You should also trim the Z from the end since the timestamp really is local.

CodePudding user response:

There’s a way to do that: store the date as the UNIX timestamp. I do it this way and when it’s needed, I pass the timestamp from server to client and convert it into local date.

That said, I don’t think it’s a good idea to build the date on client and pass it to the server, since it could be modified on client. I believe it’s mostly done this way (and that’s also how it’s done in my projects): on the server side, you check the current timestamp (at the time request is sent) and do with it whatever you want.


It appears that you allow your user to pick a date. It would be a good approach to convert it then to timestamp and pass it to the server.

How would you do that? If I return date.getTime() and then parse it (in python) with datetime.fromtimestamp(int(request.GET['date']) / 1000) I still get the same timezone issue...

You won't have any issues in this case - apart from the fact your server just could happen to have a different local time. A time-zone independent solution would have to use utcfromtimestamp instead of fromtimestamp.

Either way, the timestamp itself can't have any timezone problems by definition.

CodePudding user response:

See RobG's Answer... using the new Date(Date.UTC(year, month, day)) formatting is much better.

  • Related