ZetCode

Java ChronoZonedDateTime Interface

Last modified: April 16, 2025

The java.time.chrono.ChronoZonedDateTime interface represents a date-time with a time-zone in an arbitrary chronology. It combines temporal information with timezone rules. This interface extends Comparable and Temporal.

ChronoZonedDateTime is immutable and thread-safe. It handles date-time calculations according to the rules of a specific calendar system. The interface supports both ISO and non-ISO calendar systems through the chronology mechanism.

ChronoZonedDateTime Interface Overview

The interface provides methods to access date-time fields, perform calculations, and convert between time zones. It combines chronology, local date-time, and time zone information. All implementations must be immutable and thread-safe.

public interface ChronoZonedDateTime<D extends ChronoLocalDate>
    extends Comparable<ChronoZonedDateTime<?>>, Temporal {
    ZoneId getZone();
    ChronoLocalDateTime<D> toLocalDateTime();
    Chronology getChronology();
    boolean isBefore(ChronoZonedDateTime<?> other);
    boolean isAfter(ChronoZonedDateTime<?> other);
    ChronoZonedDateTime<D> withZoneSameInstant(ZoneId zone);
    ChronoZonedDateTime<D> withZoneSameLocal(ZoneId zone);
    long toEpochSecond();
    Instant toInstant();
}

The code above shows key methods of ChronoZonedDateTime. These methods allow working with date-time values across different calendar systems. The interface provides precision up to nanoseconds with timezone awareness.

Creating ChronoZonedDateTime Objects

ChronoZonedDateTime objects are typically created through factory methods. The most common approach is using ZonedDateTime which implements this interface for the ISO calendar system.

Main.java
package com.zetcode;

import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.chrono.ChronoZonedDateTime;

public class Main {

    public static void main(String[] args) {
        
        // Current date-time with timezone
        ChronoZonedDateTime<?> now = ZonedDateTime.now();
        System.out.println("Current zoned date-time: " + now);
        
        // Specific date-time with timezone
        ChronoZonedDateTime<?> specific = ZonedDateTime.of(
            2025, 6, 15, 14, 30, 0, 0, ZoneId.of("Europe/Paris"));
        System.out.println("Specific zoned date-time: " + specific);
        
        // From string
        ChronoZonedDateTime<?> parsed = ZonedDateTime.parse(
            "2025-01-01T12:00:00+01:00[Europe/Berlin]");
        System.out.println("Parsed zoned date-time: " + parsed);
    }
}

This example demonstrates different ways to create ChronoZonedDateTime objects. The output shows date-time values with timezone information. All examples use the ISO calendar system through ZonedDateTime implementation.

Accessing Date-Time Components

ChronoZonedDateTime provides methods to access its components including date, time, and timezone. These methods allow examining the complete temporal state. The values are specific to the chronology being used.

Main.java
package com.zetcode;

import java.time.ZonedDateTime;
import java.time.chrono.ChronoZonedDateTime;

public class Main {

    public static void main(String[] args) {
        
        ChronoZonedDateTime<?> zdt = ZonedDateTime.now();
        
        System.out.println("Chronology: " + zdt.getChronology());
        System.out.println("Zone: " + zdt.getZone());
        System.out.println("Year: " + zdt.getYear());
        System.out.println("Month: " + zdt.getMonth());
        System.out.println("Day: " + zdt.getDayOfMonth());
        System.out.println("Hour: " + zdt.getHour());
        System.out.println("Minute: " + zdt.getMinute());
        
        // Local date-time without timezone
        System.out.println("Local date-time: " + zdt.toLocalDateTime());
    }
}

This example shows how to access various components of a ChronoZonedDateTime. The getChronology method returns the calendar system in use. All temporal fields are accessed through standard getter methods.

Time Zone Conversions

ChronoZonedDateTime supports converting between time zones while preserving either the instant or local time. These operations are essential for working with global applications that need to display times in different regions.

Main.java
package com.zetcode;

import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.chrono.ChronoZonedDateTime;

public class Main {

    public static void main(String[] args) {
        
        ChronoZonedDateTime<?> nyTime = ZonedDateTime.now(ZoneId.of("America/New_York"));
        System.out.println("New York time: " + nyTime);
        
        // Convert to Tokyo time (same instant)
        ChronoZonedDateTime<?> tokyoTime = nyTime.withZoneSameInstant(ZoneId.of("Asia/Tokyo"));
        System.out.println("Tokyo time (same instant): " + tokyoTime);
        
        // Convert to London time (same local time)
        ChronoZonedDateTime<?> londonTime = nyTime.withZoneSameLocal(ZoneId.of("Europe/London"));
        System.out.println("London time (same local time): " + londonTime);
    }
}

