时间戳在接口、代码和数据库类型选用
时间戳在接口、代码和数据库分别应该用什么类型
首先用一个故事先讲下时区的概念
比如 甲在英国(假设时区是+00:00);乙在中国(时区是+08:00);丙在日本(时区是+09:00),甲在2020年10月10号凌晨0点发了条Twitter动态,乙早上8点钟刚起床刚好看到甲发的动态,而在日本的丙9点整刚好已经到公司也刷到甲的动态。这3个人的事件都在发生同一时刻,但是3人各自的本地时间都不同……甲的这条个人动态记录会存储在推特服务器上,服务器肯定不可能为甲、乙、丙3人分别存不同的时间戳,它可能以相对于本机的时区的普通时间格式来存,也可能是以带时区信息的时间格式来存的:
假设服务器在美国(时区是-07:00),存的时间可能有以下几种情况:
2020-10-09T17:00:00相对于本机时区来存2020-10-10T00:00:00ZUTC时区,Z代表0时区2020-10-09T17:00:00-07:00带上了时区信息
Oracle数据库一般只能存第1种,如果是PostgreSQL可以用
timestamptz类型
无论服务器内部以什么格式保存,在给客户端返回的接口数据里一般都不应该用服务器自己本机时区的时间;简单的做法就是接口数据里统一都用带时区的ISO8601标准日期时间格式,然后各个客户端那边它们自己根据用户设备的时区来格式化,比如JSON数据里是2020-10-09T17:00:00-07:00,乙的App里格式化显示的是2020年10月10日8:00点
Java的DTO类里时间戳字段一般以
java.time.OffsetDateTime类型,在序列化成JSON时一般的库都会自动转成ISO8601格式;而实体类通常跟DTO作自动映射,所以时间戳属性也会用OffsetDateTime类型,无论数据库字段类型是否支持时区
2020-10-10T00:00:00Z和2020-10-09T17:00:00-07:00这2个值虽然不在一个时区,但它们都是同一个时间点,是相等的
前端在格式化日期的时候,不要直接用
substring/split之类的方法来截取,应该用dayjs这样的库;比如2020-10-09T17:00:00-07:00直接截取是2020-10-09,实际应该是2020-10-10
查询某一天的数据
1 | |