不感知时区的java.util.Date为何在跨多时区场景中仍可正常工作?
java.util.Date 时区表现正常的原理说明
1. java.util.Date 的本质特性
java.util.Date 本身不存储任何时区信息,它的内部仅维护了一个long类型的时间戳,代表从1970-01-01 00:00:00 UTC到当前时间的毫秒数。你在日志中看到的Sun Sep 05 18:00:00 PKT 2021格式的输出,只是Date的toString()方法默认使用JVM当前时区(你配置的Asia/Karachi)对时间戳做了格式化展示,不会改变底层存储的UTC时间戳本身。
2. 接口反序列化阶段的处理
你配置了以下Jackson参数:
spring.jackson.deserialization.adjust-dates-to-context-time-zone=true spring.jackson.time-zone=Asia/Karachi
当前端从UTC+3时区传时间参数到后端时,Jackson会自动将前端传递的带有时区信息的时间值,转换为对应正确的UTC时间戳存入Date对象,再按照配置的服务端时区做格式化展示,整个过程不会丢失时间偏移信息,底层时间戳始终正确。
3. 数据库持久化阶段的处理
你配置了spring.jpa.properties.hibernate.jdbc.time_zone=UTC,Hibernate在做JDBC参数绑定时,会直接将Date对象存储的UTC时间戳,转换为UTC时区的DATETIME值写入数据库,刚好匹配你的MySQL数据库的UTC时区设置,因此最终存储的结果完全符合预期。
整个流程中Date只负责存储和传递无歧义的UTC时间戳,时区转换完全由Jackson和Hibernate按照你的配置完成,因此不会出现时区偏移错误。
内容的提问来源于stack exchange,提问作者Anushka Darshana
相关产品推荐
相关产品推荐

