几个日期时间相关的概念

1. 时间戳

时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。

也就是说,时间戳它是一个偏移量,比如时间戳 1551618793,就是指距离 1970-01-01 00:00:00 这个基准时间 1551618793 秒的时间,就是格林威治时间 2019-03-03T13:13:13+00:00(这个时间表示法见下面的 ISO 8601 介绍)。

2. 格林尼治标准时间

格林尼治标准时间(Greenwich Mean Time,GMT)是指位于伦敦郊区的皇家格林尼治天文台的标准时间,因为本初子午线被定义在通过那里的经线。理论上来说,格林尼治标准时间的正午是指当太阳横穿格林尼治子午线时的时间。

同时格林尼治标准时间也是世界基准时间,全世界被划分为24个时区,以尼治标准时间为0时区,其他时区在此时间上加上时区偏移量,比如我们中国北京时间就是+8区,格林威治时间 2019-03-03T13:13:13+00:00,就是北京时间的 2019-03-03T21:13:13+08:00。

3. UTC

协调世界时,又称世界统一时间、世界标准时间、国际协调时间。由于英文(CUT)和法文(TUC)的缩写不同,作为妥协,简称UTC。

UTC时间是基于标准的GMT提供的准确时间,因此我们所说的UTC时间,也就是0时区的时间。

4. ISO 8601

ISO 8601 是国际标准化组织,对于日期和时间的一种标准表示方法。

如我们所说的 2019-03-03 21:13:13 这个日期时间上并没有包含时区信息,在国际化上使用,显然这么表示是无法满足要求的,因此就有了 ISO 8601 日期时间表示法。

如北京时间 2019-03-03 21:13:13,ISO 8601 表示法为:2019-03-03T21:13:13+08:00,转换为UTC时间就是 2019-03-03T13:13:13+00:00(或 2019-03-03T13:13:13Z,+00:00 可以用一个字母 Z 表示)。

MySQL 存储日期时间一般常用几个类型

1. INT 或 BIGINT

INT 可以存储秒级时间戳(10位整数),BIGINT 可以存储毫秒级时间戳(13位整数)。

注意点:

使用时,必须将日期时间转换为时间戳整数,再存储,必须调用方约定系统使用时区。

特点:

1. 时间戳没有时区信息,必须系统自己约定使用什么时区的时间戳2. 只能表示 1970-01-01 开始的时间3. 不能使用 MySQL 提供的各种日期时间类函数4. 检索方便

2. DATETIME

DATETIME 使用8字节存储,因此能表示的时间范围比较大,可表示 1000-01-01 00:00:00 到 9999-12-31 23:59:59 范围的时间。

注意点:

DATETIME 类型不关心时区,完全由调用的系统自己决定。

特点:

1. 没有时区信息,必须系统自己约定使用什么时区的时间2. 表示范围广3. 查询效率没有使用使用 INT 高4. 可以使用 MySQL 提供的种类日期时间函数

3. TIMESTAMP

MySQL 对于 TIMESTAMP 的存储,内部使用的是4字节整数,又受限与时间戳定义,因此,可表示范围大约只有 1970-01-01 00:00:01 到 2038-01-19 03:14:07。

TIMESTAMP 与时区相关,存入时会将时间从 MySQL time_zone 参数设置的时区,转换成 UTC 时间的时间戳存储,读取时,再从 UTC 时间戳转换成 time_zone 参数设置的时区时间。

示例:




mysql 获取毫秒数 mysql 毫秒时间类型_时间戳

测试表结构




mysql 获取毫秒数 mysql 毫秒时间类型_mysql 获取毫秒数_02

当前数据库设置的时区为 +8区




mysql 获取毫秒数 mysql 毫秒时间类型_jquery 毫秒转换成日期_03

插入一条记录




mysql 获取毫秒数 mysql 毫秒时间类型_时间戳_04

修改time_zone为0时区设置后查看



可以看到,DateTime类型的,并没有受时区设置变化影响,TIMESTAMP 类型自动根据修改后的当前时区设置显示了正确的时间。 这个变化,并不是修改时区后,MySQL 把 TIMESTAMP 字段的值修改了,而是显示时,根据当前时区正确显示了,存储的值并没有变化,一直是 UTC 时间。

注意点:

insert 时,TIMESTAMP 字段值必须是与 MySQL 设置的时区一致,因为 MySQL 只会根据 time_zone 参数设置的时区转换到 UTC 时间。

特点:

1. 与时区相关,内部统一使用4字节的 UTC 时间戳存储2. insert 可以使用 MySQL 的 CURRENT_TIMESTAMP 3. update 可以使用 MySQL 的 on update CURRENT_TIMESTAMP

总结几点

  1. 不管使用 INT、DATETIME、TIMESTAMP 哪一种,系统都必须要关心时区
  2. 个人建议的实践方式是将 MySQL 时区设置为 +00:00,数据应该是 UTC 时间入、UTC 时间出,各系统展示时,再从 UTC 时间转换为相应的时区时间