繁体   English   中英

Javascript 夏令时日期计算错误

[英]Javascript date calculation wrong on the daylight saving date

我在连续三个日期在 JavaScript 中进行以下相同的计算。

结果日期与墨尔本“夏令时”生效之日(2019-10-06)不同。 第一个和第三个正确显示日期,第二个显示日期为 10 月 5 日。

有人可以说明哪里出错了。

 var apiRes = "2019-10-05"; var tempDate = Date.parse(apiRes); var dApiRes = new Date(apiRes); console.log(dApiRes.getTimezoneOffset()); tempDate = tempDate + (dApiRes.getTimezoneOffset() * 60000); var d = new Date(0) d.setUTCMilliseconds(tempDate); console.log(d); var apiRes = "2019-10-06"; var tempDate = Date.parse(apiRes); var dApiRes = new Date(apiRes); console.log(dApiRes.getTimezoneOffset()); tempDate = tempDate + (dApiRes.getTimezoneOffset() * 60000); var d = new Date(0) d.setUTCMilliseconds(tempDate); console.log(d); var apiRes = "2019-10-07"; var tempDate = Date.parse(apiRes); var dApiRes = new Date(apiRes); console.log(dApiRes.getTimezoneOffset()); tempDate = tempDate + (dApiRes.getTimezoneOffset() * 60000); var d = new Date(0) d.setUTCMilliseconds(tempDate); console.log(d);

我通常使用中午 12 点来确保不会遇到这种情况 - 也许我们需要 15:00 来确保

 var apiRes = "2019-10-05 15:00:00"; var tempDate = Date.parse(apiRes); var dApiRes = new Date(apiRes); console.log(dApiRes.getTimezoneOffset()); tempDate = tempDate + (dApiRes.getTimezoneOffset() * 60000); var d = new Date(0) d.setUTCMilliseconds(tempDate); console.log(d.toString()); var apiRes = "2019-10-06 15:00:00"; var tempDate = Date.parse(apiRes); var dApiRes = new Date(apiRes); console.log(dApiRes.getTimezoneOffset()); tempDate = tempDate + (dApiRes.getTimezoneOffset() * 60000); var d = new Date(0) d.setUTCMilliseconds(tempDate); console.log(d.toString()); var apiRes = "2019-10-07 15:00:00"; var tempDate = Date.parse(apiRes); var dApiRes = new Date(apiRes); console.log(dApiRes.getTimezoneOffset()); tempDate = tempDate + (dApiRes.getTimezoneOffset() * 60000); var d = new Date(0) d.setUTCMilliseconds(tempDate); console.log(d.toString()); var apiRes = "2019-10-27 15:00:00"; // EU DST ends var tempDate = Date.parse(apiRes); var dApiRes = new Date(apiRes); console.log(dApiRes.getTimezoneOffset()); tempDate = tempDate + (dApiRes.getTimezoneOffset() * 60000); var d = new Date(0) d.setUTCMilliseconds(tempDate); console.log(d.toString());

为了解释这个问题:日期“2019-10-06”是2019-10-06:T00:00:00Z - 这是2019-10-06:11:00:00UTC+11 ,因为到时间2019-10-06:T00:00:00Z到了,夏令时开始了。

因此,当您“考虑”时区时,您减去 11 小时,而不是 10

但是由于墨尔本的上午 11 点,一天只有 10 个小时,因此您的调整日期变为2019-10-05:23:00:00UTC+10

如果您的目标是仅使用 YYYY-MM-DD 字符串获得午夜,那么您可以通过多种方式来实现。

在 UTC 和 UTC 东部时区中,只需

d.setHours(0,0);

(对于像阿德莱德这样的奇数时区,您需要第二个 0)

在 UTC 以西的时区,您需要

d.setDate(d.getDate() + 1)

您还可以在应用更改之前和之后检查 timezoneoffset,并进行相应调整 - 我没有打扰编码

但是,我认为最简单、最可靠的方法,并且只使用 Date 构造函数中指定的方法(即“保证”跨环境工作),如下

它看起来有点时髦,但根本不需要了解本地时区偏移量

 var apiRes = "2019-10-05"; var d = new Date(...apiRes.split('-').map((n, i) => Number(n) - (i %2))); console.log(d.toString()); var apiRes = "2019-10-06"; var d = new Date(...apiRes.split('-').map((n, i) => Number(n) - (i %2))); console.log(d.toString()); var apiRes = "2019-10-07"; var d = new Date(...apiRes.split('-').map((n, i) => Number(n) - (i %2))); console.log(d.toString());

解释...apiRes.split('-').map((n, i) => Number(n) - (i %2))

apiRes.split('-') // results in ["2019", "10", "06"]

所以现在我们有...["2019", "10", "06"].map((n, i) => Number(n) - (i %2))

下一步

.map(n, i) => Number(n) - (i %2))

将每个元素转换为数字并在索引为 1 时减 1,即每月减 1,因为它在构造函数中为零

现在我们有:

new Date(...[2019, 9, 6])

在 ES6+ 中就像

new Date(2019, 9, 6)

它将在给定的 y/m/d 的午夜构造一个 Date

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM