Java ZonedDateTime Tutorial with Examples
ZonedDateTime class represent a date-time with a time-zone in the ISO-8601 calendar system, such as 2016-05-16T10:15:30+01:00 Asia/Singapore. This class is immutable and thread-safe, stores all date and time fields, to a precision of nanoseconds, and a time-zone, with a zone offset used to handle ambiguous local date-times.
Creating a ZonedDateTime
We can create a ZonedDateTime in several ways:
- static ZonedDateTime now(): Obtains the current date-time from the system clock in the default time-zone.
- static ZonedDateTime now(Clock clock): Obtains the current date-time from the specified clock.
- static ZonedDateTime now(ZoneId zone): Obtains the current date-time from the system clock in the specified time-zone.
- static ZonedDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond, ZoneId zone): Obtains an instance of ZonedDateTime from a year, month, day, hour, minute, second, nanosecond and time-zone.
- static ZonedDateTime of(LocalDate date, LocalTime time, ZoneId zone): Obtains an instance of ZonedDateTime from a local date and time.
- static ZonedDateTime of(LocalDateTime localDateTime, ZoneId zone): Obtains an instance of ZonedDateTime from a local date-time.
- static ZonedDateTime ofInstant(Instant instant, ZoneId zone): Obtains an instance of ZonedDateTime from an Instant.
- static ZonedDateTime ofInstant(LocalDateTime localDateTime, ZoneOffset offset, ZoneId zone): Obtains an instance of ZonedDateTime from the instant formed by combining the local date-time and offset.
- static ZonedDateTime ofLocal(LocalDateTime localDateTime, ZoneId zone, ZoneOffset preferredOffset): Obtains an instance of ZonedDateTime from a local date-time using the preferred offset if possible.
- static ZonedDateTime ofStrict(LocalDateTime localDateTime, ZoneOffset offset, ZoneId zone): Obtains an instance of ZonedDateTime strictly validating the combination of local date-time, offset and zone ID.
- static ZonedDateTime parse(CharSequence text): Obtains an instance of ZonedDateTime from a text string such as 2007-12-03T10:15:30+01:00[Europe/Paris].
- static ZonedDateTime parse(CharSequence text, DateTimeFormatter formatter): Obtains an instance of ZonedDateTime from a text string using a specific formatter.
The time zones are represented by the ZoneId class. You can create a ZoneId object using the ZoneId.now() method.
import java.time.Clock;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public class ZonedDateTimeInitExample {
public static void main(String[] args) {
ZonedDateTime zonedDT1 = ZonedDateTime.now();
System.out.println("ZonedDateTime1 : " + zonedDT1);
ZonedDateTime zonedDT2 = ZonedDateTime.now(Clock.systemUTC());
System.out.println("ZonedDateTime2 : " + zonedDT2);
ZonedDateTime zonedDT3 = ZonedDateTime.now(ZoneId.of("Asia/Jakarta"));
System.out.println("ZonedDateTime3 : " + zonedDT3);
ZonedDateTime zonedDT4 = ZonedDateTime.of(1980, 4, 9, 20, 15, 45, 345875000, ZoneId.systemDefault());
System.out.println("ZonedDateTime4 : " + zonedDT4);
ZonedDateTime zonedDT5 = ZonedDateTime.of(LocalDate.now(), LocalTime.of(15, 50, 25), ZoneId.systemDefault());
System.out.println("ZonedDateTime5 : " + zonedDT5);
ZonedDateTime zonedDT6 = ZonedDateTime.of(LocalDateTime.now(), ZoneId.systemDefault());
System.out.println("ZonedDateTime6 : " + zonedDT6);
ZonedDateTime zonedDT7 = ZonedDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
System.out.println("ZonedDateTime7 : " + zonedDT7);
ZonedDateTime zonedDT8 = ZonedDateTime.ofInstant(LocalDateTime.now(), ZoneOffset.UTC, ZoneId.systemDefault());
System.out.println("ZonedDateTime8 : " + zonedDT8);
ZonedDateTime zonedDT9 = ZonedDateTime.ofLocal(LocalDateTime.now(), ZoneId.systemDefault(), ZoneOffset.UTC);
System.out.println("ZonedDateTime9 : " + zonedDT9);
ZonedDateTime zonedDT10 = ZonedDateTime.ofStrict(LocalDateTime.now(), ZoneOffset.ofHours(8), ZoneId.of("Asia/Singapore"));
System.out.println("ZonedDateTime10: " + zonedDT10);
ZonedDateTime zonedDT11 = ZonedDateTime.parse("2017-10-10T18:30:45+01:00[Europe/London]");
System.out.println("ZonedDateTime11: " + zonedDT11);
ZonedDateTime zonedDT12 = ZonedDateTime.parse("2018-04-22T08:40:15+10:00[Australia/Sydney]", DateTimeFormatter.ISO_DATE_TIME);
System.out.println("ZonedDateTime12: " + zonedDT12);
}
}
ZonedDateTime1 : 2019-08-27T00:12:55.333+08:00[Asia/Singapore] ZonedDateTime2 : 2019-08-26T16:12:55.334Z ZonedDateTime3 : 2019-08-26T23:12:55.334+07:00[Asia/Jakarta] ZonedDateTime4 : 1980-04-09T20:15:45.345875+07:30[Asia/Singapore] ZonedDateTime5 : 2019-08-27T15:50:25+08:00[Asia/Singapore] ZonedDateTime6 : 2019-08-27T00:12:55.335+08:00[Asia/Singapore] ZonedDateTime7 : 2019-08-27T00:12:55.335+08:00[Asia/Singapore] ZonedDateTime8 : 2019-08-27T08:12:55.335+08:00[Asia/Singapore] ZonedDateTime9 : 2019-08-27T00:12:55.335+08:00[Asia/Singapore] ZonedDateTime10: 2019-08-27T00:12:55.335+08:00[Asia/Singapore] ZonedDateTime11: 2017-10-10T18:30:45+01:00[Europe/London] ZonedDateTime12: 2018-04-22T08:40:15+10:00[Australia/Sydney]
Getting Information from a ZonedDateTime
Following methods can be used to access Date and/or Time information from a ZonedDateTime:
- int get(TemporalField field): Gets the value of the specified field from this date-time as an int.
- int getDayOfMonth(): Gets the day-of-month field.
- DayOfWeek getDayOfWeek(): Gets the day-of-week field, which is an enum DayOfWeek.
- int getDayOfYear(): Gets the day-of-year field.
- int getHour(): Gets the hour-of-day field.
- long getLong(TemporalField field): Gets the value of the specified field from this date-time as a long.
- int getMinute(): Gets the minute-of-hour field.
- Month getMonth(): Gets the month-of-year field using the Month enum.
- int getMonthValue(): Gets the month-of-year field from 1 to 12.
- int getNano(): Gets the nano-of-second field.
- ZoneOffset getOffset(): Gets the zone offset, such as '+01:00'.
- int getSecond(): Gets the second-of-minute field.
- int getYear(): Gets the year field.
- ZoneId getZone(): Gets the time-zone, such as 'Europe/Paris'.
- long toEpochSecond(): Converts this date-time to the number of seconds from the epoch of 1970-01-01T00:00:00Z.
And following methods can be used to get another class (or convert) from a ZonedDateTime instance:
- Instant toInstant(): Converts this date-time to an Instant.
- LocalDate toLocalDate(): Gets the LocalDate part of this date-time.
- LocalDateTime toLocalDateTime(): Gets the LocalDateTime part of this date-time.
- LocalTime toLocalTime(): Gets the LocalTime part of this date-time.
- OffsetDateTime toOffsetDateTime(): Converts this date-time to an OffsetDateTime.
import java.time.ZonedDateTime;
import java.time.temporal.ChronoField;
public class ZonedDateTimeInfoExample {
public static void main(String[] args) {
ZonedDateTime zonedDT = ZonedDateTime.now();
System.out.println("ZonedDateTime : " + zonedDT);
System.out.println("DayOfMonth : " + zonedDT.getDayOfMonth());
System.out.println("MonthValue : " + zonedDT.getMonthValue());
System.out.println("Year : " + zonedDT.getYear());
System.out.println("Hour : " + zonedDT.getHour());
System.out.println("Minute : " + zonedDT.getMinute());
System.out.println("Second : " + zonedDT.getSecond());
System.out.println("Nano : " + zonedDT.getNano());
System.out.println("DayOfWeek : " + zonedDT.getDayOfWeek());
System.out.println("Month : " + zonedDT.getMonth());
System.out.println("DayOfYear : " + zonedDT.getDayOfYear());
System.out.println("DAY_OF_MONTH : " + zonedDT.get(ChronoField.DAY_OF_MONTH));
System.out.println("MONTH_OF_YEAR : " + zonedDT.get(ChronoField.MONTH_OF_YEAR));
System.out.println("YEAR : " + zonedDT.get(ChronoField.YEAR));
System.out.println("HOUR_OF_DAY : " + zonedDT.get(ChronoField.HOUR_OF_DAY));
System.out.println("MINUTE_OF_HOUR : " + zonedDT.get(ChronoField.MINUTE_OF_HOUR));
System.out.println("SECOND_OF_MINUTE : " + zonedDT.get(ChronoField.SECOND_OF_MINUTE));
System.out.println("MINUTE_OF_DAY : " + zonedDT.getLong(ChronoField.MINUTE_OF_DAY));
System.out.println("SECOND_OF_DAY : " + zonedDT.getLong(ChronoField.SECOND_OF_DAY));
System.out.println("Chronology : " + zonedDT.getChronology());
System.out.println("toEpochSecond() : " + zonedDT.toEpochSecond());
System.out.println("toInstant() : " + zonedDT.toInstant());
System.out.println("toLocalDate() : " + zonedDT.toLocalDate());
System.out.println("toLocalDateTime() : " + zonedDT.toLocalDateTime());
System.out.println("toLocalTime() : " + zonedDT.toLocalTime());
System.out.println("toOffsetDateTime(): " + zonedDT.toOffsetDateTime());
}
}
ZonedDateTime : 2019-08-27T01:14:16.255+08:00[Asia/Singapore] DayOfMonth : 27 MonthValue : 8 Year : 2019 Hour : 1 Minute : 14 Second : 16 Nano : 255000000 DayOfWeek : TUESDAY Month : AUGUST DayOfYear : 239 DAY_OF_MONTH : 27 MONTH_OF_YEAR : 8 YEAR : 2019 HOUR_OF_DAY : 1 MINUTE_OF_HOUR : 14 SECOND_OF_MINUTE : 16 MINUTE_OF_DAY : 74 SECOND_OF_DAY : 4456 Chronology : ISO toEpochSecond() : 1566839656 toInstant() : 2019-08-26T17:14:16.255Z toLocalDate() : 2019-08-27 toLocalDateTime() : 2019-08-27T01:14:16.255 toLocalTime() : 01:14:16.255 toOffsetDateTime(): 2019-08-27T01:14:16.255+08:00
Add/Subtract Operations on ZonedDateTime
Following methods used for add/subtract operation in a ZonedDateTime:
- ZonedDateTime minus(long amountToSubtract, TemporalUnit unit): Returns a copy of this date-time with the specified amount subtracted.
- ZonedDateTime minus(TemporalAmount amountToSubtract): Returns a copy of this date-time with the specified amount subtracted.
- ZonedDateTime minusDays(long days): Returns a copy of this ZonedDateTime with the specified number of days subtracted.
- ZonedDateTime minusHours(long hours): Returns a copy of this ZonedDateTime with the specified number of hours subtracted.
- ZonedDateTime minusMinutes(long minutes): Returns a copy of this ZonedDateTime with the specified number of minutes subtracted.
- ZonedDateTime minusMonths(long months): Returns a copy of this ZonedDateTime with the specified number of months subtracted.
- ZonedDateTime minusNanos(long nanos): Returns a copy of this ZonedDateTime with the specified number of nanoseconds subtracted.
- ZonedDateTime minusSeconds(long seconds): Returns a copy of this ZonedDateTime with the specified number of seconds subtracted.
- ZonedDateTime minusWeeks(long weeks): Returns a copy of this ZonedDateTime with the specified number of weeks subtracted.
- ZonedDateTime minusYears(long years): Returns a copy of this ZonedDateTime with the specified number of years subtracted.
- ZonedDateTime plus(long amountToAdd, TemporalUnit unit): Returns a copy of this date-time with the specified amount added.
- ZonedDateTime plus(TemporalAmount amountToAdd): Returns a copy of this date-time with the specified amount added.
- ZonedDateTime plusDays(long days): Returns a copy of this ZonedDateTime with the specified number of days added.
- ZonedDateTime plusHours(long hours): Returns a copy of this ZonedDateTime with the specified number of hours added.
- ZonedDateTime plusMinutes(long minutes): Returns a copy of this ZonedDateTime with the specified number of minutes added.
- ZonedDateTime plusMonths(long months): Returns a copy of this ZonedDateTime with the specified number of months added.
- ZonedDateTime plusNanos(long nanos): Returns a copy of this ZonedDateTime with the specified number of nanoseconds added.
- ZonedDateTime plusSeconds(long seconds): Returns a copy of this ZonedDateTime with the specified number of seconds added.
- ZonedDateTime plusWeeks(long weeks): Returns a copy of this ZonedDateTime with the specified number of weeks added.
- ZonedDateTime plusYears(long years): Returns a copy of this ZonedDateTime with the specified number of years added.
import java.time.Duration;
import java.time.ZonedDateTime;
import java.time.Period;
import java.time.temporal.ChronoUnit;
public class ZonedDateTimeAddSubstractExample {
public static void main(String[] args) {
ZonedDateTime zonedDT = ZonedDateTime.parse("1984-08-13T18:30:15+08:00[Asia/Singapore]");
System.out.println("ZonedDateTime : " + zonedDT);
// Adding/subtracting days
System.out.println("10 days before : " + zonedDT.minusDays(10));
System.out.println("15 days later : " + zonedDT.plusDays(15));
// Adding/subtracting months
System.out.println("Minus 4 months : " + zonedDT.minusMonths(4));
System.out.println("Plus 5 months : " + zonedDT.plusMonths(5));
// Adding/subtracting weeks
System.out.println("Minus 20 weeks : " + zonedDT.minusWeeks(20));
System.out.println("Plus 30 weeks : " + zonedDT.plusWeeks(30));
// Adding/subtracting years
System.out.println("Minus 12 years : " + zonedDT.minusYears(12));
System.out.println("Plus 4 years : " + zonedDT.plusYears(4));
// Adding/subtracting hours
System.out.println("12 hours before : " + zonedDT.minusHours(12));
System.out.println("6 hours later : " + zonedDT.plusHours(6));
// Adding/subtracting minutes
System.out.println("Minus 40 minutes : " + zonedDT.minusMinutes(40));
System.out.println("Plus 15 minutes : " + zonedDT.plusMinutes(15));
// Adding/subtracting seconds
System.out.println("Minus 30 seconds : " + zonedDT.minusSeconds(30));
System.out.println("Plus 20 seconds : " + zonedDT.plusSeconds(20));
// Adding/subtracting Nanos
System.out.println("Minus 20000 nanos : " + zonedDT.minusNanos(20000));
System.out.println("Plus 340000 nanos : " + zonedDT.plusNanos(340000));
// Using DAYS
System.out.println("30 days before : " + zonedDT.minus(30, ChronoUnit.DAYS));
// Using WEEKS
System.out.println("3 weeks before : " + zonedDT.minus(3, ChronoUnit.WEEKS));
// Using MONTHS
System.out.println("6 months later : " + zonedDT.plus(6, ChronoUnit.MONTHS));
// Using YEARS
System.out.println("2 years later : " + zonedDT.plus(2, ChronoUnit.YEARS));
// Using HOURS
System.out.println("8 hours before : " + zonedDT.minus(8, ChronoUnit.HOURS));
// Using MINUTES
System.out.println("35 minutes before : " + zonedDT.minus(35, ChronoUnit.MINUTES));
// Using SECONDS
System.out.println("125 seconds later : " + zonedDT.plus(125, ChronoUnit.SECONDS));
// Using NANOS
System.out.println("42357500 nanos later: " + zonedDT.plus(42357500, ChronoUnit.NANOS));
// Using TemporalAmount - Period
System.out.println("5 years later : " + zonedDT.plus(Period.ofYears(5)));
// Using TemporalAmount - Duration
System.out.println("60 days before : " + zonedDT.minus(Duration.ofDays(60)));
System.out.println("160 minutes before : " + zonedDT.minus(Duration.ofMinutes(160)));
System.out.println("2 hours later : " + zonedDT.plus(Duration.ofHours(2)));
}
}
ZonedDateTime : 1984-08-13T18:30:15+08:00[Asia/Singapore] 10 days before : 1984-08-03T18:30:15+08:00[Asia/Singapore] 15 days later : 1984-08-28T18:30:15+08:00[Asia/Singapore] Minus 4 months : 1984-04-13T18:30:15+08:00[Asia/Singapore] Plus 5 months : 1985-01-13T18:30:15+08:00[Asia/Singapore] Minus 20 weeks : 1984-03-26T18:30:15+08:00[Asia/Singapore] Plus 30 weeks : 1985-03-11T18:30:15+08:00[Asia/Singapore] Minus 12 years : 1972-08-13T18:30:15+07:30[Asia/Singapore] Plus 4 years : 1988-08-13T18:30:15+08:00[Asia/Singapore] 12 hours before : 1984-08-13T06:30:15+08:00[Asia/Singapore] 6 hours later : 1984-08-14T00:30:15+08:00[Asia/Singapore] Minus 40 minutes : 1984-08-13T17:50:15+08:00[Asia/Singapore] Plus 15 minutes : 1984-08-13T18:45:15+08:00[Asia/Singapore] Minus 30 seconds : 1984-08-13T18:29:45+08:00[Asia/Singapore] Plus 20 seconds : 1984-08-13T18:30:35+08:00[Asia/Singapore] Minus 20000 nanos : 1984-08-13T18:30:14.999980+08:00[Asia/Singapore] Plus 340000 nanos : 1984-08-13T18:30:15.000340+08:00[Asia/Singapore] 30 days before : 1984-07-14T18:30:15+08:00[Asia/Singapore] 3 weeks before : 1984-07-23T18:30:15+08:00[Asia/Singapore] 6 months later : 1985-02-13T18:30:15+08:00[Asia/Singapore] 2 years later : 1986-08-13T18:30:15+08:00[Asia/Singapore] 8 hours before : 1984-08-13T10:30:15+08:00[Asia/Singapore] 35 minutes before : 1984-08-13T17:55:15+08:00[Asia/Singapore] 125 seconds later : 1984-08-13T18:32:20+08:00[Asia/Singapore] 42357500 nanos later: 1984-08-13T18:30:15.042357500+08:00[Asia/Singapore] 5 years later : 1989-08-13T18:30:15+08:00[Asia/Singapore] 60 days before : 1984-06-14T18:30:15+08:00[Asia/Singapore] 160 minutes before : 1984-08-13T15:50:15+08:00[Asia/Singapore] 2 hours later : 1984-08-13T20:30:15+08:00[Asia/Singapore]
Comparing ZonedDateTimes
ZonedDateTime class is implementing interface ChronoZonedDateTime. Following methods can be use to compare two ZonedDateTimes:
- int compareTo(ChronoZonedDateTime<?> other): Compares this date-time to another date-time, including the chronology.
- boolean isAfter(ChronoZonedDateTime<?> other): Checks if the instant of this date-time is after that of the specified date-time.
- boolean isBefore(ChronoZonedDateTime<?> other): Checks if the instant of this date-time is before that of the specified date-time.
- boolean isEqual(ChronoZonedDateTime<?> other): Checks if the instant of this date-time is equal to that of the specified date-time.
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class LocalDateTimeCompareExample {
public static void main(String[] args) {
LocalDateTime localDT1 = LocalDateTime.parse("1979-12-09T09:50:25");
LocalDateTime localDT2 = LocalDateTime.parse("1980-04-09T09:50:25");
LocalDateTime localDT3 = LocalDateTime.parse("19791209095025", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
System.out.println("LocalDateTime1 after LocalDateTime2 : " + localDT1.isAfter(localDT2));
System.out.println("LocalDateTime1 before LocalDateTime2 : " + localDT1.isBefore(localDT2));
System.out.println("LocalDateTime1 equal LocalDateTime3 : " + localDT1.isEqual(localDT3));
System.out.println("LocalDateTime2 equal LocalDateTime3 : " + localDT2.isEqual(localDT3));
System.out.println("LocalDateTime1 compareTo LocalDateTime2: " + localDT1.compareTo(localDT2));
System.out.println("LocalDateTime2 compareTo LocalDateTime1: " + localDT2.compareTo(localDT1));
System.out.println("LocalDateTime1 compareTo LocalDateTime3: " + localDT1.compareTo(localDT3));
System.out.println("LocalDateTime3 compareTo LocalDateTime2: " + localDT3.compareTo(localDT2));
}
}
LocalDateTime1 after LocalDateTime2 : false LocalDateTime1 before LocalDateTime2 : true LocalDateTime1 equal LocalDateTime3 : true LocalDateTime2 equal LocalDateTime3 : false LocalDateTime1 compareTo LocalDateTime2: -1 LocalDateTime2 compareTo LocalDateTime1: 1 LocalDateTime1 compareTo LocalDateTime3: 0 LocalDateTime3 compareTo LocalDateTime2: -1
Supported Field and Unit of a ZonedDateTime
Use isSupported(...) to check if a particular field/unit is supported in a ZonedDateTime:
- boolean isSupported(TemporalField field): Checks if the specified field is supported.
- boolean isSupported(TemporalUnit unit): Checks if the specified unit is supported.
import java.time.ZonedDateTime;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
public class ZonedDateTimeIsSupportedExample {
public static void main(String[] args) {
ZonedDateTime zonedDT = ZonedDateTime.now();
System.out.println("*** ChronoField ***");
for(ChronoField chronoField : ChronoField.values()){
System.out.println(chronoField + " is supported:" + zonedDT.isSupported(chronoField));
}
System.out.println("\n*** ChronoUnit ***");
for(ChronoUnit chronoUnit : ChronoUnit.values()){
System.out.println(chronoUnit + " is supported:" + zonedDT.isSupported(chronoUnit));
}
}
}
*** ChronoField *** NanoOfSecond is supported:true NanoOfDay is supported:true MicroOfSecond is supported:true MicroOfDay is supported:true MilliOfSecond is supported:true MilliOfDay is supported:true SecondOfMinute is supported:true SecondOfDay is supported:true MinuteOfHour is supported:true MinuteOfDay is supported:true HourOfAmPm is supported:true ClockHourOfAmPm is supported:true HourOfDay is supported:true ClockHourOfDay is supported:true AmPmOfDay is supported:true DayOfWeek is supported:true AlignedDayOfWeekInMonth is supported:true AlignedDayOfWeekInYear is supported:true DayOfMonth is supported:true DayOfYear is supported:true EpochDay is supported:true AlignedWeekOfMonth is supported:true AlignedWeekOfYear is supported:true MonthOfYear is supported:true ProlepticMonth is supported:true YearOfEra is supported:true Year is supported:true Era is supported:true InstantSeconds is supported:true OffsetSeconds is supported:true *** ChronoUnit *** Nanos is supported:true Micros is supported:true Millis is supported:true Seconds is supported:true Minutes is supported:true Hours is supported:true HalfDays is supported:true Days is supported:true Weeks is supported:true Months is supported:true Years is supported:true Decades is supported:true Centuries is supported:true Millennia is supported:true Eras is supported:true Forever is supported:false