备忘。这业务中涉及到需要计算世界时间时,往往会因为时区的关系而有点晕头转向。这里就简单的介绍一下几个关于时间的概念和在前端中与之相关的方法。

##UTC,GMT和CST是什么关系?

  • 先来说下GMT是什么。是格林威治(在英国)平均时间。
  • UTC,几乎可以等同于GMT,只是比GMT更严格。
  • 时区。全球24个时区,把以伦敦为中心的世界地图展开,UTC和GMT的伦敦是0区,伦敦的右边直到新西兰的东部不远的斐济为东区,而左边到太平洋中间为西区。一般用5位时区差来表示与UTC相差的小时数,东区为正,西区为负。如北京时区是东八区,领先UTC八个小时,记为+0800;纽约的时区是西五区,比UTC落后五个小时,记为 -0500。UTC + 时区差 = 本地时间

  • CST,可以同时表示美国,澳大利亚,中国,古巴四个国家的标准时间:

    • Central Standard Time (USA) UT-6:00
    • Central Standard Time (Australia) UT+9:30
    • China Standard Time UT+8:00
    • Cuba Standard Time UT-4:00

前端中与时间相关的方法

需要注意的是:
在前端中,无论是php还是js中,有格式显示出来的时间,都是与本地相关,即与本地系统设置(或系统默认)的时区相关。
如果对方法进行不带时区传参,那就是取的默认。

php中:

  • time(),从 Unix 纪元(January 1 1970 00:00:00 GMT)到当前时间的。比如如果系统时间分别设置为Thu Mar 12 2015 07:52:53 GMT+0800 (China Standard Time)Wed Mar 11 2015 20:52:53 GMT-0300 (Local Standard Time),通过time()获取到的值是相同的。
  • date_default_timezone_set()设置时区。之后date()格式化之后的时间都是根据设置的时区来显示。

JS中:

  • new Date(timestamp),相同的timestamp,在不同时区,new Date()之后的值不同(也就是显示,与本地相关)。但是,如果不带时区直接进行设置,new Date(‘Thu Mar 12 2015 07:52:53’),如果是在GMT+0800就是相对于GMT+0800将时间设置为Thu Mar 12 2015 07:52:53,如果是在GMT-0300,就是相对于
    GMT-0300将时间设置为Thu Mar 12 2015 07:52:53。设置之后再次分别获取它们的时间戳,getTime()是不同的,因为相同时间,不同时区,相对于格林威治时间的差值不同。
  • getTime(),是获取距1970 年 1 月 1 日之间的毫秒数
  • getTimezoneOffset(),获取格林威治时间与本地时间之间的时差,分钟数UTC时间 + 时区差 = 本地时间。<0,表示早于UTC时间。比如:
1
2
3
4
5
6
7
北京所在的东八区时区差记为+0800,纽约所在的西五区时区差记为-0500
假设现在是北京时间2015312日,12:35,那么UTC时间和纽约时间可以分别计算为:
(1) UTC时间 + 时区差(北京) = 本地时间(北京) => UTC时间 = 1235 - (+0800) = 0435,就是2015312日,凌晨4:35
(2) UTC时间 + 时区差(纽约) = 本地时间(纽约) => 本地时间(纽约) = 本地时间(北京) - 时区差(北京) + 时区差(纽约) = 1235 - (+0800) + (-0500) = -0065
(3) **如果出现负数,说明提前一天,需要加上2400**。本地时间(纽约) = -0065 + 2400 = 2335,说明是2015311日,23:35
注,如果地区又使用夏时令时间,又还会做相应的加减。
  • Date.UTC函数采用UTC,返回指定的时间距GMT时间1970年1月1日午夜的毫秒数;而Date对象构造函数采用当地时间。

业务中的应用场景

正确显示世界各地时间。显然,正常的逻辑是,无论我们是在北京还是在纽约搜索伦敦时间的时候都应该显示的是伦敦当地的时间,而与用户所在地区的时区无关。
之前用了new Date()和绝对的时间戳,导致在不同时区,用户搜到的城市时间不同。业务逻辑如下图:

图2:(其实看到的也是假象)

图3:(带时区进行时间设置)

##参考的文章