DMS内部历史数据Date类型字段全球化时间改造

一、系统现状与约束

1.1 当前环境

数据库 MySQL 运行于东八区(+08:00),所有 datetime 字段均存储东八区本地时间。服务器操作系统同样设置为东八区,且无计划进行修改。
JVM 通过参数-Duser.timezone=GMT+8配置为东八区,生成的日志时间也为东八区时间。系统中已积累数百万条历史数据。
后端采用 Spring Boot / MyBatis 框架,实体类中时间类型混用 Date 和 LocalDateTime。前端框架为 Vue,目前直接展示后端返回的字符串,未进行任何时区处理。

1.2 硬性约束(红线)

不修改任何历史数据;
不改变数据库字段结构;
不在 SQL 语句中使用任何时区转换函数;
不修改 MyBatis 的映射行为;
同时不要求前端进行复杂的时区计算逻辑。

二、总体设计原则

数据库存储东八区时间,接口传输时间戳,前端根据用户本地时区自适应展示,业务相关时间需携带时区信息。
具体分层处理原则:
- 数据库层:不进行任何时区处理。
- SQL 层:不进行任何时区处理。
- Service 层:不进行任何时区处理。
- Mapper 层:不进行任何时区处理。
- Controller 入参:将接收到的时间戳转换为具有东八区语义的 Date 对象。
- Controller 出参:将 Date 对象转换为毫秒时间戳。
- 前端:将接收到的时间戳转换为用户本地时区的时间进行展示。

时间字段分类处理:
- 系统时间:以 datetime 类型存储于东八区,接口传输时使用毫秒时间戳。
- 业务时间:由 datetime 类型字段和对应的时区字段共同存储,接口传输时使用本地时间字符串(包含时区信息)。

三、系统时间解决方案

通过自定义@SystemTimeDate注解实现系统时间的统一处理。该注解具备以下功能:
- 入参时,能够接收并正确解析时间戳(毫秒)或格式为 "yyyy-MM-dd HH:mm:ss" 的字符串(此字符串语义为东八区时间)。
- 出参时,统一将 Date 类型的系统时间转换为毫秒时间戳输出。

对于如 createTime、updateTime 等系统时间字段,使用@SystemTimeDate注解进行标记;业务时间字段则不使用该注解。

四、业务时间解决方案

- 若存在业务时间字段track_time(datetime 类型),则新增对应的时区字段track_zone(varchar(50) 类型)。
- 若存在业务时间字段appointment_time(datetime 类型),则新增对应的时区字段appointment_zone(varchar(50) 类型)。通过这两个字段组合,完整记录业务时间的原始时区信息。

六、完整调用链路说明

1. 前端将用户输入或选择的时间转换为时间戳,并发送至后端。
2. Controller 层接收时间戳参数,通过反序列化将其转换为具有东八区语义的 Date 对象。
3. Service 层、Mapper 层以及 SQL 语句均不对时间做任何处理,直接使用该 Date 对象。
4. 数据库按照东八区时间存储接收到的 Date 对象。
5. 当需要返回时间数据时,Controller 层将 Date 对象序列化为毫秒时间戳输出。
6. 前端接收到时间戳后,自动根据用户设备的本地时区将其转换为对应的本地时间进行展示。

七、时序图

八、禁止操作清单

- 禁止修改历史 datetime 类型数据。
- 禁止新增用于存储 UTC 时间的冗余字段。
- 禁止在 SQL 语句中进行任何形式的时区转换操作。
- 禁止在 Service 层手动编写代码处理时区转换。
- 禁止前端通过硬编码方式设置时区偏移量。
- 禁止模糊定义时间字段的语义,必须明确其代表的时区或处理方式。
- 禁止在系统时间字段中存储时区信息。

九、常见问题与决策

- 历史无时区数据处理:对于历史数据中未明确时区的时间字段,默认其语义为东八区时间。
- 定时任务处理:所有定时任务统一按照东八区时间进行调度和执行。
- DynamicConditionUtil 兼容:确保 DynamicConditionUtil 能够正确处理以时间戳形式传入的时间参数。

十、代码示例



十一、总结

实现以下目标:
- 零历史数据改造:无需修改已有历史数据。
- 零数据库结构变更:不改变现有数据库表结构(业务时间新增时区字段除外,这属于功能扩展而非结构变更)。
- 零 SQL 修改:现有 SQL 语句无需调整。
- 零侵入业务逻辑:业务代码无需为时区处理做额外修改。
- 零影响 DynamicConditionUtil:保证其正常工作。
- 全链路时区正确:从数据存储到前端展示,时间在各环节均能正确表示和转换。
- 可灰度:支持灰度发布,降低风险。
- 可回滚:若出现问题,具备回滚能力。
- 兼容旧版前端:对未升级的旧版前端保持兼容。

方案核心内容:系统时间采用注解结合时间戳的方式进行传输和处理;
业务时间采用 datetime 字段加时区字段的方式存储,并传输本地时间字符串;数据库统一存储东八区时间;
前端根据用户本地时区自适应展示时间。
作者:陆飞  创建时间:2026-02-09 10:36
最后编辑:陆飞  更新时间:2026-03-03 10:08