tl; dr
String sql = "SELECT CURRENT_TIMESTAMP ;
…
OffsetDateTime odt = myResultSet.getObject( 1 , OffsetDateTime.class ) ;
Unikaj zależności od systemu operacyjnego hosta lub maszyny JVM dla domyślnej strefy czasowej
Zalecam napisanie całego kodu w celu jawnego określenia żądanej / oczekiwanej strefy czasowej. Nie musisz polegać na bieżącej domyślnej strefie czasowej maszyny JVM. Należy również pamiętać, że bieżąca domyślna strefa czasowa maszyny JVM może ulec zmianie w dowolnym momencie podczas działania, z dowolnym kodem w dowolnym wątku wywołania dowolnej aplikacji TimeZone.setDefault
. Takie wywołanie ma natychmiastowy wpływ na wszystkie aplikacje w tej maszynie JVM.
java.time
Niektóre z pozostałych odpowiedzi były poprawne, ale obecnie są przestarzałe. Okropne klasy data-czas dołączone do najwcześniejszych wersji Javy były błędne, napisane przez ludzi, którzy nie rozumieli złożoności i subtelności obsługi daty i godziny.
Starsze klasy daty i godziny zostały zastąpione przez klasy java.time zdefiniowane w JSR 310.
Aby przedstawić strefę czasową, użyj ZoneId
. Aby przedstawić przesunięcie od czasu UTC, użyj ZoneOffset
. Przesunięcie to zaledwie kilka godzin-minut-sekund przed lub za głównym południkiem. Strefa czasowa to znacznie więcej. Strefa czasowa to historia przeszłych, obecnych i przyszłych zmian offsetu używanego przez mieszkańców określonego regionu.
Muszę wymusić wszystkie operacje związane z czasem na GMT / UTC
Aby uzyskać przesunięcie równe zero godzin-minut-sekund, użyj stałej ZoneOffset.UTC
.
Instant
Aby uchwycić aktualny moment w UTC, użyj pliku Instant
. Ta klasa reprezentuje moment w UTC, z definicji zawsze w UTC.
Instant instant = Instant.now() ;
ZonedDateTime
Aby zobaczyć ten sam moment przez zegar ścienny używany przez mieszkańców danego regionu, dostosuj się do strefy czasowej. Ten sam moment, ten sam punkt na osi czasu, inny zegar ścienny.
ZoneId z = ZoneId.of( "Asia/Tokyo" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Baza danych
Wspominasz o bazie danych.
Aby pobrać moment z bazy danych, twoja kolumna powinna być typu danych zbliżonego do standardu SQL TIMESTAMP WITH TIME ZONE
. Pobierz obiekt, a nie ciąg. W JDBC 4.2 i nowszych możemy wymieniać obiekty java.time z bazą danych. OffsetDateTime
Jest wymagane przez JDBC, podczas Instant
i ZonedDateTime
są opcjonalne.
OffsetDateTime odt = myResultSet.getObject( … , OffsetDateTime.class ) ;
Sądzę, że w większości baz danych i sterowników uzyskasz moment taki jak w UTC. Ale jeśli nie, możesz to zmienić na dwa sposoby:
- Wyodrębnij
Instant
: odt.toInstant()
- Dostosuj od podanego przesunięcia do przesunięcia zerowego: OffsetDateTime odtUtc = odt.withOffsetSameInstant (ZoneOffset.UTC); `.
Informacje o java.time
Struktura java.time jest wbudowana w Javę 8 i nowsze. Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak java.util.Date
, Calendar
, i SimpleDateFormat
.
Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj Stack Overflow, aby znaleźć wiele przykładów i wyjaśnień. Specyfikacja to JSR 310 .
Projekt Joda-Time , obecnie w trybie konserwacji , zaleca migrację do klas java.time .
Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie ma potrzeby stosowania ciągów ani java.sql.*
klas.
Skąd wziąć klasy java.time?