Java LocalDateTime存储自动加+5:30偏移 如何设置偏移为00:00:00
问题描述
解析日期字符串得到LocalDateTime类型时间后存入数据库,实际写入值比预期值多5小时30分偏移,预期存储值为2011-10-24 00:00:00,实际存储为2011-10-24 05:30:00。
复现代码如下:
String d = "2011-10-24"; Fun fun = new Fun(); fun.setTmp(LocalDateTime.parse(d + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); fun.save(); // 实际存入数据库的值为2011-10-24 05:30:00,我的预期存储值为2011-10-24 00:00:00
根因分析
5小时30分是UTC+5:30时区(印度标准时间)的固定偏移量,出现该问题的核心原因是时区配置不统一:
LocalDateTime不携带任何时区信息,JDBC驱动持久化该类型数据时,会默认读取JVM当前默认时区做时间转换- 若数据库服务端时区、JDBC连接配置的时区、JVM时区三者不一致,驱动会自动做偏移量计算,最终导致写入时间和预期不符
解决方案
以下方案任选其一即可,优先推荐无侵入的配置类方案:
- 统一JDBC连接时区
在数据库连接URL中强制指定使用UTC+0时区,避免驱动自动推断时区,以MySQL为例,连接URL配置如下:jdbc:mysql://数据库IP:端口/库名?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8 - 配置JVM全局默认时区
在服务启动命令中添加JVM参数,强制整个应用使用UTC时区:java -Duser.timezone=UTC -jar 你的应用jar包名.jar - 代码层面显式指定时间偏移
改用带时区信息的时间类型,显式指定偏移量为0,从代码层面规避自动转换问题:String d = "2011-10-24"; LocalDateTime parsedTime = LocalDateTime.parse(d + " 00:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); // 显式绑定UTC+0偏移 OffsetDateTime utcTime = parsedTime.atOffset(ZoneOffset.UTC); Fun fun = new Fun(); fun.setTmp(utcTime); fun.save();
补充说明:如果数据库字段使用的是
timestamp类型,数据库本身会按时区配置做值转换;如果使用的是datetime类型,建议在JDBC参数中追加noDatetimeStringSync=true关闭多余的时间同步转换。
内容的提问来源于stack exchange,提问作者Rupesh
相关产品推荐
相关产品推荐

