我需要将当前UTC日期和时间保存在TIMESTAMP WITH TIMEZONE类型的Oracle列中。这是来自使用JPA和Hibernate的Spring Boot服务
我已在我的应用程序yml中启用了以下功能
jpa:
hibernate:
ddl-auto: none
show-sql: true
properties:
hibernate:
dialect: org.hibernate.dialect.Oracle12cDialect
jdbc:
time_zone: UTC
和Entity class字段看起来像
@Column(name = "last_user_edit_date", columnDefinition = "TIMESTAMP WITH TIME ZONE")
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ")
private ZonedDateTime lastUserEditDate;
我使用的设置日期
obj.setLastUserEditDate(ZonedDateTime.of(LocalDateTime.now(), ZoneId.of("UTC")));
相对于实际日期值,上面的方法工作正常。唯一的问题是在数据库中,它保存了UTC时间,但是提到了MST(我的本地时区)作为时区。例如,保存的值为
19-SEP-19 09.50.53.820000000 PM美国/丹佛
此处9.50 PM实际上是UTC时间,但时区为AMERICA / DENVER。我想要的是
19-SEP-19 09.50.53.820000000 PM UTC
如何通过Java 8类实现此Spring JPA?
谢谢
答案 0 :(得分:3)
LocalDateTime
是错误的课程 LocalDateTime
类无法跟踪时间。我无法想象调用LocalDateTime.now()
有道理的情况。在使用类之前,请阅读Javadoc。
Instant
,OffsetDateTime
,ZonedDateTime
要跟踪时刻,请使用Instant
(始终使用UTC),OffsetDateTime
(与UTC偏移的时刻)或ZonedDateTime
(如特定区域)。
奇怪的是,JDBC 4.2需要对OffsetDateTime
的支持,但保留了最常见的两个类,Instant
和ZonedDateTime
是可选的。
因此,要捕获UTC中用于JDBC工作的当前时刻:
OffsetDateTime odt = OffsetDateTime.now( ZoneOffset.UTC ) ;
或更长时间:
Instant instant = instant.now() ; // Capture current moment in UTC.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
发送到数据库:
myPreparedStatement.setObject( … , odt ) ;
从数据库检索:
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
我不使用add Jenkins credentials with curl or Ansible。但是看来您已经涵盖了这个问题,JPA。并查看这篇帖子,JPA Storing OffsetDateTime with ZoneOffset。
Oracle数据库的唯一的问题是在数据库中,它节省了UTC时间,但提到了MST
What’s new in JPA 2.2 – Java 8 Date and Time Types似乎说TIMESTAMP WITH TIME ZONE
类型确实记录了传入数据的时区或UTC偏移量。其他一些数据库,例如Postgres,会将传入的值调整为UTC(零小时-分钟-秒的偏移量)。
要获取UTC,请如上所述检索OffsetDateTime
,然后调用toInstant
方法来产生一个Instant
对象,该对象始终位于UTC中。或产生另一个肯定是UTC的OffsetDateTime
:
OffsetDateTime odtUtc = odt.withOffsetSameInstant( ZoneOffset.UTC ) ;