避免对JavaScript日期进行时区校正



我有一个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 (Central European Summer Time),当转换为ISO格式时,它会变成2022-09-13T22:00:00.000Z,即前一天。

我知道我可以使用.toLocaleDateString(),但我想坚持ISO格式,我也希望避免一些棘手的解决方案,比如总是在中午创建指定时间的日期或其他什么。

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

传递给Date构造函数的值被视为本地值,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,因为时间戳实际上是本地的。

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

也就是说,我认为在客户端上构建日期并将其传递给服务器不是一个好主意,因为它可以在客户端上修改。我相信它主要是这样做的(在我的项目中也是这样做的(:在服务器端,你检查当前的时间戳(在发送请求时(,然后随心所欲地使用它。


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

你会怎么做?如果我返回date.getTime(),然后用datetime.fromtimestamp(int(request.GET['date']) / 1000)解析它(在python中(,我仍然会得到相同的时区问题。。。

在这种情况下,您不会有任何问题,除了您的服务器可能碰巧有不同的本地时间。与时区无关的解决方案必须使用utcfromtimestamp而不是fromtimestamp

无论哪种方式,时间戳本身都不会有任何时区问题。

请参阅RobG的答案。。。使用CCD_ 11格式要好得多。

最新更新