Tl;dr
Wie in einem Kommentar erwähnt, haben Sie die Verwendung eines Locale
Objekts mit der Angabe einer Zeitzone verwechselt. Ein Locale hat überhaupt nichts mit einer Zeitzone zu tun, und ein Locale beeinflusst nicht die Bedeutung des Datum-Zeit-Werts. Ein Locale beeinflusst nur das Formatieren eines String, der zur Darstellung des Datum-Zeit-Werts verwendet wird.
Kein Locale erforderlich, wenn Sie den aktuellen Moment erfassen. Aber wir brauchen eine Zeitzone.
Instant.now().atZone( ZoneId.of( "America/Montreal" ) )
…oder kurze Version…
ZonedDateTime.now( ZoneId.of( "America/Montreal" ) )
java.time
Sie verwenden problematische alte Legacy-Datum-Zeit-Klassen, die jetzt durch die java.time-Klassen ersetzt wurden.
In UTC arbeiten
Ein Großteil Ihrer Geschäftslogik, Datenablage und Datenaustausch sollte in UTC erfolgen. Denken Sie an UTC als „die eine wahre Zeit“.
Die Instant
Klasse stellt einen Zeitpunkt auf der Zeitleiste in UTC mit einer Genauigkeit von Nanosekunden dar.
Instant instant = Instant.now();
Zeitzone angeben
Wie Sie herausgefunden haben, sollten Sie immer die gewünschte/erwartete Zeitzone angeben. Für jeden Moment variieren das Datum und die Tageszeit auf der Welt je nach Zeitzone.
Geben Sie einen richtigen Zeitzonennamen im Format Kontinent/Region
an. Verwenden Sie niemals die 3- oder 4-Buchstaben-Abkürzung wie EST
oder IST
, da sie keine echten Zeitzonen sind, nicht standardisiert und nicht einmal eindeutig(!).
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = instant.atZone( z );
Locale angeben
Beachten Sie, dass Zeitzone und Locale eigenständige, völlig separate Themen sind.
- Die Zeitzone bestimmt die Bedeutung des Datum-Zeit-Werts, wie wir seine Wanduhrzeit betrachten.
- Das Locale bestimmt (a) die menschliche Sprache für die Übersetzung von Namen des Tages, Namen des Monats und dergleichen und (b) die kulturellen Normen, die Fragen der Abkürzung, Großschreibung, Interpunktion und ähnliches entscheiden.
Dies bedeutet, dass wir jede Zeitzone mit jedem Locale mischen können. Wir können eine Datum-Zeit in der Zone Europe/Paris
mit einem Locale von Locale.KOREA
haben. Oder eine Zone von Pacific/Auckland
mit Locale.CANADA_FRENCH
.
Daher wirkt sich Locale nur auf die Darstellung des Datum-Zeit-Werts aus, wie wir eine String-Repräsentation des Datum-Zeit-Werts generieren.
Sie können ein benutzerdefiniertes Formatierungsmuster für die Generierung von Zeichenfolgen angeben. Es ist jedoch besser, java.time automatisch zu lokalisieren.
Locale l = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL )
.withLocale( l );
String output = zdt.format( f );
Über java.time
Das java.time Framework ist in Java 8 und später integriert. Diese Klassen ersetzen die problematischen alten Legacy Datum-Zeit-Klassen wie java.util.Date
, Calendar
& SimpleDateFormat
.
Das Joda-Time Projekt, das jetzt im Wartungsmodus ist, empfiehlt die Migration zu den java.time Klassen.
Weitere Informationen finden Sie im Oracle Tutorial. Und suchen Sie auf Stack Overflow nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310.
Wo erhalten Sie die java.time Klassen?
- Java SE 8, Java SE 9 und später
- Integriert.
- Bestandteil der standardmäßigen Java-API mit einer gebündelten Implementierung.
- Java 9 fügt einige kleinere Funktionen und Korrekturen hinzu.
- Java SE 6 und Java SE 7
- Viele der java.time-Funktionen sind in Java 6 & 7 mit ThreeTen-Backport zurückportiert.
- Android
- Spätere Versionen von Android enthalten Implementierungen der java.time Klassen.
- Für frühere Android-Versionen passt sich das ThreeTenABP Projekt an ThreeTen-Backport an (oben erwähnt). Siehe Wie man ThreeTenABP benutzt….
Das ThreeTen-Extra Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testgelände für mögliche zukünftige Ergänzungen zu java.time. Hier finden Sie einige nützliche Klassen wie Interval
, YearWeek
, YearQuarter
und mehr.