Java OffsetDateTime Tutorial with Examples
OffsetDateTime class represent a date-time with an offset from UTC/Greenwich in the ISO-8601 calendar system, such as 1980-04-09T10:15:30+07:00. This class is immutable and thread-safe.
OffsetDateTime, ZonedDateTime and Instant all store an instant on the time-line to nanosecond precision. Instant is the simplest, simply representing the instant. OffsetDateTime adds to the instant the offset from UTC/Greenwich, which allows the local date-time to be obtained. ZonedDateTime adds full time-zone rules.
It is intended that ZonedDateTime or Instant is used to model data in simpler applications. OffsetDateTime may be used when modeling date-time concepts in more detail, or when communicating to a database or in a network protocol.
Creating an OffsetDateTime
We can create an OffsetDateTime in several ways:
- static OffsetDateTime now(): Obtains the current date-time from the system clock in the default time-zone.
- static OffsetDateTime now(Clock clock): Obtains the current date-time from the specified clock.
- static OffsetDateTime now(ZoneId zone): Obtains the current date-time from the system clock in the specified time-zone.
- static OffsetDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond, ZoneOffset offset): Obtains an instance of OffsetDateTime from a year, month, day, hour, minute, second, nanosecond and offset.
- static OffsetDateTime of(LocalDate date, LocalTime time, ZoneOffset offset): Obtains an instance of OffsetDateTime from a date, time and offset.
- static OffsetDateTime of(LocalDateTime dateTime, ZoneOffset offset): Obtains an instance of OffsetDateTime from a date-time and offset.
- static OffsetDateTime ofInstant(Instant instant, ZoneId zone): Obtains an instance of OffsetDateTime from an Instant and zone ID.
- static OffsetDateTime parse(CharSequence text): Obtains an instance of OffsetDateTime from a text string such as 2019-08-31T15:20:30+08:00.
- static OffsetDateTime parse(CharSequence text, DateTimeFormatter formatter): Obtains an instance of OffsetDateTime from a text string using a specific formatter.
The time zone offsets are represented by the ZoneOffset class. You can create a ZoneOffset object using the ZoneId.of(...) method.
import java.time.Clock;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public class OffsetDateTimeInitExample {
public static void main(String[] args) {
OffsetDateTime offsetDT1 = OffsetDateTime.now();
System.out.println("OffsetDateTime1: " + offsetDT1);
OffsetDateTime offsetDT2 = OffsetDateTime.now(Clock.systemUTC());
System.out.println("OffsetDateTime2: " + offsetDT2);
OffsetDateTime offsetDT3 = OffsetDateTime.now(ZoneId.of("Asia/Jakarta"));
System.out.println("OffsetDateTime3: " + offsetDT3);
OffsetDateTime offsetDT4 = OffsetDateTime.of(1980, 4, 9, 20, 15, 45, 345875000, ZoneOffset.of("+07:00"));
System.out.println("OffsetDateTime4: " + offsetDT4);
OffsetDateTime offsetDT5 = OffsetDateTime.of(LocalDate.now(), LocalTime.of(15, 50, 25), ZoneOffset.of("+07:00"));
System.out.println("OffsetDateTime5: " + offsetDT5);
OffsetDateTime offsetDT6 = OffsetDateTime.of(LocalDateTime.now(), ZoneOffset.of("+07:00"));
System.out.println("OffsetDateTime6: " + offsetDT6);
OffsetDateTime offsetDT7 = OffsetDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
System.out.println("OffsetDateTime7: " + offsetDT7);
OffsetDateTime offsetDT8 = OffsetDateTime.parse("2019-08-31T15:20:30+08:00");
System.out.println("OffsetDateTime8: " + offsetDT8);
OffsetDateTime offsetDT9 = OffsetDateTime.parse("1980-04-09T08:20:45+07:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME);
System.out.println("OffsetDateTime9: " + offsetDT9);
}
}
OffsetDateTime1: 2019-08-31T23:49:05.629+08:00 OffsetDateTime2: 2019-08-31T15:49:05.630Z OffsetDateTime3: 2019-08-31T22:49:05.630+07:00 OffsetDateTime4: 1980-04-09T20:15:45.345875+07:00 OffsetDateTime5: 2019-08-31T15:50:25+07:00 OffsetDateTime6: 2019-08-31T23:49:05.631+07:00 OffsetDateTime7: 2019-08-31T23:49:05.631+08:00 OffsetDateTime8: 2019-08-31T15:20:30+08:00 OffsetDateTime9: 1980-04-09T08:20:45+07:00
Getting Information from an OffsetDateTime
Following methods can be used to access Date and/or Time information from an OffsetDateTime:
- 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.
And following methods can be used to get another class (or convert) from an OffsetDateTime instance:
- long toEpochSecond(): Converts this date-time to the number of seconds from the epoch of 1970-01-01T00:00:00Z.
- 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.
- OffsetTime toOffsetTime(): Converts this date-time to an OffsetTime.
- ZonedDateTime toZonedDateTime(): Converts this date-time to a ZonedDateTime using the offset as the zone ID.
import java.time.OffsetDateTime;
import java.time.temporal.ChronoField;
public class OffsetDateTimeInfoExample {
public static void main(String[] args) {
OffsetDateTime offsetDT = OffsetDateTime.now();
System.out.println("OffsetDateTime : " + offsetDT);
System.out.println("DayOfMonth : " + offsetDT.getDayOfMonth());
System.out.println("MonthValue : " + offsetDT.getMonthValue());
System.out.println("Year : " + offsetDT.getYear());
System.out.println("Hour : " + offsetDT.getHour());
System.out.println("Minute : " + offsetDT.getMinute());
System.out.println("Second : " + offsetDT.getSecond());
System.out.println("Nano : " + offsetDT.getNano());
System.out.println("DayOfWeek : " + offsetDT.getDayOfWeek());
System.out.println("Month : " + offsetDT.getMonth());
System.out.println("DayOfYear : " + offsetDT.getDayOfYear());
System.out.println("DAY_OF_MONTH : " + offsetDT.get(ChronoField.DAY_OF_MONTH));
System.out.println("MONTH_OF_YEAR : " + offsetDT.get(ChronoField.MONTH_OF_YEAR));
System.out.println("YEAR : " + offsetDT.get(ChronoField.YEAR));
System.out.println("HOUR_OF_DAY : " + offsetDT.get(ChronoField.HOUR_OF_DAY));
System.out.println("MINUTE_OF_HOUR : " + offsetDT.get(ChronoField.MINUTE_OF_HOUR));
System.out.println("SECOND_OF_MINUTE : " + offsetDT.get(ChronoField.SECOND_OF_MINUTE));
System.out.println("MINUTE_OF_DAY : " + offsetDT.getLong(ChronoField.MINUTE_OF_DAY));
System.out.println("SECOND_OF_DAY : " + offsetDT.getLong(ChronoField.SECOND_OF_DAY));
System.out.println("Offset : " + offsetDT.getOffset());
System.out.println("toEpochSecond() : " + offsetDT.toEpochSecond());
System.out.println("toInstant() : " + offsetDT.toInstant());
System.out.println("toLocalDate() : " + offsetDT.toLocalDate());
System.out.println("toLocalDateTime(): " + offsetDT.toLocalDateTime());
System.out.println("toLocalTime() : " + offsetDT.toLocalTime());
System.out.println("toZonedDateTime(): " + offsetDT.toZonedDateTime());
}
}
OffsetDateTime : 2019-09-01T01:32:00.896+08:00 DayOfMonth : 1 MonthValue : 9 Year : 2019 Hour : 1 Minute : 32 Second : 0 Nano : 896000000 DayOfWeek : SUNDAY Month : SEPTEMBER DayOfYear : 244 DAY_OF_MONTH : 1 MONTH_OF_YEAR : 9 YEAR : 2019 HOUR_OF_DAY : 1 MINUTE_OF_HOUR : 32 SECOND_OF_MINUTE : 0 MINUTE_OF_DAY : 92 SECOND_OF_DAY : 5520 Offset : +08:00 toEpochSecond() : 1567272720 toInstant() : 2019-08-31T17:32:00.896Z toLocalDate() : 2019-09-01 toLocalDateTime(): 2019-09-01T01:32:00.896 toLocalTime() : 01:32:00.896 toZonedDateTime(): 2019-09-01T01:32:00.896+08:00
Add/Subtract Operations on OffsetDateTime
Following methods used for add/subtract operation in an OffsetDateTime:
- OffsetDateTime minus(long amountToSubtract, TemporalUnit unit): Returns a copy of this date-time with the specified amount subtracted.
- OffsetDateTime minus(TemporalAmount amountToSubtract): Returns a copy of this date-time with the specified amount subtracted.
- OffsetDateTime minusDays(long days): Returns a copy of this OffsetDateTime with the specified number of days subtracted.
- OffsetDateTime minusHours(long hours): Returns a copy of this OffsetDateTime with the specified number of hours subtracted.
- OffsetDateTime minusMinutes(long minutes): Returns a copy of this OffsetDateTime with the specified number of minutes subtracted.
- OffsetDateTime minusMonths(long months): Returns a copy of this OffsetDateTime with the specified number of months subtracted.
- OffsetDateTime minusNanos(long nanos): Returns a copy of this OffsetDateTime with the specified number of nanoseconds subtracted.
- OffsetDateTime minusSeconds(long seconds): Returns a copy of this OffsetDateTime with the specified number of seconds subtracted.
- OffsetDateTime minusWeeks(long weeks): Returns a copy of this OffsetDateTime with the specified number of weeks subtracted.
- OffsetDateTime minusYears(long years): Returns a copy of this OffsetDateTime with the specified number of years subtracted.
- OffsetDateTime plus(long amountToAdd, TemporalUnit unit): Returns a copy of this date-time with the specified amount added.
- OffsetDateTime plus(TemporalAmount amountToAdd): Returns a copy of this date-time with the specified amount added.
- OffsetDateTime plusDays(long days): Returns a copy of this OffsetDateTime with the specified number of days added.
- OffsetDateTime plusHours(long hours): Returns a copy of this OffsetDateTime with the specified number of hours added.
- OffsetDateTime plusMinutes(long minutes): Returns a copy of this OffsetDateTime with the specified number of minutes added.
- OffsetDateTime plusMonths(long months): Returns a copy of this OffsetDateTime with the specified number of months added.
- OffsetDateTime plusNanos(long nanos): Returns a copy of this OffsetDateTime with the specified number of nanoseconds added.
- OffsetDateTime plusSeconds(long seconds): Returns a copy of this OffsetDateTime with the specified number of seconds added.
- OffsetDateTime plusWeeks(long weeks): Returns a copy of this OffsetDateTime with the specified number of weeks added.
- OffsetDateTime plusYears(long years): Returns a copy of this OffsetDateTime with the specified number of years added.
import java.time.Duration;
import java.time.OffsetDateTime;
import java.time.Period;
import java.time.temporal.ChronoUnit;
public class OffsetDateTimeAddSubstractExample {
public static void main(String[] args) {
OffsetDateTime offsetDT = OffsetDateTime.parse("1983-07-12T06:30:15+07:00");
System.out.println("OffsetDateTime : " + offsetDT);
// Adding/subtracting days
System.out.println("10 days before : " + offsetDT.minusDays(10));
System.out.println("15 days later : " + offsetDT.plusDays(15));
// Adding/subtracting months
System.out.println("Minus 4 months : " + offsetDT.minusMonths(4));
System.out.println("Plus 5 months : " + offsetDT.plusMonths(5));
// Adding/subtracting weeks
System.out.println("Minus 20 weeks : " + offsetDT.minusWeeks(20));
System.out.println("Plus 30 weeks : " + offsetDT.plusWeeks(30));
// Adding/subtracting years
System.out.println("Minus 12 years : " + offsetDT.minusYears(12));
System.out.println("Plus 4 years : " + offsetDT.plusYears(4));
// Adding/subtracting hours
System.out.println("12 hours before : " + offsetDT.minusHours(12));
System.out.println("6 hours later : " + offsetDT.plusHours(6));
// Adding/subtracting minutes
System.out.println("Minus 40 minutes : " + offsetDT.minusMinutes(40));
System.out.println("Plus 15 minutes : " + offsetDT.plusMinutes(15));
// Adding/subtracting seconds
System.out.println("Minus 30 seconds : " + offsetDT.minusSeconds(30));
System.out.println("Plus 20 seconds : " + offsetDT.plusSeconds(20));
// Adding/subtracting Nanos
System.out.println("Minus 20000 nanos : " + offsetDT.minusNanos(20000));
System.out.println("Plus 340000 nanos : " + offsetDT.plusNanos(340000));
// Using DAYS
System.out.println("30 days before : " + offsetDT.minus(30, ChronoUnit.DAYS));
// Using WEEKS
System.out.println("3 weeks before : " + offsetDT.minus(3, ChronoUnit.WEEKS));
// Using MONTHS
System.out.println("6 months later : " + offsetDT.plus(6, ChronoUnit.MONTHS));
// Using YEARS
System.out.println("2 years later : " + offsetDT.plus(2, ChronoUnit.YEARS));
// Using HOURS
System.out.println("8 hours before : " + offsetDT.minus(8, ChronoUnit.HOURS));
// Using MINUTES
System.out.println("35 minutes before : " + offsetDT.minus(35, ChronoUnit.MINUTES));
// Using SECONDS
System.out.println("125 seconds later : " + offsetDT.plus(125, ChronoUnit.SECONDS));
// Using NANOS
System.out.println("42357500 nanos later: " + offsetDT.plus(42357500, ChronoUnit.NANOS));
// Using TemporalAmount - Duration
System.out.println("60 days before : " + offsetDT.minus(Duration.ofDays(60)));
System.out.println("160 minutes before : " + offsetDT.minus(Duration.ofMinutes(160)));
System.out.println("2 hours later : " + offsetDT.plus(Duration.ofHours(2)));
// Using TemporalAmount - Period
System.out.println("5 years before : " + offsetDT.minus(Period.ofYears(5)));
System.out.println("8 months later : " + offsetDT.plus(Period.ofMonths(8)));
}
}
OffsetDateTime : 1983-07-12T06:30:15+07:00 10 days before : 1983-07-02T06:30:15+07:00 15 days later : 1983-07-27T06:30:15+07:00 Minus 4 months : 1983-03-12T06:30:15+07:00 Plus 5 months : 1983-12-12T06:30:15+07:00 Minus 20 weeks : 1983-02-22T06:30:15+07:00 Plus 30 weeks : 1984-02-07T06:30:15+07:00 Minus 12 years : 1971-07-12T06:30:15+07:00 Plus 4 years : 1987-07-12T06:30:15+07:00 12 hours before : 1983-07-11T18:30:15+07:00 6 hours later : 1983-07-12T12:30:15+07:00 Minus 40 minutes : 1983-07-12T05:50:15+07:00 Plus 15 minutes : 1983-07-12T06:45:15+07:00 Minus 30 seconds : 1983-07-12T06:29:45+07:00 Plus 20 seconds : 1983-07-12T06:30:35+07:00 Minus 20000 nanos : 1983-07-12T06:30:14.999980+07:00 Plus 340000 nanos : 1983-07-12T06:30:15.000340+07:00 30 days before : 1983-06-12T06:30:15+07:00 3 weeks before : 1983-06-21T06:30:15+07:00 6 months later : 1984-01-12T06:30:15+07:00 2 years later : 1985-07-12T06:30:15+07:00 8 hours before : 1983-07-11T22:30:15+07:00 35 minutes before : 1983-07-12T05:55:15+07:00 125 seconds later : 1983-07-12T06:32:20+07:00 42357500 nanos later: 1983-07-12T06:30:15.042357500+07:00 60 days before : 1983-05-13T06:30:15+07:00 160 minutes before : 1983-07-12T03:50:15+07:00 2 hours later : 1983-07-12T08:30:15+07:00 5 years before : 1978-07-12T06:30:15+07:00 8 months later : 1984-03-12T06:30:15+07:00
Comparing OffsetDateTimes
Following methods can be use to compare two OffsetDateTimes:
- int compareTo(OffsetDateTime other): Compares this date-time to another date-time.
- boolean isAfter(OffsetDateTime other): Checks if the instant of this date-time is after that of the specified date-time.
- boolean isBefore(OffsetDateTime other): Checks if the instant of this date-time is before that of the specified date-time.
- boolean isEqual(OffsetDateTime 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.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public class OffsetDateTimeCompareExample {
public static void main(String[] args) {
OffsetDateTime offsetDT1 = OffsetDateTime.parse("1979-12-09T09:50:25+07:00");
OffsetDateTime offsetDT2 = OffsetDateTime.parse("1980-04-09T09:50:25+08:00");
LocalDateTime localDT = LocalDateTime.parse("19791209095025", DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
OffsetDateTime offsetDT3 = OffsetDateTime.of(localDT, ZoneOffset.of("+07:00"));
System.out.println("OffsetDateTime1 after OffsetDateTime2 : " + offsetDT1.isAfter(offsetDT2));
System.out.println("OffsetDateTime1 before OffsetDateTime2 : " + offsetDT1.isBefore(offsetDT2));
System.out.println("OffsetDateTime1 equal OffsetDateTime3 : " + offsetDT1.isEqual(offsetDT3));
System.out.println("OffsetDateTime2 equal OffsetDateTime3 : " + offsetDT2.isEqual(offsetDT3));
System.out.println("OffsetDateTime1 compareTo OffsetDateTime2: " + offsetDT1.compareTo(offsetDT2));
System.out.println("OffsetDateTime2 compareTo OffsetDateTime1: " + offsetDT2.compareTo(offsetDT1));
System.out.println("OffsetDateTime1 compareTo OffsetDateTime3: " + offsetDT1.compareTo(offsetDT3));
System.out.println("OffsetDateTime3 compareTo OffsetDateTime2: " + offsetDT3.compareTo(offsetDT2));
}
}
OffsetDateTime1 after OffsetDateTime2 : false OffsetDateTime1 before OffsetDateTime2 : true OffsetDateTime1 equal OffsetDateTime3 : true OffsetDateTime2 equal OffsetDateTime3 : false OffsetDateTime1 compareTo OffsetDateTime2: -1 OffsetDateTime2 compareTo OffsetDateTime1: 1 OffsetDateTime1 compareTo OffsetDateTime3: 0 OffsetDateTime3 compareTo OffsetDateTime2: -1
Supported Field and Unit of an OffsetDateTime
Use isSupported(...) to check if a particular field/unit is supported in an OffsetDateTime:
- 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.OffsetDateTime;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
public class OffsetDateTimeIsSupportedExample {
public static void main(String[] args) {
OffsetDateTime offsetDT = OffsetDateTime.now();
System.out.println("*** ChronoField ***");
for(ChronoField chronoField : ChronoField.values()){
System.out.println(chronoField + " is supported:" + offsetDT.isSupported(chronoField));
}
System.out.println("\n*** ChronoUnit ***");
for(ChronoUnit chronoUnit : ChronoUnit.values()){
System.out.println(chronoUnit + " is supported:" + offsetDT.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