避免使用JavaScript日期的时区更正

发布于 01-19 14:32 字数 629 浏览 1 评论 0原文

我有一个 JavaScript 函数,它接受一个数字 (1-31),创建一个 Date 并通过 AJAX 请求将其发送到服务器:

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

问题是,JavaScript 是进行一些时区校正,如果我创建一个像 new Date(2022, 09, 14) 这样的日期,我会得到一个日期 Wed Sep 14 2022 00:00:00 GMT+0200(中欧夏令时间) 转换为 ISO 格式后变为 2022-09-13T22:00:00.000Z,即。前一天。

我知道我可以使用 .toLocaleDateString(),但我想坚持使用 ISO 格式,并且我还想避免一些老套的解决方案,例如始终在中间创建带有指定时间的日期当天或其他什么。

有没有一种简单的方法来创建常规日期对象并将其传递到服务器而无需时区恶作剧?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

中二柚 2025-01-26 14:32:46

传递给日期构造函数的值将其视为局部, toisostring 使用UTC。不幸的是,eCmascript没有时区 - 不含日期的形式。

如果要使用 toisostring 格式化时间戳,那么一个解决方案是将值分析为UTC,例如

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

:示例:

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() );

您还应该从末端修剪Z,因为时间戳确实是本地的。

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.

回梦 2025-01-26 14:32:46

有一种方法:将日期存储为UNIX时间戳。我这样做,当需要时,我将时间戳从服务器传递给客户端,然后将其转换为本地日期。

也就是说,我认为在客户端上建立日期并将其传递给服务器不是一个好主意,因为可以在客户端上修改它。我相信它主要是这样完成的(这也是我的项目中完成的):在服务器端,您检查当前的时间戳(在时间请求时)并随心所欲地进行操作。


看来您允许用户选择一个日期。将其转换为时间戳并将其传递给服务器将是一种很好的方法。

您将如何做?如果我返回date.getTime(),然后用dateTime.fromtimestamp(int(request.get ['date'])/1000) I仍然有相同的时区问题...

在这种情况下,您将不会有任何问题 - 除了您的服务器可能恰好有不同的当地时间。一个时区独立解决方案必须使用utcfromtimestamp而不是fromTimestamp

无论哪种方式,时间戳本身都不能有任何时区问题根据定义

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.

鹿! 2025-01-26 14:32:46

请参阅Robg的答案...使用新日期(Date.utc(年,月,日))格式化要好得多。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文