Java 在sql server中使用UTC时间保存当前日期时出现问题

Java 在sql server中使用UTC时间保存当前日期时出现问题,java,hibernate,sql-server-2014,Java,Hibernate,Sql Server 2014,我希望在sql server 2014中使用UTC时区保存日期。我使用ZonedDateTime ZonedDateTime=ZonedDateTime.nowZoneId.Oftc获取当前日期时间,并使用Hibernate会话对象将其持久化到db。在调试过程中,我可以看到Java程序中的日期是这样的2019-09-25T13:22:29.573Z[UTC],但在数据库列中保存后,它是这样的2019-09-25 18:53:23.3630000。它根据系统时间自动转换时间部分。有人能提出问题吗?

我希望在sql server 2014中使用UTC时区保存日期。我使用ZonedDateTime ZonedDateTime=ZonedDateTime.nowZoneId.Oftc获取当前日期时间,并使用Hibernate会话对象将其持久化到db。在调试过程中,我可以看到Java程序中的日期是这样的2019-09-25T13:22:29.573Z[UTC],但在数据库列中保存后,它是这样的2019-09-25 18:53:23.3630000。它根据系统时间自动转换时间部分。有人能提出问题吗?在数据库中创建此列时,我使用了datetime2数据类型。

类型错误 您的列使用了错误的数据类型

datetime2类型不能表示时刻。该类型仅存储日期和时间,但缺少时区或UTC偏移量的上下文。因此,如果你存储“2020年1月23日中午”,我们无法知道你是指日本东京的中午,突尼斯的中午,还是美国俄亥俄州托莱多的中午,三个不同的时刻相隔几个小时。此错误类型类似于没有时区的SQL标准类型时间戳。Java中的等效类是

如果已经存储了数据,则需要。基本上,添加一个正确类型的新列,为每一行复制数据,并进行转换。当然,这只有在您知道每个保存的值中缺少的预期时区时才有效

正确类型 虽然我不使用MicrosoftSQLServer,但根据文档,您应该使用datetimeoffset类型的列来记录一个时刻。此类型将任何提交的值调整为UTC以进行查询和排序,同时记录偏移量。此类型类似于带时区的SQL标准类型时间戳

通常,最好以UTC(零小时分秒的偏移量)存储您的时刻

Instant类表示UTC中的一个时刻

Instant instant = Instant.now() ;
如果你有一个ZoneDateTime,你可以提取一个瞬间

我们希望将该瞬间直接保存到数据库中。不幸的是,JDBC 4.2 soec不需要支持两个最常用的java.time类:Instant和ZonedDateTime。该规范确实需要对OffsetDateTime的支持。所以我们皈依了

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
提交到数据库

myPreparedStatement.setObject( … , odt ) ; 
找回

OffsetDateTime odt = MyResultSet.getObject( … , OffsetDateTime.class ) ;
提取一个瞬间,以便在代码中明确您想要UTC

Instant instant = odt.toInstant() ;
通过墙上的时钟看这个时刻特定地区的人们使用的时间——时区

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
错误类型 您的列使用了错误的数据类型

datetime2类型不能表示时刻。该类型仅存储日期和时间,但缺少时区或UTC偏移量的上下文。因此,如果你存储“2020年1月23日中午”,我们无法知道你是指日本东京的中午,突尼斯的中午,还是美国俄亥俄州托莱多的中午,三个不同的时刻相隔几个小时。此错误类型类似于没有时区的SQL标准类型时间戳。Java中的等效类是

如果已经存储了数据,则需要。基本上,添加一个正确类型的新列,为每一行复制数据,并进行转换。当然,这只有在您知道每个保存的值中缺少的预期时区时才有效

正确类型 虽然我不使用MicrosoftSQLServer,但根据文档,您应该使用datetimeoffset类型的列来记录一个时刻。此类型将任何提交的值调整为UTC以进行查询和排序,同时记录偏移量。此类型类似于带时区的SQL标准类型时间戳

通常,最好以UTC(零小时分秒的偏移量)存储您的时刻

Instant类表示UTC中的一个时刻

Instant instant = Instant.now() ;
如果你有一个ZoneDateTime,你可以提取一个瞬间

我们希望将该瞬间直接保存到数据库中。不幸的是,JDBC 4.2 soec不需要支持两个最常用的java.time类:Instant和ZonedDateTime。该规范确实需要对OffsetDateTime的支持。所以我们皈依了

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
提交到数据库

myPreparedStatement.setObject( … , odt ) ; 
找回

OffsetDateTime odt = MyResultSet.getObject( … , OffsetDateTime.class ) ;
提取一个瞬间,以便在代码中明确您想要UTC

Instant instant = odt.toInstant() ;
通过墙上的时钟看这个时刻特定地区的人们使用的时间——时区

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

Sql server没有将时区存储为日期的一部分,因此如果不在系统时间的时区中,您希望如何存储它?如果您需要完全相同的时间,请修改服务器以使用UTC时间,或者在将日期读回java时记住将其转换回UTC如果使用hibernate/java检索日期并通过java或在调试器中打印,您会得到什么?Sql server不会将时区存储为日期的一部分,因此如果不在系统时间的时区?如果需要完全相同的时间,请修改服务器以使用UTC时间,或者在读取日期时记住将其转换回UTC
回到java如果用hibernate/java检索日期并用java或调试器打印它,你会得到什么?嗨,Basil,谢谢你的回答,实际上我正在使用hibernate来持久化和检索数据,在这种情况下,我可以在我的pojo类的这个日期时间字段中使用哪个类?嗨,Basil,感谢您的回复,实际上我正在使用Hibernate来持久化和检索数据,在这种情况下,我可以在pojo类的这个日期时间字段中使用哪个类?