【问题标题】:Spring myBatis forcing to save ZonedDateTime in system default timezone, how to prevent?Spring myBatis 强制将 ZonedDateTime 保存在系统默认时区,如何防止?
【发布时间】:2019-12-31 05:03:12
【问题描述】:

我正在设置一个 API,它以字符串形式接收日期时间以及日期时间所在的国家/地区。我有一个格式化程序,可以将这些字符串转换为 ZonedDateTime

假设我正在发送这个 JSON:

{
    "country": "ID",
    "activeUntil":"2020-03-10 08:00:00"
}

ID 用于印度尼西亚(时区“亚洲/雅加达”UTC+7)

这是我的转换器

public static ZonedDateTime convertDatetimeStringToDatetime(String dtString, String country) throws ParseException {
    DateFormat formatter = new SimpleDateFormat(("yyyy-MM-dd HH:mm:ss"));
    formatter.setTimeZone(TimeZone.getTimeZone(CountryTimezones.timezoneMap.get(country)));
    return formatter.parse(dtString).toInstant().atZone(ZoneId.of(CountryTimezones.timezoneMap.get(country)));
}

CountryTimezones.getTimeZone 只是一个将国家简码链接到其时区的地图。

到目前为止一切正常,我的对象拥有我想要的值。

log.info(myObject.getActiveUntil().toString());
log.info(myObject.getActiveUntil().toLocalDateTime().toString());
log.info(myObject.getActiveUntil().withZoneSameInstant(ZoneId.of("UTC")).toString());

表演

2020-03-10T08:00+07:00[Asia/Jakarta]
2020-03-10T08:00
2020-03-10T01:00Z[UTC]

当我将日期保存到数据库时,问题就来了。我用的是mybatis,我的查询是这样的:

<insert id="insert">
    INSERT INTO sometable (country, active_until, created_by)
    VALUES (#{entity.country}, #{entity.activeUntil}, #{entity.createdBy})
</insert>

(为清楚起见缩短)

保存的日期时间为“2020-03-10 09:00:00”

有关信息,我的位置时区是 utc+8,这意味着日期时间会自动转换为我的位置时区。

MyBatis 版本&lt;mybatis.version&gt;3.4.5&lt;/mybatis.version&gt;

我正在使用 MySQL 数据库

active_until 列的类型是(MySQL)日期时间。

这是查询日志:

==> Preparing: INSERT INTO sometable (country, active_until, created_by) VALUES (?, ?, ?)
==> Parameters: ID(String), 2020-03-10 09:00:00.0(Timestamp), Created by System(String)

如何更改此行为以强制将我的所有 ZonedDateTime 保存为 UTC

【问题讨论】:

  • 请指定 1) MyBatis 版本,2) DB/驱动程序版本和 3) active_until 列的类型。
  • 我将编辑我的帖子。 3.4.5 MySQL DB active_until 属于 Mysql datetime 类型

标签: java spring datetime timezone mybatis


【解决方案1】:

我通过将它添加到我的 Application.java 来修复它

@PostConstruct
public void init() {
    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
    System.out.println("Spring boot application running in UTC timezone :" + new Date());
}

myBatis 显然将应用程序的时区作为用于保存 ZonedDateTime 的时区。 由于我没有设置它,所以应用程序时区使用的是系统默认值,这一定是我所在位置的时区。

【讨论】:

    猜你喜欢
    • 2021-10-24
    • 2019-08-04
    • 1970-01-01
    • 2015-02-02
    • 1970-01-01
    • 2016-10-14
    • 2022-01-24
    • 1970-01-01
    相关资源
    最近更新 更多