O ile mogę powiedzieć istnieją dwa błędy tutaj. Oba są (jeśli mam rację) w klasie java.util.Date
, nadklasa java.sql.Timestamp
.
Po pierwsze, nie ma przesunięcia czasowego w Warszawie w roku 1900. Najwcześniejsze przejście, o którym wie moja Java 8, nastąpiło w 1915 roku. Więc Warszawa była przesunięta o 1:24 od GMT przez cały czas z.
Próbowałem:
TimeZone.setDefault(TimeZone.getTimeZone("Europe/Warsaw"));
ZoneOffset offset0124 = ZoneOffset.ofHoursMinutes(1, 24);
System.out.println("" + new Date(0, 0, 1, 0, 59)
+ " -> " + new Date(0, 0, 1, 0, 59).toInstant().atOffset(offset0124));
System.out.println("" + new Date(0, 0, 1, 1, 14)
+ " -> " + new Date(0, 0, 1, 1, 14).toInstant().atOffset(offset0124));
System.out.println("" + new Date(0, 0, 1, 1, 24)
+ " -> " + new Date(0, 0, 1, 1, 24).toInstant().atOffset(offset0124));
Drukuje:
Mon Jan 01 00:59:00 CET 1900 -> 1900-01-01T01:23+01:24
Mon Jan 01 01:38:00 CET 1900 -> 1900-01-01T01:38+01:24
Mon Jan 01 01:24:00 CET 1900 -> 1900-01-01T01:24+01:24
metody Timestamp.valueOf
Metoda używana pośrednio korzysta z przestarzałej Date
konstruktora, tak więc jestem (nie dokładnie taki sam konstruktor, ja używam tego bez sekund, ufając, że nie robi różnicy). będę komentować powyższych trzech przypadkach zacofanych:
- 1:24 jest obsługiwane prawidłowo, mamy czas oczekiwany zarówno z
Date.toString()
i od OffsetDateTime
.
- 1:14 jest postrzegany jako 1:38, 24 minuty później. To dla mnie wygląda jak błąd.
- 0:59 jest postrzegana jako 1:23, także 24 minuty później. Możemy to zobaczyć z
OffsetDateTime
. Ten sam błąd. Jednak Date.toString()
produkuje 00:59 zgodnie z oczekiwaniami. To wydaje mi się być drugim błędem, który w jakiś sposób rekompensuje pierwszy. Nie sprawdziłem, ale podejrzewam, że źródło tego błędu powoduje również nieprawidłowe zachowanie się.
Jako czek obliczyłem różnicę między waszymi obiektami Timestamp
z 0:59 i 1:24. Pożądany wynik to 25 minut lub 1 500 000 milisekund.Kod jest:
System.out.println(java.sql.Timestamp.valueOf("1900-01-01 01:24:00").getTime()
- java.sql.Timestamp.valueOf("1900-01-01 00:59:00").getTime());
Drukuje
60000
60 sekund, tak jak 1 minutę. Mimo że oba te znaczniki czasu wydrukowały się tak, jak się spodziewaliśmy, nadal istnieje błąd.
Jakie jest Twoje miejsce zamieszkania? Przechodząc tylko przez Java 8, bez Scala, nie mogę odtworzyć tego w moim locale (en_US). – rgettman
@rgettman 'ZoneId.systemDefault' zwraca' Europe/Warsaw' –
Powieliłem problem za pomocą 'System.setProperty (" user.timezone "," Europe/Warsaw ");' ... wygląda jak błąd dla mnie, i w przeszłości występowały błędy strefy czasowej. Przechodząc przez kod biblioteki wygląda na to, że może zaistnieć fałszywe przejście w bazie danych zoneinfo dla tego okresu. Potrzeba trochę pracy, aby to zweryfikować, i niestety nie mam teraz czasu. –