You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot不同版本写入ZonedDateTime到MySQL 8的时间差异问题

问题描述

使用Spring Boot 3.0将ZonedDateTime写入MySQL 8时,结果与Spring Boot 3.1/3.2存在差异。本地机器时间为2024-02-22 21:00:00+08:00,Spring Boot 3.0写入的时间为2024-02-22 21:00:00,而3.1/3.2版本写入的是2024-02-22 13:00:00。除Spring Boot版本外,所有代码均一致,请问为何会出现该差异?

相关代码

数据库表创建语句

CREATE TABLE Abc (
  id int NOT NULL AUTO_INCREMENT,
  dt datetime DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

实体类代码

@Data
@Entity
@Table(name = "Abc")
public class Abc {
    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Integer id;

    private ZonedDateTime dt;
}

Repository接口代码

public interface AbcRepository extends CrudRepository<Abc, Integer> {
}

保存数据的代码

Abc abc = new Abc();
abc.setDt(ZonedDateTime.now());
abcRepository.save(abc);
原因分析
  • Hibernate版本升级带来的时区转换逻辑变更:Spring Boot 3.0对应Hibernate 6.1.x,Spring Boot 3.1/3.2升级到了Hibernate 6.2.x。Hibernate 6.1默认将ZonedDateTime转换为数据库服务器的本地时区后存储;而Hibernate 6.2调整了默认行为,会将ZonedDateTime转换为UTC时区再写入datetime字段,这就导致东八区的21:00被转换为UTC的13:00存储。
  • JDBC驱动默认配置的调整:Spring Boot 3.1+对MySQL JDBC驱动的默认时区处理做了优化,当未显式指定serverTimezone参数时,ORM框架会优先采用UTC时区进行时间转换,而3.0版本则会沿用应用或数据库的本地时区。
  • MySQL datetime类型的特性限制:MySQL的datetime类型本身不存储时区信息,仅保存日期时间数值。不同版本的ORM框架对带时区的Java时间类型(如ZonedDateTime)的转换规则差异,直接导致了最终存储结果的不同。

内容的提问来源于stack exchange,提问作者吳俊霆

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 16:00:56