DateAPI大家肯定都有用过,虽然更多时候关于日期的处理都交给了dayjs或者moment。
但我们肯定免不了去直接使用原生API,这时候你可能会免不了爆一句粗口「什么阴间玩意?」,接下来我们来看看到底这个API不好用到哪里去。
首先我们先了解下Date支持哪些类型的传参:
newDate();newDate(value);newDate(dateString);newDate(year,monthIndex[,day[,hours[,minutes[,seconds[,milliseconds]]]]]);
了解完参数类型,就直接用起来咯:
截屏-07-28下午10.07.36没啥毛病,符合预期,不传参就获取当前系统时间。
那么我们换种写法,传入字符串呢?
截屏-07-28下午10.10.36小小的脑袋充满了问号,明明我传入同样的日期,无非格式变了一下,为啥输出的内容却完全不一样?
笔者这里解释下,当我们输入第一种格式时,内部会帮我们解析成当前时区所对应的协调世界时(UTC),也就是零点加八小时。
而当我们输入第二种格式时,内部会帮我们解析成当前时区的零点。
到这里其实笔者已经有点懵逼了,不踩过这种坑鬼知道会有这样的不同。
你以为这样就结束了?天真了,我们再来看这种写法:
截屏-07-28下午10.24.46好家伙,我这传的明明是七月份,咋的给我解析成八月份了???
这看起来是个Bug,实际上算是一个老传统,在很久之前的编程语言里确实以0开头作为某些时间的起始位:
截屏-07-28下午10.29.50以上内容大家可以在Linux[1]的文档中阅读到。
文章到这里还没有结束,咱们再来换个写法看看:
截屏-07-28下午9.56.32这第一个写法笔者还能理解一点,毕竟年份从年开始计数,但是为啥换成数组的写法你就给我变成了年啊!
img笔者这里也就不考古了,反正打死不这样写就行了。
那么多坑,心累了,以后就只用newDate()吧,但其实也不好意思,单用这个你说不定也能踩到一个坑。
举个场景,我们在服务端给接口setCookie的时候都会设置一个expires字段代表这个Cookie的有效时间,此时如果你的expires字段是以newDate()生成的话,千万记得要做一次转换。
比如说我们利用newDate()获取了一个时间,大家可以看到输出是带有中文的:
截屏-07-28下午10.07.36此时如果你把这个时间去做setCookie的话,服务端就会报一个TypeError的错误:invalidcharacterinheadercontent["set-cookie"],这是因为我们设置的值里存在中文。
因此我们需要对这个时间做一次转换得到一个不包含中文的时间字符串。
讲了那么多,难道原生API真的没救了?只能全用库了么?这倒也不是,TS39也知道如此阴间的API不好用,因此搞了proposal-temporal[2]这个提案来解决问题,算是融合了目前日期处理库的功能。
但是等这个提案兼容大部分浏览器也不知道什么时候呢,还是继续dayjs吧。
引用链接[1]Linux: