Z 用来表示传入时间的时区(zone),不指定并且没有使用 T 分隔而是使用空格分隔时,就按本地时区处理。这个说法也不严谨,指定 Z 时表示 UTC 时间,不指定时表示的是本地时间。
> new Date('1970-01-01T00:00:00') Thu Jan 01 1970 00:00:00 GMT+0800 (CST) > new Date('1970-01-01T00:00:00Z') Thu Jan 01 1970 08:00:00 GMT+0800 (CST)
示例 1 是东八区时间,显示的时间和传入的时间一致(因为我本地时区是东八区)。
示例 2 指定了 Z(也就是 UTC 零时区),显示的时间会加上本地时区的偏移(8 小时)。
RFC-2822
RFC-2822 的标准格式大概是这样:Wed Mar 25 2015 09:56:24 GMT+0100。其实就是上面显示时间时使用的形式:
> new Date('Thu Jan 01 1970 00:00:00 GMT+0800 (CST)') Thu Jan 01 1970 00:00:00 GMT+0800 (CST)
除了能表示基本信息,还可以表示星期,但是一点也不容易读,不建议使用。完整的规范可以在这里查看:
时间戳
Date 构造器还可以接受整数,表示想要构造的时间自 UTC 时间 1970-01-01 00:00:00 经过的毫秒数。比如下面的代码:
> new Date(1000 * 1) Thu Jan 01 1970 08:00:01 GMT+0800 (CST)
传人 1 秒,等价于:1970-01-01 00:00:01Z,显示的时间加上了本地时区的偏移(8 小时)。
多参数
最后,Date 构造器还支持传递多个参数,这种方法就没办法指定时区了,都当做本地时间处理。比如下面的代码:
> new Date(1970, 0, 1, 0, 0, 0) Thu Jan 01 1970 00:00:00 GMT+0800 (CST)
显示时间和传入时间一致,均是本地时间。注意:月份是从 0 开始的。
Date.parse
Date.parse 接受一个时间字符串,如果字符串能正确解析就返回自 UTC 时间 1970-01-01 00:00:00 经过的毫秒数,否则返回 NaN:
> Date.parse('1970-01-01 00:00:00') -28800000 > new Date(Date.parse('1970-01-01 00:00:00')) Thu Jan 01 1970 00:00:00 GMT+0800 (CST) > Date.parse('1970-01-01T00:00:00') 0 > new Date(Date.parse('1970-01-01T00:00:00')) Thu Jan 01 1970 08:00:00 GMT+0800 (CST)
示例 1,-28800000 换算后刚好是 8 小时表示的毫秒数,28800000 / (1000 * 60 * 60),我们传入的是本地时区时间,等于 UTC 时间的 1969-12-31 16:00:00,和 UTC 时间 1970-01-01 00:00:00 相差刚好 -8 小时。
示例 2,将 parse 后的毫秒数传递给构造器,最后显示的时间加上了本地时区的偏移(8 小时),所以结果刚好是 1970-01-01 00:00:00。
示例 3,传入的是 UTC 时区时间,所以结果为 0。
示例 4,将 parse 后的毫秒数传递给构造器,最后显示的时间加上了本地时区的偏移(8 小时),所以结果刚好是 1970-01-01 08:00:00。
Date.UTC
Date.UTC 接受的参数和 Date 构造器多参数形式一样,然后返回时间自 UTC 时间 1970-01-01 00:00:00 经过的毫秒数:
> Date.UTC(1970,0,1,0,0,0) 0 > Date.parse('1970-01-01T00:00:00') 0 > Date.parse('1970-01-01 00:00:00Z') 0
可以看出,Date.UTC 进行的是一种“绝对运算”,传入的时间就是 UTC 时间,不会转换为当地时间。
Date.now
Date.now 返回当前时间距 UTC 时间 1970-01-01 00:00:00 经过的毫秒数:
> Date.now() 1452520484343 > new Date(Date.now()) Mon Jan 11 2016 21:54:55 GMT+0800 (CST) > new Date() Mon Jan 11 2016 21:55:00 GMT+0800 (CST)
MySQL 中的“时间”
MySQL 中和时间相关的数据类型主要包括:YEAR、TIME、DATE、DATETIME、TIMESTAMP。
DATE、YEAR、TIME 比较简单,大概总结如下:
名称
占用字节
取值
DATE
3 字节
1000-01-01 ~ 9999-12-31
YEAR
1 字节
1901 ~ 2155
TIME
3 字节
-838:59:59 ~ 838:59:59
注:TIME 的小时范围可以这么大(超过 24 小时),是因为它还可以用来表示两个时间点之差。
DATEIME vs TIMESTAMP
我们主要来说明下 DATETIME 和 TIMESTAMP,可以做下面的总结:
名称
占用字节
取值
受 time_zone 设置影响
DATETIME
8 字节
1000-01-01 00:00:00 ~ 9999-12-31 23:59:59
否
TIMESTAMP
4 字节
1970-01-01 00:00:00 ~ 2038-01-19 03:14:07
是
第一个区别是占用字节不同,导致能表示的时间范围也不一样。