守望者--AIR技术交流

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
热搜: ANE FlasCC 炼金术
查看: 281|回复: 0

[ECMAScript] 夏令时间:可能被你忽略的一个坑

[复制链接]
  • TA的每日心情
    擦汗
    2018-4-10 15:18
  • 签到天数: 447 天

    [LV.9]以坛为家II

    1742

    主题

    2094

    帖子

    13万

    积分

    超级版主

    Rank: 18Rank: 18Rank: 18Rank: 18Rank: 18

    威望
    562
    贡献
    29
    金币
    51783
    钢镚
    1422

    开源英雄守望者

    发表于 2016-8-15 10:10:03 | 显示全部楼层 |阅读模式

    前端的童鞋,请你在你的浏览器的console里执行这么一句: new Date(1987,3,12),然后来看看结果。

    • Chrome: Sun Apr 12 1987 01:00:00 GMT+0900 (CDT)
    • Firefox: Date {Sat Apr 11 1987 23:00:00 GMT+0800 (CST)}

    发现没有,两个不一样?chrome里多了一个小时,Firefox里少了一个小时。什么鬼???

    让咱们先来看看夏令时间是咋回事

    夏时制,夏时令(Daylight Saving Time:DST),又称“日光节约时制”和“夏令时间”,是一种为节约能源而人为规定地方时间的制度,在这一制度实行期间所采用的统一时间称为“夏令时间”。一般在天亮早的夏季人为将时间提前一小时,可以使人早起早睡,减少照明量,以充分利用光照资源,从而节约照明用电。各个采纳夏时制的国家具体规定不同。目前全世界有近110个国家每年要实行夏令时。

    1986年至1991年,中华人民共和国在全国范围实行了六年夏令时,每年从4月中旬的第一个星期日2时整(北京时间)到9月中旬第一个星期日的凌晨2时整(北京夏令时)。除1986年因是实行夏令时的第一年,从5月4日开始到9月14日结束外,其它年份均按规定的时段施行。夏令时实施期间,将时间调快一小时。1992年4月5日后不再实行。

    这么看来,1987-04-12 这一天刚好在中国执行夏令时间的范围内。

    寻根问底

    再在Firefox中执行这么一句:

    new Date(1987,3,11,23,0,0,0).getTime() - new Date(1987,3,12,1,0,0,0).getTime() 结果为-3600000,刚好等于 60 * 60 * 1000,也就是一小时,不应该是相差两小时的么?

    原因是:浏览器的new Date默认会解析出本地时间,而在中国,因为从1987-4-11的一天结束之后,本来应该是1987-4-12日00:00:00的,但是刚好这一天开始夏令时,所以会将时钟拨快一小时,变成1987-04-12 01:00:00

    也就是说,再计算本地时间的时候,1987-04-11 23:00:00 再过3600000毫秒,就变成1987-04-12 01:00:00

    也就是说,1987-4-12 00:00:00在中国的本地时间中是不存在的。

    ECMASCRIPT 规范对于本地时间不存在时的处理

    moment.js 的作者给我这么一句话:

    This is actually standard browser behavior in compliance with the ECMA standard. China did a DST transition at midnight on April 12 1987. This means that the date and time in question - 1987-04-12T00:00.00 - does not exist. Given an ambiguous time, the ECMA standard specifies that the time should be shifted by the amount of the transition, to result in a time that actually exists, but it does not specify in which direction. In this case, Firefox is shifting it back by one hour.

    也就是说,解析本地时间的时候,如果不存在的时间浏览器会给一个模糊的时间,并且带一个便宜,chrome往后调了一小时,Firefox往前调了一小时

    那么问题来了

    在实行夏令时间的阶段,一年中有一小时不存在,而另一个小时会出现两次。

    var date = new Date(1987,3,12,0,0,0);
    date.setHours(0);
    console.log(date)
    

    Firefox回退了一天,chrome前进了一小时。

    实际中遇到的问题

    最头疼的就是日历插件了,现在好多日历插件都是使用本地时间计算的,选择后传给你一个date对象,你根据Date解析成字符串,却发现这一天怎么都选择不了。

    有些日历插件在Firefox(mac)上'1987-04-12'这一天显示不出来。。

    或者给你一个字符串'1987-04-12', 你解析出毫秒传给后台,两个浏览器解析的并不同,莫名其妙少一天。。。

    或者后台没有使用夏令时间,传给你一个时间戳,某些浏览器解析出来后少了一天。。。

    解决

    现在有些日历插件都是使用UTC时间的,所以不会出现这些问题,但是仅限于前后的传值是通过'2013-11-11'这种format格式传,而不是通过时间戳传。


    来源:http://div.io/topic/1775

    守望者AIR技术交流社区(www.airmyth.com)
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    
    关闭

    站长推荐上一条 /4 下一条

    QQ|手机版|Archiver|网站地图|小黑屋|守望者 ( 京ICP备14061876号

    GMT+8, 2019-11-14 05:28 , Processed in 0.045479 second(s), 33 queries .

    守望者AIR

    守望者AIR技术交流社区

    本站成立于 2014年12月31日

    快速回复 返回顶部 返回列表