tl; dr
… Parsowane… z ciągu… strefa czasowa nie jest określona… Chcę ustawić określoną strefę czasową
LocalDateTime.parse( "2018-01-23T01:23:45.123456789" ) // Parse string, lacking an offset-from-UTC and lacking a time zone, as a `LocalDateTime`.
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Assign the time zone for which you are certain this date-time was intended. Instantiates a `ZonedDateTime` object.
Brak strefy czasowej w czerwcu
Jak podają inne poprawne odpowiedzi, java.util.Date nie ma strefy czasowej † . Reprezentuje UTC / GMT (bez przesunięcia strefy czasowej). Bardzo mylące, ponieważ jego toString
metoda stosuje domyślną strefę czasową maszyny JVM podczas generowania reprezentacji typu String.
Unikaj juDate
Z tego i wielu innych powodów należy unikać korzystania z wbudowanego java.util.Date & .Calendar & java.text.SimpleDateFormat. Są notorycznie kłopotliwe.
Zamiast tego użyj pakietu java.time dołączonego do Java 8 .
java.time
Klasy java.time mogą reprezentować moment na osi czasu na trzy sposoby:
- UTC (
Instant
)
- Z przesunięciem (
OffsetDateTime
z ZoneOffset
)
- Ze strefą czasową (
ZonedDateTime
z ZoneId
)
Instant
W java.time podstawowym elementem konstrukcyjnym jest Instant
chwila na linii czasu w UTC. Używaj Instant
obiektów przez większą część logiki biznesowej.
Instant instant = Instant.now();
OffsetDateTime
Zastosuj przesunięcie względem UTC aby dostosować się do czasu zegara ściennego w danej miejscowości .
Złóż ZoneOffset
wniosek, aby uzyskać OffsetDateTime
.
ZoneOffset zoneOffset = ZoneOffset.of( "-04:00" );
OffsetDateTime odt = OffsetDateTime.ofInstant( instant , zoneOffset );
ZonedDateTime
Lepiej jest zastosować strefę czasową , przesunięcie oraz zasady postępowania z anomaliami, takimi jak czas letni (DST) .
Zastosuj ZoneId
do, Instant
aby uzyskać ZonedDateTime
. Zawsze określ prawidłową nazwę strefy czasowej . Nigdy nie używaj 3-4 skrótów, takich jak EST
lub IST
, które nie są ani unikalne, ani standardowe.
ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
LocalDateTime
Jeśli w łańcuchu wejściowym brakowało jakiegokolwiek wskaźnika przesunięcia lub strefy, parsuj jako LocalDateTime
.
Jeśli jesteś pewien planowanej strefy czasowej, przypisz a, ZoneId
aby utworzyć ZonedDateTime
. Zobacz przykładowy kod powyżej w sekcji tl; dr u góry.
Sformatowane ciągi
Wywołaj toString
metodę dowolnej z tych trzech klas, aby wygenerować ciąg znaków reprezentujący wartość daty i godziny w standardowym formacie ISO 8601 . ZonedDateTime
Klasa rozszerza standardowego formatu, dołączając nazwę strefy czasowej w nawiasie.
String outputInstant = instant.toString(); // Ex: 2011-12-03T10:15:30Z
String outputOdt = odt.toString(); // Ex: 2007-12-03T10:15:30+01:00
String outputZdt = zdt.toString(); // Ex: 2007-12-03T10:15:30+01:00[Europe/Paris]
W przypadku innych formatów użyj DateTimeFormatter
klasy. Ogólnie najlepiej, aby pozwolić tej klasie generować zlokalizowane formaty przy użyciu oczekiwanego języka ludzkiego i norm kulturowych. Lub możesz określić konkretny format.
O java.time
Środowisko java.time jest wbudowane w Javę 8 i nowsze wersje . Klasy te kłopotliwe zastąpić stary starszych klas Date-Time, takich jak java.util.Date
, Calendar
, iSimpleDateFormat
.
Projekt Joda-Time , teraz w trybie konserwacji , zaleca migrację do klas java.time .
Aby dowiedzieć się więcej, zobacz samouczek Oracle . I przeszukaj stos przepełnienia dla wielu przykładów i wyjaśnień. Specyfikacja to JSR 310 .
Możesz wymieniać obiekty java.time bezpośrednio ze swoją bazą danych. Użyj sterownika JDBC zgodnego z JDBC 4.2 lub nowszym. Nie potrzeba ciągów, nie ma potrzeby java.sql.*
klas.
Gdzie można uzyskać klasy java.time?
Projekt ThreeTen-Extra rozszerza java.time o dodatkowe klasy. Ten projekt jest poligonem doświadczalnym dla ewentualnych przyszłych dodatków do java.time. Można znaleźć kilka przydatnych klas tutaj takie jak Interval
, YearWeek
, YearQuarter
, i więcej .
Joda-Time
Chociaż Joda-Time jest nadal aktywnie utrzymywany, jego twórcy powiedzieli nam, abyśmy migrowali do java.time, gdy tylko będzie to wygodne. Zostawiam tę sekcję nietkniętą jako odniesienie, ale sugeruję użyciejava.time
zamiast tego powyższej sekcji.
W Joda-Time obiekt date-time ( DateTime
) naprawdę zna swoją przypisaną strefę czasową. Oznacza to przesunięcie w stosunku do UTC oraz zasad i historii czasu letniego (DST) w tej strefie czasowej i innych tego rodzaju anomalii.
String input = "2014-01-02T03:04:05";
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZone );
DateTime dateTimeUtcGmt = dateTimeIndia.withZone( DateTimeZone.UTC );
Wywołaj toString
metodę, aby wygenerować ciąg znaków w formacie ISO 8601 .
String output = dateTimeIndia.toString();
Joda-Time oferuje również bogate możliwości generowania wszelkiego rodzaju innych formatów String.
W razie potrzeby możesz przekonwertować z Joda-Time DateTime na java.util.Date.
Java.util.Date date = dateTimeIndia.toDate();
Wyszukaj StackOverflow dla „joda date”, aby znaleźć wiele innych przykładów, niektóre dość szczegółowe.
† To właśnie tam znajduje się strefa czas osadzony w java.util.Date, używane do niektórych funkcji wewnętrznych (patrz komentarze na tę odpowiedź). Ale ta wewnętrzna strefa czasowa nie jest ujawniana jako właściwość i nie można jej ustawić. Ta wewnętrzna strefa czasowa nie jest używana przez toString
metodę do generowania ciągu reprezentującego wartość daty i godziny; zamiast tego bieżąca domyślna strefa czasowa JVM jest stosowana w locie. Tak więc, jak stenografia, często mówimy „juDate nie ma strefy czasowej”. Mylące? Tak. To kolejny powód, aby unikać tych zmęczonych starych klas.