【问题标题】:Does mybatis change time zone while inserting into a DB?mybatis 在插入数据库时​​会更改时区吗?
【发布时间】:2020-09-09 10:32:00
【问题描述】:

在 Oracle 中向表中插入记录时,创建日期列中的时间戳为 UTC 下午 4 点(完整格式,例如...2020-05-20 10:30:20.15 UTC)。这甚至在调用 Mybatis 的 save 方法之前就得到了验证。调用 save 方法后,DB 中新记录中的创建日期列没有 UTC 作为时间。它显示下午 4 点亚洲/加尔各答。时间戳的数字部分正确,但时区已更改。

我们的代码在 Spring 框架中 - mybatisMapper.save(events) .. events POJO 中的 created_date 列是 java.util.Date 类型。 我们正在尝试在蒙特利尔托管的数据库中插入一条记录。 从对偶中选择 dbtimezone; 服务器的 DBtimezone - -04:00 表示美国/蒙特利尔时区(托管在美国/蒙特利尔)

从双重中选择会话时区; 会话时区 - 亚洲/加尔各答。(因为应用程序在印度运行)。

创建日期列的数据类型为TIME STAMP WITH TIMEZONE。 mybatis 是在随意更改时区,还是完全放弃它并让 Oracle 自己决定时区?

【问题讨论】:

  • 在时区之上,我会检查locale。你能检查一下本地系统和数据库主机上的那个吗?
  • 语言环境?数据库语言环境?不知道这件事。这一切可能的原因是什么?你能详细说明一下语言环境是如何造成问题的吗?
  • 并非每个国家/地区都有夏令时,如果设置错误可能会导致问题。我也支持 Basil Bourque 并且会摆脱 java.util.Date
  • 即使在尝试了 OffsetDateTime 之后,问题仍然存在。可能是什么原因?
  • 它应该可以工作。请务必使用最新版本的驱动程序和 MyBatis。在版本 PreparedStatement#setTimestamp(),这导致了与时区相关的issues。 Java Time API 的支持因 DB/驱动程序而异。对于OffsetDateTime,请参阅here 了解更多信息。

标签: java oracle mybatis spring-mybatis timestamp-with-timezone


【解决方案1】:

永远不要使用java.util.Date这个可怕的类在几年前被 JSR 310 中定义的现代 java.time 类所取代。

Date 的问题之一是它的toString 方法在生成其文本时动态应用 JVM 的当前默认时区。这会产生该区域包含在对象中的错觉,而实际上Date(尽管用词不当)代表UTC 中的一个时刻。避免此类的众多原因之一。

由于您没有发布任何代码,我只能猜测您的问题是被Date::toString所说的谎言误导了。

从 JDBC 4.2 开始,我们可以与数据库交换 java.time 对象。具体来说,使用OffsetDateTime 类来交换存储在类似于SQL 标准类型TIMESTAMP WITH TIME ZONE 的类型的列中的值。 InstantZonedDateTime 也可能根据您的 JDBC 驱动程序工作,但奇怪的是 JDBC 4.2 不需要支持这两个更常用的类。我一般建议你在课堂上存储一个Instant,转换为OffsetDateTime/从OffsetDateTime

仅供参考,时区Asia/Calcutta 已重命名为Asia/Kolkata

示例代码

String input = "2020-05-20T10:30:20.15Z" ;
Instant instant = Instant.parse( input ) ;
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
ZonedDateTime zdt = instant.atZone( ZoneId.of( "Asia/Kolkata" ) ) ;

写入数据库。

…
myPreparedStatement.setObject( … , odt ) ;

从数据库中检索。

OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( ZoneId.of( "Asia/Kolkata" ) ) ;

这已经在 Stack Overflow 上讨论过很多次了。搜索以了解更多信息。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-16
    • 1970-01-01
    • 2013-08-21
    • 1970-01-01
    • 2017-06-01
    • 1970-01-01
    • 2021-06-22
    • 2018-04-29
    相关资源
    最近更新 更多