本身觉得Date对象只会在获取时间时会用到,但是在排查项目bug时发现date的一些隐患,所以就去详细的了解了Date对象。
通过new Date()创建出来的对象可能并不是你说期望的,看一下例子:
let date1 = new Date('2021-12-26')
let date2 = new Date('2021-12-26 00:00:00')
console.log({
date1: date1.toString(),
date2: date2.toString()
});
<!--
date1: "Sun Dec 26 2021 08:00:00 GMT+0800 (中国标准时间)"
date2: "Sun Dec 26 2021 00:00:00 GMT+0800 (中国标准时间)"
-->
通过对比,可以发现,只有let date2 = new Date('2021-12-26 00:00:00')这行代码声明的date2是我们所期望的时间2021年12月26日 0时0分0秒(午夜),而date1输出的却是2021年12月26日 8时0分0秒。
"Sun Dec 26 2021 08:00:00 GMT+0800 (中国标准时间)"。解释一下date.toString()解析的这个字符串代表什么含义:
- Sun:星期
- Dec 26 2021:日期
- 08:00:00:时间,24小时制
- GMT:格林威治时间
- +0800:偏移量,比UTC(世界协调时间,常表示0点)提前8小时
- (中国标准时间):中国标准时间(与偏移量有关)
重点关注的是后三部分 ,时差。
new Date()在生成时间的时候,是参考当地时间和UTC时间的时差。结合代码进行解释这句话。
new Date('2021-12-26')生成的时间确实是2021年12月26日0时0分0秒,但是这个时间是UTC的时间,简单的说就是这个时间是伦敦的时间;对应的北京时间是2021年12月26日 8时0分0秒。
再看代码:
let date3 = new Date('2021-12-26 00:00:00')
let date4 = new Date('2021-12-26')
console.log({
date3: date3.toString(),
date4: date4.toString()
});
<--
date3: "Sun Dec 26 2021 00:00:00 GMT+0800 (中国标准时间)"
date4: "Sun Dec 26 2021 08:00:00 GMT+0800 (中国标准时间)"
-->
可以看到date3指定了时分秒,也就是指定偏移量(即,本地时间);date4则是默认使用了UTC对应的本地时间。
再次解释一下UTC对应的本地时间,UTC指的本地时间是相较于伦敦0时的时间,所以相较于伦敦现在的北京时间是08:00:00。
重点偏移量:
在整个的研究过程中,偏移量带来了巨大的作用。我们所获取的时间是UTC的时间,但是如果我们指定了偏移量就可以获取到正确的本地时间。
应用场景:
当进行两个日期的时间戳相减计算差值时,如果其中有变量使用了 new Date('2021-12-26') 这种写法,就会产生 N 个小时的正负误差,如果参与操作的两个变量都是相同的处理方式,误差刚好抵消,虽然结果正确,但是错误就被掩盖了。
比如 element-UI 中的日期控件,有个一 value-format 属性(Attribute),当设置 value-format = 'yyyy-MM-dd' 时,用户操作选择日期后,获取到的日期为字符串形式,比如 '2021-12-26',这个值参与后续逻辑时,如果使用了 (new Date('2021-12-26')).getTime() 获取时间戳时,无论存储还是参与计算,误差就被悄悄地引入了,功能不出错只是碰巧误差被消除,但是隐患就被埋下了。
举一个例子:
如果场景中涉及到过期时间,过期时间是通过new Date("2021-12-26")设置,那么就会出现隐患。

本文揭示了Date对象在newDate('2021-12-26')中的时区误区,指出UTC与本地时间差异可能导致的计算误差,并强调在处理日期时间时注意偏移量和正确的时间格式转换

被折叠的 条评论
为什么被折叠?



