gpt4 book ai didi

java - 在 SQL Server 中使用 UTC 时间保存当前日期时出现问题

转载 作者:行者123 更新时间:2023-12-02 09:29:29 25 4
gpt4 key购买 nike

我想在sql server 2014中使用UTC时区保存日期。我已使用ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("UTC"))来获取当前日期时间并使用 Hibernate session 对象将其保存到数据库。在调试时,我可以看到在Java程序中日期很好,像这样2019-09-25T13:22:29.573Z[UTC],但是在保存到数据库列之后,它是这样的2019 -09-25 18:53:23.3630000。它会根据系统时间自动转换时间部分。任何人都可以建议是什么问题吗?我在数据库中创建此列时使用了 datetime2 数据类型。

最佳答案

类型错误

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

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

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

右类型

虽然我不使用 Microsoft SQL Server,但根据文档,您应该使用 datetimeoffset 类型的列来记录时刻。此类型将任何提交的值调整为 UTC 以进行查询和排序,同时还记录偏移量。此类型类似于 SQL 标准类型TIMESTAMP WITH TIME ZONE

通常最好以 UTC 格式存储您的时刻,偏移量为零时-分-秒。

Instant 类表示 UTC 中的某个时刻。

Instant instant = Instant.now() ;

如果您有 ZonedDateTime,则可以提取 Instant

Instant instant = zdt.toInstant() ;

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

OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;

提交到数据库。

myPreparedStatement.setObject( … , odt ) ; 

检索。

OffsetDateTime odt = MyResultSet.getObject( … , OffsetDateTime.class ) ;

提取 Instant 以在代码中明确表示您需要 UTC。

Instant instant = odt.toInstant() ;

通过特定地区(时区)的人们使用的挂钟时间来查看这一时刻。

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

Table of date-time types in Java (both legacy and modern) and in standard SQL.

关于java - 在 SQL Server 中使用 UTC 时间保存当前日期时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58099500/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com