Java OffsetTime Tutorial with Examples

OffsetTime class represent a time with an offset from UTC/Greenwich in the ISO-8601 calendar system, such as 18:30:45+08:00, often viewed as hour-minute-second-offset. This class is immutable and thread-safe, stores all time fields, to a precision of nanoseconds, as well as a zone offset.

Creating an OffsetTime

We can create an OffsetTime in several ways:

OffsetTimeInitExample.java
import java.time.Clock;
import java.time.Instant;
import java.time.OffsetTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class OffsetTimeInitExample {

    public static void main(String[] args) {
        OffsetTime offsetTime1 = OffsetTime.now();
        System.out.println("OffsetTime1: " + offsetTime1);

        OffsetTime offsetTime2 = OffsetTime.now(Clock.systemUTC());
        System.out.println("OffsetTime2: " + offsetTime2);
        
        OffsetTime offsetTime3 = OffsetTime.now(ZoneId.of("Asia/Jakarta"));
        System.out.println("OffsetTime3: " + offsetTime3);
        
        OffsetTime offsetTime4 = OffsetTime.of(20, 15, 45, 345875000, ZoneOffset.of("+07:00"));
        System.out.println("OffsetTime4: " + offsetTime4);
        
        OffsetTime offsetTime5 = OffsetTime.of(LocalTime.of(15, 50, 25), ZoneOffset.of("+07:00"));
        System.out.println("OffsetTime5: " + offsetTime5);
        
        OffsetTime offsetTime6 = OffsetTime.ofInstant(Instant.now(), ZoneId.systemDefault());
        System.out.println("OffsetTime6: " + offsetTime6);
        
        OffsetTime offsetTime7 = OffsetTime.parse("10:15:30+07:00");
        System.out.println("OffsetTime7: " + offsetTime7);
        
        OffsetTime offsetTime8 = OffsetTime.parse("18:30:15+08:00", DateTimeFormatter.ISO_OFFSET_TIME);
        System.out.println("OffsetTime8: " + offsetTime8);
    }
}
                    

OffsetTime1: 00:30:52.313+08:00
OffsetTime2: 16:30:52.314Z
OffsetTime3: 23:30:52.314+07:00
OffsetTime4: 20:15:45.345875+07:00
OffsetTime5: 15:50:25+07:00
OffsetTime6: 00:30:52.315+08:00
OffsetTime7: 10:15:30+07:00
OffsetTime8: 18:30:15+08:00

The time zone offsets are represented by the ZoneOffset class. You can create a ZoneOffset object using the ZoneId.of(...) method.

Getting Information from an OffsetTime

Following methods can be used to access Time information of an OffsetTime:

And following methods can be used to get another class (or convert) from an OffsetTime instance:

OffsetTimeInfoExample.java
import java.time.OffsetTime;
import java.time.temporal.ChronoField;

public class OffsetTimeInfoExample {
    
    public static void main(String[] args) {
        OffsetTime offsetTime = OffsetTime.now();
        System.out.println("OffsetTime      : " + offsetTime);
        System.out.println("Hour            : " + offsetTime.getHour());
        System.out.println("Minute          : " + offsetTime.getMinute());
        System.out.println("Second          : " + offsetTime.getSecond());
        System.out.println("Nano            : " + offsetTime.getNano());
        
        System.out.println("HOUR_OF_DAY     : " + offsetTime.get(ChronoField.HOUR_OF_DAY));        
        System.out.println("MINUTE_OF_HOUR  : " + offsetTime.get(ChronoField.MINUTE_OF_HOUR));
        System.out.println("SECOND_OF_MINUTE: " + offsetTime.get(ChronoField.SECOND_OF_MINUTE));
        System.out.println("NANO_OF_SECOND  : " + offsetTime.get(ChronoField.NANO_OF_SECOND));
        
        System.out.println("MINUTE_OF_DAY   : " + offsetTime.getLong(ChronoField.MINUTE_OF_DAY));
        System.out.println("SECOND_OF_DAY   : " + offsetTime.getLong(ChronoField.SECOND_OF_DAY));
        System.out.println("NANO_OF_DAY     : " + offsetTime.getLong(ChronoField.NANO_OF_DAY));
        
        System.out.println("Offset          : " + offsetTime.getOffset());        
        System.out.println("toLocalTime()   : " + offsetTime.toLocalTime());
    }
}
                    

OffsetTime      : 01:32:45.748+08:00
Hour            : 1
Minute          : 32
Second          : 45
Nano            : 748000000
HOUR_OF_DAY     : 1
MINUTE_OF_HOUR  : 32
SECOND_OF_MINUTE: 45
NANO_OF_SECOND  : 748000000
MINUTE_OF_DAY   : 92
SECOND_OF_DAY   : 5565
NANO_OF_DAY     : 5565748000000
Offset          : +08:00
toLocalTime()   : 01:32:45.748

Add/Subtract Operations on OffsetTime

Following methods used for add/subtract operation in an OffsetTime:

OffsetTimeAddSubstractExample.java
import java.time.Duration;
import java.time.OffsetTime;
import java.time.temporal.ChronoUnit;

public class OffsetTimeAddSubstractExample {