This example demonstrates time zone conversions with ChronoZonedDateTime. withZoneSameInstant changes the timezone while keeping the same instant. withZoneSameLocal keeps the local time but changes the timezone, resulting in a different instant.

Comparing ChronoZonedDateTime

ChronoZonedDateTime instances can be compared chronologically. The comparison considers both the instant in time and the chronology. Different calendar systems can be compared through their equivalent instants.

Main.java
package com.zetcode;

import java.time.ZonedDateTime;
import java.time.ZoneId;
import java.time.chrono.ChronoZonedDateTime;
import java.time.temporal.ChronoUnit;

public class Main {

    public static void main(String[] args) {
        
        ChronoZonedDateTime<?> now = ZonedDateTime.now();
        ChronoZonedDateTime<?> future = now.plus(1, ChronoUnit.HOURS);
        ChronoZonedDateTime<?> past = now.minus(30, ChronoUnit.MINUTES);
        
        System.out.println("Now is before future: " + now.isBefore(future));
        System.out.println("Now is after past: " + now.isAfter(past));
        System.out.println("Comparison result: " + now.compareTo(future));
        
        // Equality considers both chronology and instant
        ChronoZonedDateTime<?> copy = ZonedDateTime.from(now);
        System.out.println("Now equals copy: " + now.equals(copy));
    }
}

This example shows various ways to compare ChronoZonedDateTime objects. The comparison methods consider both the instant and chronology. Note that equality requires both the chronology and instant to match exactly.

Converting to Instant and Epoch Seconds

ChronoZonedDateTime can be converted to Instant and epoch seconds for interoperability with other time representations. These conversions are useful when working with APIs that require machine time representations.

Main.java
package com.zetcode;

import java.time.ZonedDateTime;
import java.time.chrono.ChronoZonedDateTime;

public class Main {

    public static void main(String[] args) {
        
        ChronoZonedDateTime<?> zdt = ZonedDateTime.now();
        
        // Convert to Instant
        System.out.println("As Instant: " + zdt.toInstant());
        
        // Convert to epoch seconds
        System.out.println("Epoch seconds: " + zdt.toEpochSecond());
        
        // Convert from Instant back to ChronoZonedDateTime
        ChronoZonedDateTime<?> fromInstant = 
            ZonedDateTime.ofInstant(zdt.toInstant(), zdt.getZone());
        System.out.println("From Instant: " + fromInstant);
    }
}

This example demonstrates conversions between ChronoZonedDateTime and Instant. The toInstant method converts to an absolute point in time. toEpochSecond provides the count of seconds from 1970-01-01T00:00:00Z.

Working with Different Chronologies

ChronoZonedDateTime supports non-ISO calendar systems through the chronology mechanism. This allows working with date-times in different cultural calendar systems while maintaining timezone awareness.

Main.java
package com.zetcode;

import java.time.ZoneId;
import java.time.chrono.HijrahChronology;
import java.time.chrono.JapaneseChronology;
import java.time.chrono.ChronoZonedDateTime;
import java.time.LocalDateTime;

public class Main {

    public static void main(String[] args) {
        
        // Japanese calendar
        ChronoZonedDateTime<?> japaneseDate = JapaneseChronology.INSTANCE
            .zonedDateTime(LocalDateTime.now(), ZoneId.systemDefault());
        System.out.println("Japanese date-time: " + japaneseDate);
        
        // Hijrah (Islamic) calendar
        ChronoZonedDateTime<?> hijrahDate = HijrahChronology.INSTANCE
            .zonedDateTime(LocalDateTime.now(), ZoneId.of("Asia/Riyadh"));
        System.out.println("Hijrah date-time: " + hijrahDate);
        
        // Comparing across chronologies
        System.out.println("Same instant: " + 
            japaneseDate.toInstant().equals(hijrahDate.toInstant()));
    }
}

This example shows ChronoZonedDateTime with non-ISO calendar systems. The Japanese and Hijrah chronologies are used to create date-time values. Despite different calendar systems, they can be compared through their instant values.

Source

Java ChronoZonedDateTime Interface Documentation

In this article, we've covered the essential methods and features of the Java ChronoZonedDateTime interface. Understanding these concepts is crucial for handling date-time values across different calendar systems and time zones.

Author

My name is Jan Bodnar, and I am a dedicated programmer with many years of experience in the field. I began writing programming articles in 2007 and have since authored over 1,400 articles and eight e-books. With more than eight years of teaching experience, I am committed to sharing my knowledge and helping others master programming concepts.

List all Java tutorials.