Niewłaściwy typ
LocalDateTime
jest tutaj zły typ. Ta klasa nie może reprezentować chwili, jak wyjaśniono w dokumentacji Javadoc.
Ta klasa celowo nie ma pojęcia o strefie czasowej ani o przesunięciu względem UTC. Przedstawia więc datę i porę dnia, taką jak „południe 23 stycznia 2019 r.”, ale nie wiem, czy jest to południe w Tokio, Paryżu czy Montrealu, na przykład trzy bardzo różne momenty, które dzieli kilka godzin. Więc ten typ jest odpowiedni dla standardowego typu SQL TIMESTAMP WITHOUT TIME ZONE
– bez , a nie z .
Aby uzyskać więcej informacji, zobacz:Jaka jest różnica między funkcją Instant a LocalDateTime?
Właściwy typ
Dla standardowego typu SQL TIMESTAMP WITH TIME ZONE
, powinieneś używać typów Java Instant
, OffsetDateTime
lub ZonedDateTime
. Spośród tych trzech, JDBC 4.2 wymaga wsparcia tylko dla drugiego, OffsetDateTime
.
Wyszukiwanie.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Wartość pobrana z Postgresa zawsze będzie w UTC. Standard SQL nie określa tego zachowania, więc bazy danych są różne. W Postgresie dowolna wartość wysyłana do pola typu TIMESTAMP WITH TIME ZONE
jest dostosowany do czasu UTC. Pobrane wartości są w UTC.
Przechowywanie.
myPreparedStatement.setObject( … , odt ) ;
Dostosuj od UTC (przesunięcie od zera) do czasu zegara ściennego używanego przez ludzi z określonego regionu (strefy czasowej).
ZoneId z = ZoneId.of( "Asia/Tokyo" ;
ZonedDateTime zdt = odt.atZoneSameInstant( z ) ;
JPA
Nie używam JPA, wolę zachować prostotę.
Ale według tej odpowiedzi , JPA 2.2 obsługuje java.time typy.
Hibernacja również obsługuje java.time .