首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ZonedDateTime到MySql --错偏移了吗?

ZonedDateTime到MySql --错偏移了吗?
EN

Stack Overflow用户
提问于 2021-05-03 16:53:58
回答 1查看 598关注 0票数 0

安装程序: Spring '2.4.1‘应用程序,(hibernate 5.4.25),Java 11

问题如何使用java.time*保存日期(德文时间),以便使运行时= db

问题

调试期间: ZonedDateTime = 2021-05-03 16:11:42.021236

DB: Datetime(6) 2021-05-03 14:11:42.021236

代码语言:javascript
复制
@Entity
public class User {
  private ZonedDateTime createdAt;

//getter&setter
代码语言:javascript
复制
//calling the setter like like: 
user.setCreatedAt(ZonedDateTime.now(ZoneId.of("Europe/Berlin")))
代码语言:javascript
复制
//saving via JPARepo...
Repository.save(user);

application.properties:

代码语言:javascript
复制
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect

#tried but no effect
hibernate.jdbc.time_zone=CET

#tried but no effect
hibernate.jdbc.time_zone=UTC

gradle

代码语言:javascript
复制
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'mysql:mysql-connector-java'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.security:spring-security-test'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
EN

回答 1

Stack Overflow用户

发布于 2021-05-04 03:43:14

我既不使用Spring,也不使用Hibernate,所以我无法具体地帮助它。您还省略了关键的细节,例如数据库列的确切数据类型,因此不可能有特定的答案。但我可以给你一些一般性的建议。

使用OffsetDateTimeZoneOffset.UTC在JDBC中通信

关于ZonedDateTime,要知道JDBC 4.2规范需要对OffsetDateTime的支持。奇怪的是,规范忽略了对更常用的InstantZonedDateTime类的支持。Java团队的这一设计选择让我感到困惑,尤其是在Instant方面,它简单得可以来回转换。

JDBC,重点是在您的OffsetDateTime工作中使用➥。

通常最好在UTC中完成所有业务逻辑、数据交换、数据存储、日志记录和调试。也就是说,与协调世界时的零小时-分-秒,没有时区的偏移.仅在业务规则或演示文稿中用户的期望所要求的情况下使用时区。

UTC中的矩的基本类是Instant。通常,这应该是您的类成员字段的类型,它跟踪时间线上的某个特定点。

使用Instant.now捕捉当前时刻。要记录创建"user“对象的时间,请执行以下操作:

代码语言:javascript
复制
Instant userCreated = Instant.now() ;

要在数据库中记录片刻,您的列必须是类似于SQL标准TIMESTAMP WITH TIME ZONE的类型。在MySQL 8中,意思是TIMESTAMP,而不是DATETIME。见文献资料

要将我们的Instant对象的值写入数据库,您的JDBC驱动程序可能能够处理Instant对象,尽管它在JDBC规范中是可选的。如果没有,或者如果您想编写更多的可移植代码,请使用OffsetDateTime。指定偏移量为零小时-分钟-秒的ZoneOffset.UTC常量。

代码语言:javascript
复制
OffsetDateTime odt = userCreated.atOffset( ZoneOffset.UTC ) ;

将该对象传递给您准备好的语句。

代码语言:javascript
复制
myPreparedStatement.setObject( … , odt ) ;

检索。

代码语言:javascript
复制
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;

轻松地转换回一个简单的Instant

代码语言:javascript
复制
Instant instant = odt.toInstant() ;

若要适应德国时间,请应用ZoneId获得ZonedDateTime

代码语言:javascript
复制
ZoneId z = ZoneId.of( "Europe/Berlin" ) ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;

请理解,MySQL只存储UTC中的所有TIMESTAMP值。不幸的是,一些中间件和工具可能选择对从数据库中检索的值进行时区调整。使用上面的代码,我相信你不会有这个问题。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67372819

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档