JavaScript为我们供应了不是很好用的Date作为时候日期对象,除了接口设想奇异以外,另有一些隐蔽很深的bug,先看接口设想:
- Date()直接返回当前时候字符串,无参数。
- new Date()则是会依据参数来返回对应的时候对象,参数很有意义:
// 无参数,并返回当前时候。
new Date();
// 可接收一个数字参数,该参数示意与1970年1月1日0点之间的毫秒数。
new Date(value);
// 可接收一个字符串参数,参数情势相似于Date.parse()要领。
new Date(dateString);
// 可接收年月日时分秒参数,是当地时候。
new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);
先且不说如许的接口难免不够天真(很难处置惩罚种种字符串花样的时候),最诡异的一点是个中运用dateString的谁人组织要领,MDN网站在这个函数下有下面一段解释:
注重这里用的是strongly discouraged
– 猛烈不引荐运用,原本的我没有注重这句话,直到。。。支付凄惨的价值。
征象
我的一款逐日打卡类的App,由于有大批的时候运算,为了能接收种种时候,我做了一个轻易的函数:
date2ymd(input) {
let day = (input instanceof Date) ? input : new Date(input)
return `${day.getFullYear()}-${day.getMonth() + 1}-${day.getDate()}`
}
上面的函数在某些input时没有题目,但当参数为相似’2018-10-1’这类花样,根据MDN的文档,就属于猛烈不引荐运用的情势,但我没有注意,App宣布以后,不错,大部分用户没有反应题目,直到某天,一个阿根廷的用户给我邮件反应,说界面上的日历好像紊乱了,我试着变动本身的时区到对应的-3时区,截图一看:
上图中彩色小方块的地区是年视图,原本应当和下面的日历一一对应,但在这个时区下,年视图完整错位了,肯定是那里计算错误了,经由调试,我找到了上面这个函数,并发现了题目,我们用chrome的console演示一下:
看到了吗? 从9号到10号,转换出的时候没有翻天,固然,我们可认为这类转换找到来由,JS应当是把这类参数当做UTC时候了,我们看看firefox:
Firefox的表现能够明白,由于UTC和-3:00时区之间有个时候差,虽然这依旧不是我想要的,但比起chrome的跳变要好接收一些,我们把输入时候换一个花样,再看下在chrome下的例子:
这类花样终究相符了一般逻辑,也就是短杠和斜杠分开的时候处置惩罚上是不一致的,斜杠分开的时候终究准确的根据了当地时候举行处置惩罚。
结论
正如MDN所说,不要运用单字符串参数的Date组织函数,纵然你晓得种种花样之间的区分,也不发起运用,毕竟影象这些玄妙,甚至不兼容的差异毫无意义。