Spring myBatis强制在系统默认时区保存ZonedDateTime,如何防止?
Spring myBatis forcing to save ZonedDateTime in system default timezone, how to prevent?
我正在设置一个 API 接收日期时间作为字符串以及日期时间来自的国家/地区。我有一个格式化程序可以将这些字符串转换为 ZonedDateTime
假设我发送这个 JSON:
{
"country": "ID",
"activeUntil":"2020-03-10 08:00:00"
}
ID 适用于印度尼西亚(时区 "Asia/Jakarta" 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 只是一个地图,link 一个国家简码到它的时区。
至此一切顺利,我的对象拥有我想要的值。
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 版本<mybatis.version>3.4.5</mybatis.version>
我正在使用 MySQL 数据库
active_until 列的类型是 (MySQL) datetime。
这是查询日志:
==> 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)
如何更改此行为以强制以 UTC 格式保存我的所有 ZonedDateTime
我通过将此添加到我的 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 的时区。
由于我没有设置它,应用程序时区使用的是系统默认值,这一定是我所在位置的时区。
我正在设置一个 API 接收日期时间作为字符串以及日期时间来自的国家/地区。我有一个格式化程序可以将这些字符串转换为 ZonedDateTime
假设我发送这个 JSON:
{
"country": "ID",
"activeUntil":"2020-03-10 08:00:00"
}
ID 适用于印度尼西亚(时区 "Asia/Jakarta" 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 只是一个地图,link 一个国家简码到它的时区。
至此一切顺利,我的对象拥有我想要的值。
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 版本<mybatis.version>3.4.5</mybatis.version>
我正在使用 MySQL 数据库
active_until 列的类型是 (MySQL) datetime。
这是查询日志:
==> 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)
如何更改此行为以强制以 UTC 格式保存我的所有 ZonedDateTime
我通过将此添加到我的 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 的时区。 由于我没有设置它,应用程序时区使用的是系统默认值,这一定是我所在位置的时区。