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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 03:22:45