Avoid timezone correction for JavaScript Date

Viewed 198

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?

3 Answers

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.

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.

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

Related