I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE COURSE

1. Introduction

In our world, each country follows a certain time-zone. These time-zones are crucial for expressing time conveniently and effectively. However, time-zones can sometimes be inexplicit due to variables such as daylight saving time, coming into the picture.

Moreover, while representing these time-zones in our code, things can get confusing. Java has provided multiple classes such as Date, Time and DateTime in the past to also take care of time-zones.

However, new Java versions have come up with more useful and expressive classes such as ZoneId and ZoneOffset, for managing time-zones.

In this article, we’ll discuss ZoneId and ZoneOffset as well as related DateTime classes.

We can also read about the new set of DateTime classes introduced in Java 8, in our previous post.

2. ZoneId and ZoneOffset

With the advent of JSR-310, some useful APIs were added for managing date, time and time-zones. ZoneId and ZoneOffset classes were also added as a part of this update.

2.1. ZoneId

As stated above, ZoneId is a representation of the time-zone such as ‘Europe/Paris‘.

There are 2 implementations of ZoneId. First, with a fixed offset as compared to GMT/UTC. And second, as a geographical region, which has a set of rules to calculate the offset with GMT/UTC.

Let’s create a ZoneId for Berlin, Germany:

ZoneId zone = ZoneId.of("Europe/Berlin");

2.2. ZoneOffset

ZoneOffset extends ZoneId and defines the fixed offset of the current time-zone with GMT/UTC, such as +02:00.

This means that this number represents fixed hours and minutes, representing the difference between the time in current time-zone and GMT/UTC:

LocalDateTime now = LocalDateTime.now();
ZoneId zone = ZoneId.of("Europe/Berlin");
ZoneOffset zoneOffSet = zone.getRules().getOffset(now);

In case a country has 2 different offsets – in summer and winter, there will be 2 different ZoneOffset implementations for the same region, hence the need to specify a LocalDateTime.

3. DateTime Classes

Next let’s discuss some DateTime classes, that actually take advantage of ZoneId and ZoneOffset.

3.1. ZonedDateTime

ZonedDateTime is an immutable representation of a date-time with a time-zone in the ISO-8601 calendar system, such as 2007-12-03T10:15:30+01:00 Europe/Paris. ZonedDateTime holds state equivalent to three separate objects, a LocalDateTime, a ZoneId and the resolved ZoneOffset

This class stores all date and time fields, to a precision of nanoseconds, and a time-zone, with a ZoneOffset, to handle ambiguous local date-times. For example, ZonedDateTime can store the value “2nd October 2007 at 13:45.30.123456789 +02:00 in the Europe/Paris time-zone”.

Let’s get the current ZonedDateTime for the previous region:

ZoneId zone = ZoneId.of("Europe/Berlin");
ZonedDateTime date = ZonedDateTime.now(zone);

ZonedDateTime also provides inbuilt functions, to convert a given date from one time-zone to another:

ZonedDateTime destDate = sourceDate.withZoneSameInstant(destZoneId);

3.2. OffsetDateTime

OffsetDateTime is an immutable representation of a date-time with an offset in the ISO-8601 calendar system, such as 2007-12-03T10:15:30+01:00.

This class stores all date and time fields, to a precision of nanoseconds, as well as the offset from GMT/UTC. For example,OffsetDateTime can store the value “2nd October 2007 at 13:45.30.123456789 +02:00”.

Let’s get the current OffsetDateTime with 2 hours of offset from GMT/UTC:

ZoneOffset zoneOffSet= ZoneOffset.of("+02:00");
OffsetDateTime date = OffsetDateTime.now(zoneOffSet);

3.3. OffsetTime

OffsetTime is an immutable date-time object that represents a time, often viewed as hour-minute-second-offset, in the ISO-8601 calendar system, such as 10:15:30+01:00.

This class stores all time fields, to a precision of nanoseconds, as well as a zone offset. For example, OffsetTime can store the value “13:45.30.123456789+02:00”.

Let’s get the currentOffsetTime with 2 hours of offset:

ZoneOffset zoneOffSet = ZoneOffset.of("+02:00");
OffsetTime time = OffsetTime.now(zoneOffSet);

4. Conclusion

Getting back to the focal point, ZoneOffset is a representation of time-zone in terms of the difference between GMT/UTC and the given time. This is a handy way of representing time-zone, although there are other representations also available.

Moreover, ZoneId and ZoneOffset are not only used independently but also by certain DateTime Java classes such as ZonedDateTime, OffsetDateTime, and OffsetTime.

As usual, the code is available in our GitHub repository.

I just announced the new Spring Boot 2 material, coming in REST With Spring:

>> CHECK OUT THE LESSONS