MariaDB与应用时区配置异常及正确配置方法咨询
问题解答
1. 这不是正常流程,问题根源在于LocalDateTime的特性
你用LocalDateTime.now()获取的是不带时区信息的本地时间(KST),但JDBC驱动在serverTimezone=UTC的配置下,会默认把传入的LocalDateTime当作UTC时间直接存入数据库。也就是说,驱动不知道你传入的14:00是KST时区的,直接把它当成UTC时间存了进去,所以出现了预期和实际不符的情况。
2. 正确配置方案(保持数据库UTC,应用用Asia/Seoul)
核心思路
使用带时区信息的日期时间类型(ZonedDateTime/OffsetDateTime)替代LocalDateTime,让JDBC驱动能明确识别应用侧的时区,自动完成KST到UTC的转换后存入数据库。
具体操作
(1)修改代码
- 替换
LocalDateTime为ZonedDateTime,明确指定应用时区:
@PostConstruct void started() { // 保持默认时区设置不变 TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul")); } @PostMapping public void insertTime() { // 获取带Asia/Seoul时区的当前时间 ZonedDateTime now = ZonedDateTime.now(ZoneId.of("Asia/Seoul")); log.info(now.toString()); TImeTest timeTest = TImeTest.builder() .createdAt(now) .modifiedAt(now) .build(); timeTestRepository.save(timeTest); }
- 实体类
TImeTest的createdAt、modifiedAt字段类型同步改为ZonedDateTime(JPA等ORM框架会自动适配数据库的TIMESTAMP类型)。
(2)保持现有配置不变
- JDBC URL的
serverTimezone=UTC保留:这个参数是告诉驱动,数据库的时区是UTC,驱动会自动完成应用时区(KST)到数据库时区(UTC)的转换。 - MariaDB的UTC配置(全局、会话、系统时区均为UTC)保持现状,无需修改。
补充说明
如果坚持要用LocalDateTime,也可以手动将其转换为UTC时间后存入,但这种方式容易出错,不如直接使用带时区的类型更可靠:
// 手动转换KST的LocalDateTime到UTC LocalDateTime kstTime = LocalDateTime.now(); ZonedDateTime utcTime = kstTime.atZone(ZoneId.of("Asia/Seoul")).withZoneSameInstant(ZoneId.of("UTC")); LocalDateTime utcLocal = utcTime.toLocalDateTime(); // 存入utcLocal
内容的提问来源于stack exchange,提问作者jinwoo
相关产品推荐
相关产品推荐

