起因
最近在写一个页面,需要用到时间控制。然后我通过new Date()
传入日期字符串创建了一个对象,并与当前时间做时间戳比较,结果12点刚过,就出问题了。举个栗子:
// 假设当前时间是2019年12月22日0点20分
new Date('2019-12-22').getTime() < new Date().getTime()
// 上面的结果是什么?正常来说应该是true吧,但不好意思啊,返回了false
百思不得其解,当时因为情况紧急,查出了上面的创建时间返回的内容并不是0点,而是8点
所以就强行在时间字符串上拼接了时间:new Date('2019-12-22 00:00:00').getTime()
, 强行解决了这个问题。
然后又碰到了在IOS上不识别中横线分割的时间字符串问题,讲中横线转成了反斜杠。
当时临时解决问题后的字符串大概长这样:
new Date('2019/12/22 00:00:00').getTime() < new Date().getTime()
临时解决问题。现在闲来无事,可以看看这个问题究竟是什么鬼?
尝试
传入不同的字符串格式,看看结果,我只尝试了最常使用的两种格式
惊讶的发现,-
分割的字符串,被默认解析到了8点,而/
分割的字符串,默认解析到了0点。这么说来,我之前有点多次一举了,直接讲-
替换成/
就可以了啊。
探究
那么为什么默认是8点呢?有没有觉得8这个数字很值得关注,我们所在的时区是东八区,如果以GMT标准0点来算的话,在那个时间点,这里就是8点啊。
那我就可以这样理解了,创建时间时,它默认时间确实是0点,但是是以GMT为基准的,所以将其转换成本地时间就是8点。而/
分割的字符串在创建时,则是以本地时区为基准。
那么为什么js会对不同分割的时间字符串进行不同处理呢?貌似是因为-
分隔且具有前导0的日期字符串,会被解析成ISO格式的字符串,以GMT时区为基准,不过我也没看懂。
解决
最终,既然-
分割的字符串会出问题,那我就讲所有的-
都换成/
就好了,正好也可以借此解决IOS的兼容问题。动手解决:
/*** 将时间字符串转换成date对象* @param dateStr* 时间字符串*/
function getDate(dateStr){/* 若日期是使用-分割的,全部转换成/因为只有日期时,js会将-分割的字符串基准时区设置为GMT,与当前时区相差8小时 */dateStr = dateStr.replace(/-/g, '/');return new Date(dateStr);
}