Грешен тип
LocalDateTime
е грешен тип тук. Този клас не може да представлява момент, както е обяснено в неговия Javadoc.
Този клас нарочно няма концепция за часова зона или отместване спрямо UTC. Така че представлява дата и час от деня, като например „обед на 23 януари 2019 г.“, но не знам дали това е обяд в Токио, Париж или Монреал, например, три много различни момента, които са няколко часа разлика. Така че този тип е подходящ за стандартен SQL тип TIMESTAMP WITHOUT TIME ZONE
– без , а не с .
За повече дискусия вижте:Каква е разликата между Instant и LocalDateTime?
Правилен тип
За стандартен SQL въведете TIMESTAMP WITH TIME ZONE
, трябва да използвате Java типовете Instant
, OffsetDateTime
или ZonedDateTime
. От тези три, JDBC 4.2 изисква поддръжка само за второто, OffsetDateTime
.
Извличане.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Стойността, извлечена от Postgres, винаги ще бъде в UTC. Стандартът SQL не определя това поведение, така че базите данни варират. В Postgres всяка стойност, изпратена до поле от тип TIMESTAMP WITH TIME ZONE
се коригира в UTC. Извлечените стойности са в UTC.
Съхраняване.
myPreparedStatement.setObject( … , odt ) ;
Коригирайте от UTC (отместване на нула) към времето на стенния часовник, използвано от хората в определен регион (часова зона).
ZoneId z = ZoneId.of( "Asia/Tokyo" ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
JPA
Не използвам JPA, предпочитам да опростя нещата.
Но според този отговор , JPA 2.2 поддържа java.time видове.
Hibernate също поддържа java.time .