Java-Klasse ZonedDateTime
ZonedDateTime ist eine wichtige Klasse in der mit Java 8 eingeführten Datum-Zeit-API (Paket java.time); sie repräsentiert ein Datum und eine Uhrzeit mit Zeitzone. Diese Klasse kombiniert LocalDateTime und ZoneId, um einen Zeitpunkt in einer bestimmten Zeitzone präzise darzustellen.
Hauptfunktionen
- Enthält das Datum (Jahr, Monat, Tag)
- Enthält die Uhrzeit (Stunde, Minute, Sekunde, Nanosekunde)
- Enthält Zeitzoneninformationen
- Ist eine unveränderliche und threadsichere Klasse
- Unterstützt Zeitzonenumrechnung und automatische Anpassung an die Sommerzeit
Möglichkeiten zum Erstellen von ZonedDateTime
1. Erstellen mit der aktuellen Zeit
Beispiel
// Aktuelles Datum und aktuelle Uhrzeit in der Standardzeitzone des Systems abrufen
ZonedDateTime now = ZonedDateTime.now();
// Aktuelles Datum und aktuelle Uhrzeit in der angegebenen Zeitzone abrufen
ZonedDateTime nowInTokyo = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
ZonedDateTime now = ZonedDateTime.now();
// Aktuelles Datum und aktuelle Uhrzeit in der angegebenen Zeitzone abrufen
ZonedDateTime nowInTokyo = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
2. Erstellen aus Komponenten
Beispiel
// Jahr, Monat, Tag, Stunde, Minute, Sekunde und Zeitzone angeben
ZonedDateTime customDateTime = ZonedDateTime.of(
2023, 12, 25, 15, 30, 0, 0,
ZoneId.of("America/New_York")
);
ZonedDateTime customDateTime = ZonedDateTime.of(
2023, 12, 25, 15, 30, 0, 0,
ZoneId.of("America/New_York")
);
3. Kombinieren von LocalDateTime und ZoneId
Beispiel
LocalDateTime localDateTime = LocalDateTime.of(2023, 6, 15, 10, 30);
ZoneId zoneId = ZoneId.of("Europe/Paris");
ZonedDateTime parisTime = ZonedDateTime.of(localDateTime, zoneId);
ZoneId zoneId = ZoneId.of("Europe/Paris");
ZonedDateTime parisTime = ZonedDateTime.of(localDateTime, zoneId);
Häufige Operationsmethoden
1. Zeitinformationen abrufen
Beispiel
ZonedDateTime zdt = ZonedDateTime.now();
int year = zdt.getYear(); // Jahr
Month month = zdt.getMonth(); // Monat
int day = zdt.getDayOfMonth(); // Tag
int hour = zdt.getHour(); // Stunde
int minute = zdt.getMinute(); // Minute
int second = zdt.getSecond(); // Sekunde
ZoneId zone = zdt.getZone(); // Zeitzone
int year = zdt.getYear(); // Jahr
Month month = zdt.getMonth(); // Monat
int day = zdt.getDayOfMonth(); // Tag
int hour = zdt.getHour(); // Stunde
int minute = zdt.getMinute(); // Minute
int second = zdt.getSecond(); // Sekunde
ZoneId zone = zdt.getZone(); // Zeitzone
2. Addieren und Subtrahieren von Zeit
Beispiel
ZonedDateTime zdt = ZonedDateTime.now();
// 1 Tag hinzufügen
ZonedDateTime tomorrow = zdt.plusDays(1);
// 2 Stunden abziehen
ZonedDateTime twoHoursEarlier = zdt.minusHours(2);
// 3 Wochen hinzufügen
ZonedDateTime threeWeeksLater = zdt.plusWeeks(3);
// 1 Tag hinzufügen
ZonedDateTime tomorrow = zdt.plusDays(1);
// 2 Stunden abziehen
ZonedDateTime twoHoursEarlier = zdt.minusHours(2);
// 3 Wochen hinzufügen
ZonedDateTime threeWeeksLater = zdt.plusWeeks(3);
3. Zeitzonenumwandlung
Beispiel
ZonedDateTime tokyoTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
// In New-York-Zeit umwandeln
ZonedDateTime newYorkTime = tokyoTime.withZoneSameInstant(ZoneId.of("America/New_York"));
// In UTC-Zeit umwandeln
ZonedDateTime utcTime = tokyoTime.withZoneSameInstant(ZoneOffset.UTC);
// In New-York-Zeit umwandeln
ZonedDateTime newYorkTime = tokyoTime.withZoneSameInstant(ZoneId.of("America/New_York"));
// In UTC-Zeit umwandeln
ZonedDateTime utcTime = tokyoTime.withZoneSameInstant(ZoneOffset.UTC);
Praktische Anwendungsbeispiele
1. Berechnung der Zeitdifferenz zwischen zwei Zeitzonen
Beispiel
ZonedDateTime londonTime = ZonedDateTime.now(ZoneId.of("Europe/London"));
ZonedDateTime sydneyTime = ZonedDateTime.now(ZoneId.of("Australia/Sydney"));
// Berechne die Stundendifferenz
long hoursBetween = ChronoUnit.HOURS.between(londonTime, sydneyTime);
System.out.println("Aktuelle Zeitdifferenz zwischen London und Sydney: " + hoursBetween + "hours");
ZonedDateTime sydneyTime = ZonedDateTime.now(ZoneId.of("Australia/Sydney"));
// Berechne die Stundendifferenz
long hoursBetween = ChronoUnit.HOURS.between(londonTime, sydneyTime);
System.out.println("Aktuelle Zeitdifferenz zwischen London und Sydney: " + hoursBetween + "hours");
2. Umgang mit Besprechungszeiten über Zeitzonen hinweg
Beispiel
// Die Besprechungszeit in New York ist 3 PM
ZonedDateTime meetingTimeNY = ZonedDateTime.of(
LocalDate.now(),
LocalTime.of(15, 0),
ZoneId.of("America/New_York")
);
// In Tokio-Zeit umwandeln
ZonedDateTime meetingTimeTokyo = meetingTimeNY.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
System.out.println("Teilnehmer in Tokio sollten dort zur Ortszeit anwesend sein: " + meetingTimeTokyo);
ZonedDateTime meetingTimeNY = ZonedDateTime.of(
LocalDate.now(),
LocalTime.of(15, 0),
ZoneId.of("America/New_York")
);
// In Tokio-Zeit umwandeln
ZonedDateTime meetingTimeTokyo = meetingTimeNY.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
System.out.println("Teilnehmer in Tokio sollten dort zur Ortszeit anwesend sein: " + meetingTimeTokyo);
3. Umgang mit Sommerzeit
Beispiel
// Zeiten vor und nach der Sommerzeitumstellung in New York
ZonedDateTime beforeDST = ZonedDateTime.of(
LocalDateTime.of(2023, 3, 11, 1, 30),
ZoneId.of("America/New_York")
);
ZonedDateTime afterDST = beforeDST.plusHours(1);
System.out.println("Tatsächliche Zeitdifferenz: " +
Duration.between(beforeDST, afterDST).toHours() + "Stunden");
ZonedDateTime beforeDST = ZonedDateTime.of(
LocalDateTime.of(2023, 3, 11, 1, 30),
ZoneId.of("America/New_York")
);
ZonedDateTime afterDST = beforeDST.plusHours(1);
System.out.println("Tatsächliche Zeitdifferenz: " +
Duration.between(beforeDST, afterDST).toHours() + "Stunden");
Konvertieren von ZonedDateTime und anderen Datums-/Zeitklassen
1. Umwandlung in Instant
Beispiel
ZonedDateTime zdt = ZonedDateTime.now();
Instant instant = zdt.toInstant(); // In UTC-Zeitstempel umwandeln
Instant instant = zdt.toInstant(); // In UTC-Zeitstempel umwandeln
2. Umwandlung in LocalDateTime
Beispiel
ZonedDateTime zdt = ZonedDateTime.now();
LocalDateTime ldt = zdt.toLocalDateTime(); // Verliert Zeitzoneninformationen
LocalDateTime ldt = zdt.toLocalDateTime(); // Verliert Zeitzoneninformationen
3. Erstellen aus Instant
Beispiel
Instant instant = Instant.now();
ZonedDateTime zdt = instant.atZone(ZoneId.of("Asia/Shanghai"));
ZonedDateTime zdt = instant.atZone(ZoneId.of("Asia/Shanghai"));
Umfassendes Beispiel
Beispiel
import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class ZonedDateTimeDemo {
public static void main(String[] args) {
// 1. Aktuelle Zeit in der aktuellen Zeitzone abrufen
ZonedDateTime now = ZonedDateTime.now();
System.out.println("Aktuelle Zeitzonenzeit: " + now);
// 2. Aktuelle Zeit in der angegebenen Zeitzone abrufen
ZonedDateTime tokyoTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println("Tokio-Zeit: " + tokyoTime);
// 3. Ein bestimmtes Datum/Uhrzeit mit Zeitzone erstellen
ZonedDateTime specificTime = ZonedDateTime.of(
2023, 5, 15, 10, 30, 0, 0,
ZoneId.of("America/New_York")
);
System.out.println("Bestimmte Zeit in New York: " + specificTime);
// 4. Zeitzonenumwandlung
ZonedDateTime londonTime = specificTime.withZoneSameInstant(ZoneId.of("Europe/London"));
System.out.println("Entsprechende Londoner Zeit: " + londonTime);
// 5. Ausgabe formatieren
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
System.out.println("Formatierte Zeit: " + now.format(formatter));
// 6. Informationen für jede Komponente abrufen
System.out.println("Zeitzone: " + now.getZone());
System.out.println("Jahr: " + now.getYear());
System.out.println("Monat: " + now.getMonth());
System.out.println("Stunde: " + now.getHour());
}
}
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class ZonedDateTimeDemo {
public static void main(String[] args) {
// 1. Aktuelle Zeit in der aktuellen Zeitzone abrufen
ZonedDateTime now = ZonedDateTime.now();
System.out.println("Aktuelle Zeitzonenzeit: " + now);
// 2. Aktuelle Zeit in der angegebenen Zeitzone abrufen
ZonedDateTime tokyoTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
System.out.println("Tokio-Zeit: " + tokyoTime);
// 3. Ein bestimmtes Datum/Uhrzeit mit Zeitzone erstellen
ZonedDateTime specificTime = ZonedDateTime.of(
2023, 5, 15, 10, 30, 0, 0,
ZoneId.of("America/New_York")
);
System.out.println("Bestimmte Zeit in New York: " + specificTime);
// 4. Zeitzonenumwandlung
ZonedDateTime londonTime = specificTime.withZoneSameInstant(ZoneId.of("Europe/London"));
System.out.println("Entsprechende Londoner Zeit: " + londonTime);
// 5. Ausgabe formatieren
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss z");
System.out.println("Formatierte Zeit: " + now.format(formatter));
// 6. Informationen für jede Komponente abrufen
System.out.println("Zeitzone: " + now.getZone());
System.out.println("Jahr: " + now.getYear());
System.out.println("Monat: " + now.getMonth());
System.out.println("Stunde: " + now.getHour());
}
}
Die Ausgabe ähnelt der folgenden:
当前时区时间: 2025-05-01T11:29:07.411467+08:00[Asia/Shanghai] 东京时间: 2025-05-01T12:29:07.417938+09:00[Asia/Tokyo] 纽约特定时间: 2023-05-15T10:30-04:00[America/New_York] 对应的伦敦时间: 2023-05-15T15:30+01:00[Europe/London] 格式化时间: 2025-05-01 11:29:07 CST 时区: Asia/Shanghai 年份: 2025 月份: MAY 小时: 11
Best Practices
- Speicherung und Übertragung: Beim Speichern in einer Datenbank oder bei der Übertragung über ein Netzwerk wird empfohlen, Instant oder ZonedDateTime in UTC-Zeit zu verwenden.
- Anzeige: Konvertieren Sie nur bei der Anzeige in der Benutzeroberfläche in die lokale Zeitzone.
- Vergleich: Wenn Sie Zeiten in verschiedenen Zeitzonen vergleichen, konvertieren Sie sie zuerst in dieselbe Zeitzone oder in Instant.
- Sommerzeit: Verwenden Sie immer die vollständige Zeitzonen-ID (z. B. "America/New_York") anstelle eines einfachen Offsets (z. B. "-05:00").
ZonedDateTime ist ein leistungsstarkes Werkzeug für die Handhabung zeitzonenempfindlicher Anwendungen; bei korrekter Verwendung können viele häufige Datums-/Uhrzeitprobleme vermieden werden.
Statische Factory-Methoden
| Methode | Beschreibung | Beispiel |
|---|---|---|
static ZonedDateTime now() |
Aktuelles Datum und Uhrzeit in der aktuellen Zeitzone abrufen | ZonedDateTime.now() |
static ZonedDateTime now(ZoneId zone) |
Aktuelles Datum und Uhrzeit in der angegebenen Zeitzone abrufen | ZonedDateTime.now(ZoneId.of("Asia/Shanghai")) |
static ZonedDateTime of(int year, int month, int day, int hour, int minute, int second, int nano, ZoneId zone) |
Mit angegebenen Parametern erstellen | ZonedDateTime.of(2023, 6, 15, 14, 30, 0, 0, ZoneId.of("GMT+8")) |
static ZonedDateTime of(LocalDate date, LocalTime time, ZoneId zone) |
Durch Kombinieren von LocalDate, LocalTime und Zeitzone erstellen | ZonedDateTime.of(LocalDate.now(), LocalTime.now(), ZoneId.systemDefault()) |
static ZonedDateTime of(LocalDateTime localDateTime, ZoneId zone) |
Aus LocalDateTime und Zeitzone erstellen | ZonedDateTime.of(LocalDateTime.now(), ZoneId.of("America/New_York")) |
static ZonedDateTime ofInstant(Instant instant, ZoneId zone) |
Aus Instant und Zeitzone erstellen | ZonedDateTime.ofInstant(Instant.now(), ZoneId.of("UTC")) |
static ZonedDateTime parse(CharSequence text) |
Aus einer Zeichenfolge parsen | ZonedDateTime.parse("2023-06-15T14:30:45+08:00[Asia/Shanghai]") |
static ZonedDateTime parse(CharSequence text, DateTimeFormatter formatter) |
Mit einem angegebenen Format parsen | ZonedDateTime.parse("2023-06-15 14:30 CST", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm z")) |
Datum-Uhrzeit-Informationen abrufen
| Methode | Beschreibung | Beispiel |
|---|---|---|
int getYear() |
Jahr abrufen | 2023 |
Month getMonth() |
Monat abrufen (Month enum) | Month.JUNE |
int getMonthValue() |
Monatswert abrufen (1-12) | 6 |
int getDayOfMonth() |
Tag des Monats abrufen | 15 |
int getDayOfYear() |
Tag des Jahres abrufen | 166 |
DayOfWeek getDayOfWeek() |
Wochentag abrufen (DayOfWeek enum) | DayOfWeek.THURSDAY |
int getHour() |
Die Stunde abrufen (0-23) | 14 |
int getMinute() |
Die Minute abrufen (0-59) | 30 |
int getSecond() |
Die Sekunde abrufen (0-59) | 45 |
int getNano() |
Die Nanosekunde abrufen | 0 |
ZoneId getZone() |
Die Zeitzone abrufen | Asia/Shanghai |
ZoneOffset getOffset() |
Den Zeitzonenversatz abrufen | +08:00 |
Datum-Uhrzeit-Operationen
| Methode | Beschreibung | Beispiel |
|---|---|---|
ZonedDateTime plusDays(long days) |
Tage hinzufügen | zdt.plusDays(5) |
ZonedDateTime plusHours(long hours) |
Stunden hinzufügen | zdt.plusHours(2) |
ZonedDateTime plusMinutes(long minutes) |
Minuten hinzufügen | zdt.plusMinutes(30) |
ZonedDateTime plusSeconds(long seconds) |
Sekunden hinzufügen | zdt.plusSeconds(45) |
ZonedDateTime plusNanos(long nanos) |
Nanosekunden hinzufügen | zdt.plusNanos(1000000) |
ZonedDateTime minusDays(long days) |
Tage subtrahieren | zdt.minusDays(5) |
ZonedDateTime minusHours(long hours) |
Stunden subtrahieren | zdt.minusHours(2) |
ZonedDateTime minusMinutes(long minutes) |
Minuten subtrahieren | zdt.minusMinutes(30) |
ZonedDateTime minusSeconds(long seconds) |
Sekunden subtrahieren | zdt.minusSeconds(45) |
ZonedDateTime minusNanos(long nanos) |
Nanosekunden subtrahieren | zdt.minusNanos(1000000) |
ZonedDateTime withYear(int year) |
Das Jahr ändern | zdt.withYear(2024) |
ZonedDateTime withMonth(int month) |
Den Monat ändern | zdt.withMonth(12) |
ZonedDateTime withDayOfMonth(int day) |
Den Tag des Monats ändern | zdt.withDayOfMonth(1) |
ZonedDateTime withHour(int hour) |
Die Stunde ändern | zdt.withHour(0) |
ZonedDateTime withMinute(int minute) |
Die Minute ändern | zdt.withMinute(0) |
ZonedDateTime withSecond(int second) |
Die Sekunde ändern | zdt.withSecond(0) |
ZonedDateTime withNano(int nano) |
Die Nanosekunde ändern | zdt.withNano(0) |
ZonedDateTime withZoneSameInstant(ZoneId zone) |
Zeitzone konvertieren (gleichen Zeitpunkt beibehalten) | zdt.withZoneSameInstant(ZoneId.of("UTC")) |
ZonedDateTime withZoneSameLocal(ZoneId zone) |
Zeitzone konvertieren (Ortszeit beibehalten) | zdt.withZoneSameLocal(ZoneId.of("UTC")) |
Konvertierungsmethoden
| Methode | Beschreibung | Beispiel |
|---|---|---|
LocalDate toLocalDate() |
In LocalDate konvertieren | zdt.toLocalDate() |
LocalTime toLocalTime() |
In LocalTime konvertieren | zdt.toLocalTime() |
LocalDateTime toLocalDateTime() |
In LocalDateTime konvertieren | zdt.toLocalDateTime() |
OffsetDateTime toOffsetDateTime() |
In OffsetDateTime konvertieren | zdt.toOffsetDateTime() |
Instant toInstant() |
In Instant konvertieren | zdt.toInstant() |
Vergleichsmethoden
| Methode | Beschreibung | Beispiel |
|---|---|---|
boolean isAfter(ChronoZonedDateTime<?> other) |
Ob nach dem angegebenen Datum/Uhrzeit | zdt1.isAfter(zdt2) |
boolean isBefore(ChronoZonedDateTime<?> other) |
Ob vor dem angegebenen Datum/Uhrzeit | zdt1.isBefore(zdt2) |
boolean isEqual(ChronoZonedDateTime<?> other) |
Ob gleich dem angegebenen Datum/Uhrzeit | zdt1.isEqual(zdt2) |
int compareTo(ChronoZonedDateTime<?> other) |
Zwei Datum/Uhrzeit-Werte vergleichen | zdt1.compareTo(zdt2) |
Formatierung und String-Konvertierung
| Methoden | Beschreibung | Beispiel |
|---|---|---|
String format(DateTimeFormatter formatter) |
Als String formatieren | zdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME) |
String toString() |
In einen String im ISO-Format konvertieren | "2023-06-15T14:30:45+08:00[Asia/Shanghai]" |