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"));

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")
);

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);

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

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);

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);

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");

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);

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");

Konvertieren von ZonedDateTime und anderen Datums-/Zeitklassen

1. Umwandlung in Instant

Beispiel

ZonedDateTime zdt = ZonedDateTime.now();
Instant instant = zdt.toInstant();  // In UTC-Zeitstempel umwandeln

2. Umwandlung in LocalDateTime

Beispiel

ZonedDateTime zdt = ZonedDateTime.now();
LocalDateTime ldt = zdt.toLocalDateTime();  // Verliert Zeitzoneninformationen

3. Erstellen aus Instant

Beispiel

Instant instant = Instant.now();
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());
    }
}

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

  1. 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.
  2. Anzeige: Konvertieren Sie nur bei der Anzeige in der Benutzeroberfläche in die lokale Zeitzone.
  3. Vergleich: Wenn Sie Zeiten in verschiedenen Zeitzonen vergleichen, konvertieren Sie sie zuerst in dieselbe Zeitzone oder in Instant.
  4. 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]"
Weitere Erweiterungen