1. ZonedDateTime class

There is another very interesting class in the Date Time API: the ZonedDateTime class. Its main purpose is to make it convenient to work with dates in different time zones.

LocalDate is great for representing dates. For example, birthdays. My birthday is March 15th no matter where I am. This is an example of a date.

LocalTime is great to describe time, like the time set on an alarm clock: I set the alarm for 5:00 am and it doesn't matter where I am. 5:00 am is 5:00 am. This is an example of working with time.

Now let's say that we're writing an application that books flights. Planes take off and arrive based on the local time. The plane is in the air for a fixed time, but the time zones can change.

Time zones

By the way, time zones are a real mess. And if you think that there are 24 time zones, you are greatly mistaken.

For example, the time in India differs from Greenwich Mean Time by five and a half hours: GMT+5:30. Some countries switch to daylight saving time, and others do not. What's more, different countries switch to summer time at different times of the year.

And some countries pass laws that cancel daylight saving time, or reintroduce it, or cancel it again.

In any event, the world has time zones, and within each time zone there is one time. Time in different zones may coincide during certain periods of the year, and then differ during other periods. Time zones are usually named after major cities located in them: Europe/Monaco, Asia/Singapore, but there are also exceptions — US/Pacific.

Officially, there are 599 time zones at the moment. Think about it: 599. That's far from 24. Welcome to the global world.

The ZoneId class from the java.time package is used to store a time zone in Java.

By the way, it has a static getAvailableZoneIds() method, which returns the set of all currently known time zones. To get a list of all zones, you need to write the following code:

Code Console output (partial)
for (String s: ZoneId.getAvailableZoneIds())
   System.out.println(s);
Asia/Aden
America/Cuiaba
Etc/GMT+9
Etc/GMT+8

To get a ZoneId object by its name, you need to use the static of() method;

Code Note
ZoneId zone = ZoneId.of("Africa/Cairo");
Cairo


2. Creating a ZonedDateTime object

When creating a ZonedDateTime object, you need to call the class's static now() method and pass a ZoneId object to it.

Code Console output
ZoneId zone = ZoneId.of("Africa/Cairo");
ZonedDateTime time = ZonedDateTime.now(zone);
System.out.println(time);


2019-02-22T11:37:58.074816+02:00[Africa/Cairo]

If you don't pass a ZoneId object to the now() method (and that is allowed), then the time zone is determined automatically based on the settings of the computer that is running the program.

Example:

Code Console output
ZonedDateTime time = ZonedDateTime.now();
System.out.println(time);

2019-02-22T13:39:05.70842+02:00[Europe/Helsinki]

Converting a global date to a local one

One of the interesting features of ZonedDateTime is its ability to convert to a local date and time. Example:

ZoneId zone = ZoneId.of("Africa/Cairo");
ZonedDateTime cairoTime = ZonedDateTime.now(zone);

LocalDate localDate = cairoTime.toLocalDate();
LocalTime localTime = cairoTime.toLocalTime();
LocalDateTime localDateTime = cairoTime.toLocalDateTime();

3. Working with time

Like the LocalDateTime class, the ZonedDateTime class has lots of ways to get individual elements of a date and time. Here is a list of these methods:

int getYear()
Returns the year of a specific date
Month getMonth()
Returns the date's month: one of several constants — JANUARY, FEBRUARY, ...;
int getMonthValue()
Returns the index of the date's month. January == 1
int getDayOfMonth()
Returns the index of the day of the month
DayOfWeek getDayOfWeek()
Returns the day of the week: one of several constants — MONDAY, TUESDAY, ...;
int getDayOfYear()
Returns the index of the day of the year
int getHour()
Returns the hours
int getMinute()
Returns the minutes
int getSecond()
Returns the seconds
int getNano()
Returns the nanoseconds

All the methods are perfectly analogous to the methods of the LocalDateTime class. And, of course, the ZonedDateTime class has methods that let you work with dates and times. That said, the object on which the methods are called does not change. Instead, they return a new ZonedDateTime object:

Methods Description
plusYears(int)
Adds years to the date
plusMonths(int)
Adds months to the date
plusDays(int)
Adds days to the date
plusHours(int)
Adds hours
plusMinutes(int)
Adds minutes
plusSeconds(int)
Adds seconds
plusNanos(int)
Adds nanoseconds
minusYears(int)
Subtracts years from the date
minusMonths(int)
Subtracts months from date
minusDays(int)
Subtracts days from the date
minusHours(int)
Subtracts hours
minusMinutes(int)
Subtracts minutes
minusSeconds(int)
Subtracts seconds
minusNanos(int)
Subtracts nanoseconds

We won't provide any examples, since we think everything here is clear by analogy with the classes we just considered.