JavaScript中的Date对象,以及UTC、GMT、时区的关系

前言

最近在写一个功能的时候,需要把本地时间0点的时间戳存下来。因为一直就没怎么去研究UTC、GMT、本地时间(中国算是东八区)的关系,所以乘着要写这个功能,就把这几个概念理了一下。

UTC与GMT的关系

UTC和GMT实际上可以理解为同一东西,具体的关系如下。

1
UTC = GMT +/- 0.9 s

我们国家的时间实际是UTC+8,也就是说当国际标准时间为1号早上8点的时候,我们的本地时间是1号的16点。
即:东八区比标准时间快8小时。

JS中Date对象主要方法所用的参数,以及返回类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// 该方法传递的是国际标准时间
now = new Date(int)
// 该方法返回的也是国际标准时间戳
getTime() 返回 国际时间 1970110点至今的毫秒数。(也就是我们东八区的1970118点至今的毫秒数)
// 以下方法返回的是本地时间
getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31)。本地时间
getDay() 从 Date 对象返回一周中的某一天 (0 ~ 6)。本地时间
getMonth() 从 Date 对象返回月份 (0 ~ 11)。本地时间
getFullYear() 从 Date 对象以四位数字返回年份。本地时间
getYear() 请使用 getFullYear() 方法代替。本地时间
getHours() 返回 Date 对象的小时 (0 ~ 23)。本地时间
getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。本地时间
getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。本地时间
getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。本地时间
// 以下方法返回的是国际标准时间
getUTCDate() 根据世界时从 Date 对象返回月中的一天 (1 ~ 31)。国际标准时间
getUTCDay() 根据世界时从 Date 对象返回周中的一天 (0 ~ 6)。国际标准时间
getUTCMonth() 根据世界时从 Date 对象返回月份 (0 ~ 11)。国际标准时间
getUTCFullYear() 根据世界时从 Date 对象返回四位数的年份。国际标准时间
getUTCHours() 根据世界时返回 Date 对象的小时 (0 ~ 23)。国际标准时间
getUTCMinutes() 根据世界时返回 Date 对象的分钟 (0 ~ 59)。国际标准时间
getUTCSeconds() 根据世界时返回 Date 对象的秒钟 (0 ~ 59)。国际标准时间
getUTCMilliseconds() 根据世界时返回 Date 对象的毫秒(0 ~ 999)。国际标准时间
// 以下两个方法返回本地时间的字符串
toLocaleString()
toString()
// 返回国际标准时间的字符串
toUTCString()

从上面的api中可以看到Date中的,getTime方比较特殊,它虽然没有加UTC这个标识,但是实际上返回的却是UTC的时间戳,估计主要是为了和构造方法对应起来。

小结

理清这些概念之后,实现起来就比较清晰了。最后附上获取本地当天0点时间的国际标准时间戳(有点绕口…)

1
2
3
4
exports.getZeroTime =()->
now = new Date()
now.setHours(0);now.setMinutes(0); now.setSeconds(0); now.setMilliseconds(0);
return now.getTime()

更进一步

在本文开头提到了需要把本地时间0点的时间戳存下来。那么如果现在要做一个功能,是记录全球所有用户每天的体温变化。那么是存各地区本地的0点时间的时间戳方便,还是存国际标准0点时间的时间戳方便呢?
(存数据库里面的时间戳都是国际时间 1970 年 1 月 1 日 0点至今的毫秒数)。
以下内容没有具体实验,纯理论分析,如果有问题,请给我留言;-)

如果存本地0点时间

因为存的是本地时间,所以每个地区的时间数据都是不统一的。以本地时间10月24号为例,西时区:存的就是10月24号国际标准时间戳+0~12小时;东时区存的就是10月24号国际标准时间戳-(0~12)小时,也就是10月23号的国际标准时间戳+(12~24)小时。

  1. 查询全球所有用户国际标准时间(比如说是10月24号)的数据
    查询条件为10月24号0点国际标准时间+/-12小时内。 其中西时区为+0~12,东时区为-12~0
  2. 查询全球所有用户本地时间(比如说是10月24号)的数据
    查询条件为10月24号0点国际标准时间+24小时内。其中西时区为+0~12,东时区为12~24

如果存国际标准0点时间

以本地时间10月24号为例,不管是西时区还是东时区存的都是10月24号国际标准时间戳。

  1. 查询全球所有用户国际标准时间(比如说是10月24号)的数据
    直接查就是了,没有什么问题
  2. 查询全球所有用户本地时间(比如说是10月24号)的数据
    查询条件为10月24号0点国际标准时间+/-12小时内。 其中西时区为+0~12,东时区为-12~0

最后结合项目的实际需求,就可以选择最合适的存储格式了。


更新2016-4-10
最近很火的手游《皇室战争》,采用的就是国际标准0点时间作为一天的开始。
具体表现为:中国区部落的捐赠数量会在每个星期一的早上8点清零!

转载本站文章请注明作者(xtutu)和出处 xtutu.me