引言
涉及多国家时时常会被时间的时区所困惑。
根据所需时间的精度选择不同的类型进行存储。
存储范围
每种日期类型都有一个有效范围,超过则报错并以零值存储。
时区
需要注意的是即便 DATETIME
和 TIMESTAMP
返回相同的格式,它们的工作方式很不同。在 INSERT 或 UPDATE 查询中,TIMESTAMP 自动把自身设置为当前的日期和时间。TIMESTAMP 也接受不同的格式,比如 YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD 或 YYMMDD。
并且TIMESTAMP
带时区,DATETIME
不带时区。
TIMESTAMP
具体效果为:
当插入日期时,会先转换为本地时区后再存放;当查询日期时,会将日期转换为本地时区后再显示。所以不同时区的人看到的同一时间是 不一样的。
例如:连接MYSQL设置的是serverTimezone=UTC
北京时间的时区为UTC+8
当我们存入2020-10-10 16:13:41 查看数据库得到 2020-10-10 8:13:41
若我们在泰国的服务器(UTC+7)查看,取出来时将会显示 2020-10-10 15:13:41
基于以上特性,该如何进行时间的存储?
我的想法是最好采用无时区类型进行存储。即要么采用datetime 要么使用bigint的整型时间戳(我们目前使用的)。
基于“数据的存储和显示相分离”的设计原则,只需要把Long或者Float表示的时间戳存到BIGINT
或REAL
类型的列中,完全不用管数据库自己提供的DATETIME
或TIMESTAMP
存入数据库,在显示的时候根据用户设置的时区格式化为正确的字符串。
但是有一个问题,分布式应用场景下,服务器处于不同时区,最好存储成某一个特定时区的时间戳整型。如都使用UTC+0的时间下的时间戳。