Utrata strefy czasowe po podbiciu javy i springa

1

Mam converter w którym robię instant.toEpochMilli() i w sumie dostawałem dobry czas w mojej strefie aż do momentu gdy podbiłem jave do 21 springa do 6.1.2 a springboota do 3.2.1 i od tego momentu już dostaje o 1h do przodu, why?

1

Jeżeli Java działa w kontenerze to coś mi w głowie świta że był taki problem. Po prostu ustaw to jawnie i będzie po kłopocie: https://www.baeldung.com/java-jvm-time-zone

0
0xmarcin napisał(a):

Jeżeli Java działa w kontenerze to coś mi w głowie świta że był taki problem. Po prostu ustaw to jawnie i będzie po kłopocie: https://www.baeldung.com/java-jvm-time-zone

Chcę po prostu aby data z bazy była taka sama jak z mojego API (w bazie chyba mam dobrą strefę bo jak robię select now() to zwraca aktualną datę)
Próbowałem już z -Duser.timezone="Europe/Warsaw", nawet dodałem dodatkowo TimeZone.setDefault(TimeZone.getTimeZone("Europe/Warsaw"));
a i tak po podbiciu javy do 21 i springa mam po instant.toEpochMilli() o 1h do przodu

0

Możliwe, że konwersja zachodzi między time zone serwera bazodanowego oraz klientem (sterownikiem JDBC). Bazy TZ są od czasu do czasu aktualizowane, może trafiłęś w taką aktualizację.

a) na której wersji było ok?
b) jaka baza? jaka tz ustawiona na bazie?
c) jaki sterownik bazodanowy? (wersja)
d) jakie masz locale ustawione na maszynie, z której uruchamiasz jvm'a
e) czy używasz tej samej bazy do reprodukcji problemu (między java21 a javaXYZ? )

0
yarel napisał(a):

Możliwe, że konwersja zachodzi między time zone serwera bazodanowego oraz klientem (sterownikiem JDBC). Bazy TZ są od czasu do czasu aktualizowane, może trafiłęś w taką aktualizację.

a) na której wersji było ok?
b) jaka baza? jaka tz ustawiona na bazie?
c) jaki sterownik bazodanowy? (wersja)
d) jakie masz locale ustawione na maszynie, z której uruchamiasz jvm'a
e) czy używasz tej samej bazy do reprodukcji problemu (między java21 a javaXYZ? )

korzystam z jdbc, hibernate (org.hibernate.orm.hibernate-core:6.4.4.Final), gdy na mysql robię select now() to mam aktualną datę. Wszędzie w apce mam "Europe/Warsaw". na java 18 było OK a na 21 się pomieszało, baza podpięta cały czas ta sama

0

Z dokumentacji:

The java.time.Instant.toEpochMilli() method converts this instant to the number of milliseconds from the epoch of 1970-01-01T0000Z.

Jeżeli korzystasz ze Swagger/OpenAPI sprawdź jaki tam typ jest użyty, może biblioteka lub JSON serializer jest ustwaiony tak żeby zwracać w UTC?

0
0xmarcin napisał(a):

Z dokumentacji:

The java.time.Instant.toEpochMilli() method converts this instant to the number of milliseconds from the epoch of 1970-01-01T0000Z.

Jeżeli korzystasz ze Swagger/OpenAPI sprawdź jaki tam typ jest użyty, może biblioteka lub JSON serializer jest ustwaiony tak żeby zwracać w UTC?

nie używam żadnych swaggerów.
Jak napisałem w komentarzu wyżej:
przed podbiciem, czyli java 18

Instant i = getDateFromDB();
System.out.println(i); //zwraca 2024-02-19T08:00:10Z
System.out.println(i.toEpochMilli()); //zwraca 1708329610000

po podbiciu, czyli java 21:

Instant i = getDateFromDB();
System.out.println(i); //zwraca 2024-02-19T09:00:10Z
System.out.println(i.toEpochMilli()); //zwraca 1708333210000
2

Wygląda na problem generowany przez sterownik JDBC.

Moja hipoteza robocza:
a) podbicie wersji springa i springboota skutkuje podbiciem wersji sterownika JDBC do wersji 8.3.0 (https://docs.spring.io/spring-boot/docs/current/reference/html/dependency-versions.html)
b) Twoje obecna konfiguracja połączenia do bazy danych (którą się nie pochwaliłeś w tym wątku), może operować na właściwościach, które w wersji 8+ zostały usunięte ( https://dev.mysql.com/doc/connectors/en/connector-j-upgrading-to-8.0.html)

Wersja 8+ jedzie na ustawieniach domyślnych i robi jakąś konwersję z time zone bazy do domyślnej time zony sterownika.

0

A jak jest zapisana data w bazie? Tzn. jaki typ i jaka wartość?

0
wartek01 napisał(a):

A jak jest zapisana data w bazie? Tzn. jaki typ i jaka wartość?

typ to datetime a wartość to 2024-02-19 09:00:10
I teraz jak uzyskać tą samą datę w zwrotce api przy java 21 i najnowszym springu?

0

Nie masz problemu z Instant.toEpochMilli() tylko z tym jak JDBC / cokolwiek w środku tego getDateFromDB() interpretuje datę z bazy i tworzy z tego Instant. Sterownik JDBC, ustawienie połączenia z bazą, czy jakiś kod którego nam tu nie pokazałeś.

I teraz jak uzyskać tą samą datę w zwrotce api przy java 21 i najnowszym springu?

Co to za baza, MySQL? Jak ustawiasz połączenie do bazy, może możesz tam też ustawić timezone? Czy z podbiciem javy do 21 zmieniła ci się wersja JDBC? Co jest w środku tego getDateFromDB()?

W ogóle to trzymanie czasu w bazie w lokalnej strefie czasowej, gdzie informacja jaka to strefa czasowa wynika jedynie z ustawienia strefy czasowej serwera to kiepski pomysł. I ja się nie dziwię, że jeden rabin ("Java 18") odczyta tak, a drugi rabin ("Java 21") odczyta inaczej. Lepiej trzymać to jako UTC albo jakiś typ z informacją o strefie czasowej. Ale to dygresja.

0

spróbuj ustawić na twoją strefę tego propertiesa: spring.jpa.properties.hibernate.jdbc.time_zone=UTC (podmień UTC)

1 użytkowników online, w tym zalogowanych: 0, gości: 1