    public static void main(String[] args) {
        OffsetTime offsetTime = OffsetTime.parse("10:15:30+07:00");
        System.out.println("OffsetTime          : " + offsetTime);
        
        // Adding/subtracting hours
        System.out.println("12 hours before     : " + offsetTime.minusHours(12));
        System.out.println("6 hours later       : " + offsetTime.plusHours(6));
        
        // Adding/subtracting minutes
        System.out.println("Minus 40 minutes    : " + offsetTime.minusMinutes(40));
        System.out.println("Plus 15 minutes     : " + offsetTime.plusMinutes(15));
        
        // Adding/subtracting seconds
        System.out.println("Minus 30 seconds    : " + offsetTime.minusSeconds(30));
        System.out.println("Plus 20 seconds     : " + offsetTime.plusSeconds(20));
        
        // Adding/subtracting Nanos
        System.out.println("Minus 20000 nanos   : " + offsetTime.minusNanos(20000));
        System.out.println("Plus 340000 nanos   : " + offsetTime.plusNanos(340000));
        
        // Using HOURS
        System.out.println("8 hours before      : " + offsetTime.minus(8, ChronoUnit.HOURS));
        // Using MINUTES
        System.out.println("35 minutes before   : " + offsetTime.minus(35, ChronoUnit.MINUTES));
        // Using SECONDS
        System.out.println("125 seconds later   : " + offsetTime.plus(125, ChronoUnit.SECONDS));
        // Using NANOS
        System.out.println("42357500 nanos later: " + offsetTime.plus(42357500, ChronoUnit.NANOS));
        
        // Using TemporalAmount - Duration 
        System.out.println("60 days before      : " + offsetTime.minus(Duration.ofDays(60)));
        System.out.println("160 minutes before  : " + offsetTime.minus(Duration.ofMinutes(160)));
        System.out.println("2 hours later       : " + offsetTime.plus(Duration.ofHours(2)));
    }
}
                    

OffsetTime          : 10:15:30+07:00
12 hours before     : 22:15:30+07:00
6 hours later       : 16:15:30+07:00
Minus 40 minutes    : 09:35:30+07:00
Plus 15 minutes     : 10:30:30+07:00
Minus 30 seconds    : 10:15+07:00
Plus 20 seconds     : 10:15:50+07:00
Minus 20000 nanos   : 10:15:29.999980+07:00
Plus 340000 nanos   : 10:15:30.000340+07:00
8 hours before      : 02:15:30+07:00
35 minutes before   : 09:40:30+07:00
125 seconds later   : 10:17:35+07:00
42357500 nanos later: 10:15:30.042357500+07:00
60 days before      : 10:15:30+07:00
160 minutes before  : 07:35:30+07:00
2 hours later       : 12:15:30+07:00

Comparing OffsetTimes

Following methods can be use to compare two OffsetTimes:

OffsetTimeCompareExample.java
import java.time.LocalTime;
import java.time.OffsetTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class OffsetTimeCompareExample {

    public static void main(String[] args) {
        OffsetTime offsetTime1 = OffsetTime.parse("18:30:15+07:00");
        OffsetTime offsetTime2 = OffsetTime.parse("18:30:15+08:00");
        
        LocalTime localTime = LocalTime.parse("183015", DateTimeFormatter.ofPattern("HHmmss"));
        OffsetTime offsetTime3 = OffsetTime.of(localTime, ZoneOffset.of("+07:00"));
        
        System.out.println("OffsetTime1 after OffsetTime2    : " + offsetTime1.isAfter(offsetTime2));
        System.out.println("OffsetTime1 before OffsetTime2   : " + offsetTime1.isBefore(offsetTime2));
        System.out.println("OffsetTime1 equal OffsetTime3    : " + offsetTime1.isEqual(offsetTime3));
        System.out.println("OffsetTime2 equal OffsetTime3    : " + offsetTime2.isEqual(offsetTime3));

        System.out.println("OffsetTime1 compareTo OffsetTime2: " + offsetTime1.compareTo(offsetTime2));
        System.out.println("OffsetTime2 compareTo OffsetTime1: " + offsetTime2.compareTo(offsetTime1));
        System.out.println("OffsetTime1 compareTo OffsetTime3: " + offsetTime1.compareTo(offsetTime3));
        System.out.println("OffsetTime3 compareTo OffsetTime2: " + offsetTime3.compareTo(offsetTime2));
    }
}
                    

OffsetTime1 after OffsetTime2    : true
OffsetTime1 before OffsetTime2   : false
OffsetTime1 equal OffsetTime3    : true
OffsetTime2 equal OffsetTime3    : false
OffsetTime1 compareTo OffsetTime2: 1
OffsetTime2 compareTo OffsetTime1: -1
OffsetTime1 compareTo OffsetTime3: 0
OffsetTime3 compareTo OffsetTime2: 1

Supported Field and Unit of an OffsetTime

Use isSupported(...) to check if a particular field/unit is supported in an OffsetTime:

OffsetTimeIsSupportedExample.java
import java.time.OffsetTime;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;

public class OffsetTimeIsSupportedExample {

    public static void main(String[] args) {
        OffsetTime offsetTime = OffsetTime.now();

        System.out.println("*** ChronoField ***");
        for(ChronoField chronoField : ChronoField.values()){
            System.out.println(chronoField + " is supported:" + offsetTime.isSupported(chronoField));
        }

        System.out.println("\n*** ChronoUnit ***");
        for(ChronoUnit chronoUnit : ChronoUnit.values()){
            System.out.println(chronoUnit + " is supported:" + offsetTime.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:false
AlignedDayOfWeekInMonth is supported:false
AlignedDayOfWeekInYear is supported:false
DayOfMonth is supported:false
DayOfYear is supported:false
EpochDay is supported:false
AlignedWeekOfMonth is supported:false
AlignedWeekOfYear is supported:false
MonthOfYear is supported:false
ProlepticMonth is supported:false
YearOfEra is supported:false
Year is supported:false
Era is supported:false
InstantSeconds is supported:false
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:false
Weeks is supported:false
Months is supported:false
Years is supported:false
Decades is supported:false
Centuries is supported:false
Millennia is supported:false
Eras is supported:false
Forever is supported:false