简体   繁体   English

夏令时没有时区的时间戳中的时间偏移

[英]Daylight Savings Time shift in Timestamp without timezone

I am using hibernate to communicate with a postgresql database for storing data for modelling. 我正在使用hibernate与postgresql数据库进行通信,以存储用于建模的数据。 In these models, there are time series that are based on time stamps without timezone. 在这些模型中,有时间序列基于没有时区的时间戳。 Now, when uploading timestamps that were created correctly (in this case for the year 2030), the timestamp for 2030-03-31T02:00 ends up as 2030-03-31T-03:00 in the database in the column that is a timestamp without timezone. 现在,在上传正确创建的时间戳(在本例中为2030年)时,2030-03-31T02:00的时间戳最终为2030-03-31T-03:00,该数据库中的列是没有时区的时间戳。 I already changed the Database config so that its timezone is UTC, but the problem stays. 我已经更改了数据库配置,使其时区为UTC,但问题仍然存在。

The problem seems to be located either in the driver ( https://mvnrepository.com/artifact/org.postgresql/postgresql/42.2.5 ) or in the database. 问题似乎位于驱动程序( https://mvnrepository.com/artifact/org.postgresql/postgresql/42.2.5 )或数据库中。 When inserting the timestamp as string, it works. 将时间戳插入字符串时,它可以正常工作。 Also this problem is occuring on a local and a remote DB. 此问题也出现在本地和远程数据库上。

Also, hibernate is in Version 5.4.2 (newest) and in my persistence.xml i set the flag: 另外,hibernate是在版本5.4.2(最新版本)中,在我的persistence.xml中我设置了标志:

<property name="hibernate.jdbc.time_zone" value="UTC"/>

A small test i wrote looks like this: 我写的一个小测试看起来像这样:

@Test
   public void testTimeShift() {

       EntityManager em = JPAUtil.createEntityManager();


       TimeStep timeStep = new TimeStep();
       LocalDateTime.now(Clock.systemUTC());
       LocalDateTime ldt = LocalDateTime.parse("2030-03-31T02:00:00");
       timeStep.setTimeStamp(ldt);

       SaveToDB.(timeStep, em);

       em.close();

       EntityManager em2 = JPAUtil.createEntityManager();

       TimeStep timeStep2 = LoadFromDB.getTimeStep(ldt, em2);

       if (timeStep.getTimeStamp() != timeStep2.getTimeStamp()) {
           System.out.println(timeStep.getTimeStamp());
           System.out.println(timeStep2.getTimeStamp());
           throw new EmptyStackException();
       }
   }

This code returns the following: 此代码返回以下内容:

2030-03-31T02:00
2030-03-31T03:00

Process finished with exit code -1

The Answer is to set the type for the timestamp to ZonedTimeData. 答案是将时间戳的类型设置为ZonedTimeData。 This can be parsed from and to LocalDateTime for convenience. 为方便起见,可以从LocalDateTime解析这个问题。 That way, the test works. 这样,测试工作。

So, in contrast to what is recommended, for a timestep without timezone use: 因此,与推荐的相比,对于没有时区使用的时间步长:

@Entity
@Table(name = "`TimeStep`")
public class TimeStep {

   @Column(name = "`TimeStamp`")
   private ZonedDateTime TimeStamp;
}

Creating timesteps ist then done via 然后通过创建时间步长

LocalDateTime.now(Clock.systemUTC());
LocalDateTime ldt = LocalDateTime.parse("2030-03-31T02:00:00");

ZonedDateTime zonedDateTime = ZonedDateTime.of(ldt, ZoneId.of("UTC"));
timeStep.setTimeStamp(zonedDateTime);

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

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