一直以来以为中国是没有夏令时的概念的,直到上次项目中碰到一个问题。

问题是这样的,客户在管理后台录入一个人员的生日是1989-05-23可是到ios上发现日期是1989-05-22。因为前后端使用的时间戳来传递时间的,在ios上格式化为YYYY-MM-DD HH:mm:ss之后打印发现是1989-05-22 23:00:00。而在android和chrome上打印的都是1989-05-23 00:00:00。足足少了一个小时。

在中国的话一般时间上少8小时,那么可能是国际标准时间和北京时间的时差导致的,一个小时倒是很少见。不过之前做过一个国际的项目,针对欧美那边的用户有个叫夏令时冬令时的差别,这个恰好是有一小时的前后调整。会不会是夏令时导致的呢?

于是在chrome和safari上试了一下:

// chrome
new Date(1989, 4, 23) // Tue May 23 1989 00:00:00 GMT+0900 (中国夏令时间)
 
// safari
new Date(1989, 4, 23) // Tue May 23 1989 00:00:00 GMT+0800 (CST) = $6

我们可以看到chrome自动针对当地时区做了夏令时转换,后面的时区是GMT+0900,而safari是GMT+0800。

查了一下,原来中国在86年-92年实行了一段时间的夏令时:
1986年4月,中国中央有关部门发出“在全国范围内实行夏时制的通知”,具体作法是:每年从四月中旬第一个星期日的凌晨2时整(北京时间),将时钟拨快一小时,即将表针由2时拨至3时,夏令时开始;到九月中旬第一个星期日的凌晨2时整(北京夏令时),再将时钟拨回一小时,即将表针由2时拨至1时,夏令时结束。从1986年到1991年的六个年度,除1986年因是实行夏时制的第一年,从5月4日开始到9月14日结束外,其它年份均按规定的时段施行。在夏令时开始和结束前几天,新闻媒体均刊登有关部门的通告。1992年起,夏令时暂停实行。
因此在chrome中转换为时间戳的时候,本身就少了一个小时的时间。

// chrome
new Date(1989, 4, 23).getTime() // 611852400000
 
// safari
new Date(611852400000) // Mon May 22 1989 23:00:00 GMT+0800 (CST) = $7

在每年夏令时,结束时,这两个时间戳是一样的

new Date("1987-09-06 02:00:00").getTime()
557859600000
new Date("1987-09-06 01:00:00").getTime()
557856000000

这时候我们在消费这个时间戳的时候就不好判断原有的时间是什么了。仅仅针对生日这种特殊情况来处理的话,因为上传的时间肯定是某日的零点的时间,因此,检测是23点的时候,我们可以加一个小时,但是除了这种特殊情况我们就不好处理了。

想要根治这种问题,我们就需要在生产这个时间戳的时候就要针对夏令时做处理。比如说检测new Date().toString()中是否包含夏令时或者+0900这样的字符串。如果有则说明进行了夏令时转换。这时候我们的时间戳就需要在原有的基础上加上1h的时间。或者使用momentjs的检测是否进行夏令时转换函数判断也可以。

标签: none

添加新评论