Java ZonedDateTime Class
Last modified: April 16, 2025
The java.time.ZonedDateTime
class represents a date-time with a timezone.
It combines LocalDateTime with ZoneId to handle timezone rules. This class is
immutable and thread-safe.
ZonedDateTime
is used when timezone context is important. It handles
daylight saving time automatically. The class provides precision up to
nanoseconds and follows ISO-8601 calendar system.
ZonedDateTime Class Overview
ZonedDateTime
provides methods to create, manipulate, and format
date-time values. It can convert between timezones and handle daylight saving.
The class is part of Java's modern date-time API introduced in Java 8.
public final class ZonedDateTime implements Temporal, ChronoZonedDateTime<LocalDate>, Serializable { public static ZonedDateTime now(); public static ZonedDateTime of(LocalDateTime localDateTime, ZoneId zone); public static ZonedDateTime parse(CharSequence text); public ZoneId getZone(); public ZonedDateTime withZoneSameInstant(ZoneId zone); public LocalDateTime toLocalDateTime(); public Instant toInstant(); public boolean isBefore(ChronoZonedDateTime<?> other); public boolean isAfter(ChronoZonedDateTime<?> other); }
The code above shows key methods of ZonedDateTime
. These methods
allow timezone-aware date-time operations. The class handles all timezone
conversions and daylight saving adjustments automatically.
Creating ZonedDateTime Objects
ZonedDateTime objects can be created in several ways. The most common methods
are now
for current time and factory methods for specific values.
Parsing from strings is also supported.
package com.zetcode; import java.time.ZonedDateTime; import java.time.ZoneId; import java.time.LocalDateTime; public class Main { public static void main(String[] args) { // Current date-time with timezone ZonedDateTime now = ZonedDateTime.now(); System.out.println("Current ZonedDateTime: " + now); // Specific timezone ZonedDateTime parisTime = ZonedDateTime.now(ZoneId.of("Europe/Paris")); System.out.println("Paris time: " + parisTime); // From LocalDateTime LocalDateTime ldt = LocalDateTime.of(2025, 6, 15, 10, 30); ZonedDateTime zdt = ZonedDateTime.of(ldt, ZoneId.of("America/New_York")); System.out.println("From LocalDateTime: " + zdt); // From string ZonedDateTime parsed = ZonedDateTime.parse("2025-01-01T12:00:00+01:00[Europe/Berlin]"); System.out.println("Parsed from string: " + parsed); } }
This example shows different ways to create ZonedDateTime objects. The output includes both the date-time and timezone information. Note how timezone affects the displayed time values.
Getting ZonedDateTime Components
ZonedDateTime can be decomposed into its components like year, month, and timezone. These values are useful for display or further calculations. The class provides getter methods for all components.
package com.zetcode; import java.time.ZonedDateTime; import java.time.ZoneId; public class Main { public static void main(String[] args) { ZonedDateTime zdt = ZonedDateTime.now(); // Get date and time components 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()); // Get timezone information ZoneId zone = zdt.getZone(); System.out.println("Timezone: " + zone.getId()); // Get offset from UTC System.out.println("Offset: " + zdt.getOffset()); } }
This example demonstrates how to extract components from a ZonedDateTime. The timezone information includes both the zone ID and UTC offset. All components reflect the values in the specified timezone.
Converting Timezones
ZonedDateTime can convert between different timezones while preserving the instant in time. This is useful for displaying the same moment in various locations. The conversion handles daylight saving automatically.
package com.zetcode; import java.time.ZonedDateTime; import java.time.ZoneId; public class Main { public static void main(String[] args) { ZonedDateTime nyTime = ZonedDateTime.now(ZoneId.of("America/New_York")); System.out.println("New York time: " + nyTime); // Convert to London time ZonedDateTime londonTime = nyTime.withZoneSameInstant(ZoneId.of("Europe/London")); System.out.println("London time: " + londonTime); // Convert to Tokyo time ZonedDateTime tokyoTime = nyTime.withZoneSameInstant(ZoneId.of("Asia/Tokyo")); System.out.println("Tokyo time: " + tokyoTime); // Keep local time, change only timezone ZonedDateTime sameLocal = nyTime.withZoneSameLocal(ZoneId.of("Europe/Paris")); System.out.println("Same local time in Paris: " + sameLocal); } }
This example shows timezone conversions with ZonedDateTime. The
withZoneSameInstant
method changes the timezone while keeping the
same instant. withZoneSameLocal
keeps the local time values.
Comparing ZonedDateTime
ZonedDateTime objects can be compared chronologically. The comparison considers both the instant in time and the timezone rules. This ensures accurate ordering of events across timezones.
package com.zetcode; import java.time.ZonedDateTime; import java.time.ZoneId; import java.time.Duration; public class Main { public static void main(String[] args) { ZonedDateTime nyTime = ZonedDateTime.now(ZoneId.of("America/New_York")); ZonedDateTime londonTime = nyTime.withZoneSameInstant(ZoneId.of("Europe/London")); ZonedDateTime futureTime = nyTime.plusHours(2); System.out.println("NY before London: " + nyTime.isBefore(londonTime)); System.out.println("NY after future: " + nyTime.isAfter(futureTime)); System.out.println("Compare NY and London: " + nyTime.compareTo(londonTime)); // Time difference between zones Duration offsetDiff = Duration.between(nyTime.toLocalTime(), londonTime.toLocalTime()); System.out.println("Time difference: " + offsetDiff.toHours() + " hours"); } }
This example demonstrates comparing ZonedDateTime objects. The comparison methods consider the actual instant in time, not just the local time values. The time difference calculation shows the current offset between timezones.
Working with Daylight Saving Time
ZonedDateTime automatically handles daylight saving time transitions. It adjusts the time values according to the timezone rules. This ensures correct time representation throughout the year.
package com.zetcode; import java.time.ZonedDateTime; import java.time.ZoneId; import java.time.Month; public class Main { public static void main(String[] args) { ZoneId nyZone = ZoneId.of("America/New_York"); // Before DST transition (March 10, 2025 1:59 AM) ZonedDateTime beforeDST = ZonedDateTime.of(2025, 3, 10, 1, 59, 0, 0, nyZone); System.out.println("Before DST: " + beforeDST); // After DST transition (1 hour later) ZonedDateTime afterDST = beforeDST.plusHours(1); System.out.println("After DST: " + afterDST); // Check if DST is in effect System.out.println("Is DST: " + afterDST.getZone().getRules().isDaylightSavings(afterDST.toInstant())); // November DST end ZonedDateTime endDST = ZonedDateTime.of(2025, 11, 2, 1, 59, 0, 0, nyZone); System.out.println("Before DST end: " + endDST); System.out.println("After DST end: " + endDST.plusHours(1)); } }
This example shows ZonedDateTime handling daylight saving time transitions. The spring forward and fall back transitions are handled automatically. The DST status can be checked for any specific instant.
Converting to Other Types
ZonedDateTime can be converted to other date-time types like LocalDateTime or Instant. These conversions are useful when timezone information is no longer needed or when working with legacy APIs.
package com.zetcode; import java.time.ZonedDateTime; import java.time.LocalDateTime; import java.time.Instant; import java.time.OffsetDateTime; public class Main { public static void main(String[] args) { ZonedDateTime zdt = ZonedDateTime.now(); // Convert to LocalDateTime (loses timezone) LocalDateTime ldt = zdt.toLocalDateTime(); System.out.println("LocalDateTime: " + ldt); // Convert to Instant (UTC) Instant instant = zdt.toInstant(); System.out.println("Instant: " + instant); // Convert to OffsetDateTime (keeps offset but not zone ID) OffsetDateTime odt = zdt.toOffsetDateTime(); System.out.println("OffsetDateTime: " + odt); // Convert back to ZonedDateTime ZonedDateTime back = instant.atZone(zdt.getZone()); System.out.println("Back to ZonedDateTime: " + back); } }
This example demonstrates conversions between ZonedDateTime and other date-time types. Each conversion serves different purposes depending on whether timezone, offset, or UTC time is needed. The original ZonedDateTime can be reconstructed.
Source
Java ZonedDateTime Class Documentation
In this article, we've covered the essential methods and features of the Java ZonedDateTime class. Understanding these concepts is crucial for accurate timezone handling in modern Java applications.
Author
List all Java tutorials.