简体   繁体   English

在 sql 服务器中使用 UTC 时间保存当前日期的问题

[英]Issue in saving current date with UTC time in sql server

I want save date with UTC time zone in sql server 2014. I have used ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("UTC")) to get the current date time and persisting this to db using Hibernate session object. I want save date with UTC time zone in sql server 2014. I have used ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("UTC")) to get the current date time and persisting this to db using Hibernate session object. While debugging I can see that in Java program date is fine like this 2019-09-25T13:22:29.573Z[UTC] , but after saving in database column it is something like this 2019-09-25 18:53:23.3630000 .在调试时,我可以看到在 Java 程序日期很好,就像这样2019-09-25T13:22:29.573Z[UTC] ,但是在保存到数据库列之后,它就像这样2019-09-25 18:53:23.3630000 It's automatically converting the time part according to system time.它会根据系统时间自动转换时间部分。 Can anyone please suggest what is the issue?任何人都可以请建议是什么问题? I have used datetime2 datatype while creating this column in database.我在数据库中创建此列时使用了datetime2数据类型。

Wrong type类型错误

You are using the wrong data type for your column.您为列使用了错误的数据类型。

The type datetime2 cannot represent a moment. datetime2类型不能代表片刻。 That type stores only a date and a time-of-day, but lacks the context of a time zone or offset-from-UTC.该类型仅存储日期和时间,但缺少时区或从 UTC 偏移的上下文。 So if you store “noon on the 23rd of January in 2020”, we cannot know if you meant noon in Tokyo Japan, noon in Tunis Tunisia, or noon in Toledo Ohio US, three different moments several hours apart.因此,如果您存储“2020 年 1 月 23 日中午”,我们无法知道您是指日本东京的中午、突尼斯突尼斯的中午,还是美国俄亥俄州托莱多的中午,三个不同的时刻相隔几个小时。 This wrong type is akin to the SQL standard type TIMESTAMP WITHOUT TIME ZONE .这种错误类型类似于 SQL 标准类型TIMESTAMP WITHOUT TIME ZONE The equivalent class in Java is LocalDateTime . Java 中的等效 class 是LocalDateTime

If you already have data stored, you will need to refactor your database .如果您已经存储了数据,则需要重构您的数据库 Basically, add a new column of the correct type, copy data over for each row, converting as you go.基本上,添加一个正确类型的新列,为每一行复制数据,转换为 go。 Of course, this only works if you know the intended time zone that was absent from each value saved.当然,这仅在您知道每个保存的值中缺少的预期时区时才有效。

Right type正确的类型

While I don't use Microsoft SQL Server, according to the doc you should be using a column of type datetimeoffset to record a moment .虽然我不使用 Microsoft SQL 服务器,但根据文档,您应该使用datetimeoffset类型的列来记录 moment This type adjusts any submitted value into UTC for queries and sorting, while also recording the offset.此类型将任何提交的值调整为 UTC 以进行查询和排序,同时还记录偏移量。 This type is akin to the SQL standard type TIMESTAMP WITH TIME ZONE .此类型类似于 SQL 标准类型TIMESTAMP WITH TIME ZONE

Generally best to store your moments in UTC, an offset of zero hours-minutes-seconds.通常最好将您的时刻存储在 UTC 中,偏移量为零时分秒。

The Instant class represents a moment in UTC. Instant class 代表 UTC 中的一个时刻。

Instant instant = Instant.now() ;

If you have a ZonedDateTime , you can extract an Instant .如果您有ZonedDateTime ,则可以提取Instant

Instant instant = zdt.toInstant() ;

We would like to save that Instant directly to the database.我们想将该Instant直接保存到数据库中。 Unfortunately the JDBC 4.2 soec does not require support for either of the two most commonly used java.time classes: Instant and ZonedDateTime .不幸的是,JDBC 4.2 soec 不需要支持两个最常用的java.time类中的任何一个: InstantZonedDateTime The spec does require support for OffsetDateTime .该规范确实需要支持OffsetDateTime So we convert.所以我们转换。

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

Submit to database.提交到数据库。

myPreparedStatement.setObject( … , odt ) ; 

Retrieve.取回。

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

Extract an Instant to make clear in your code that you want UTC.提取Instant以在您的代码中明确您需要 UTC。

Instant instant = odt.toInstant() ;

See this moment through the wall-clock-time used by the people of a particular region (a time zone).通过特定地区(时区)的人们使用的挂钟时间来查看这一刻。

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

Java(传统和现代)和标准 SQL 中的日期时间类型表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM