Time zones in the Java Date and Time API
October 1, 2017 Leave a comment
Introduction
I know for a fact that all programmers love working with time zones. Chances are high that you, as a reader of this blog, are also a programmer so I bet you also just love time zones. Let’s see what Java 8 offers as far as time zones are concerned.
Time zones
So far in this series on the date and time in Java 8 we always worked with the local time zone found on your computer. All date-related classes, such as LocalTime or LocalDateTime allow you to easily set the time zone. Here’s an example with the LocalDateTime class:
ZoneId zoneId = ZoneId.of("Europe/Budapest"); LocalDateTime now = LocalDateTime.now(zoneId);
Where are these string values coming from? They follow what Internet Assigned Numbers Authority (IANA) has in its database. That page doesn’t offer a readable list of time zones, they are only available in compressed .tar.gz files. In case you don’t want to deal with those you can find the time zones on Wikipedia.
You can get the full list of time zones in Java 8 as follows:
Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
There’s support for 586 time zones which should be enough for all cases.
You can view the default time zone of your environment like this:
ZoneId systemDefault = ZoneId.systemDefault();
…which in my case returned “Europe/Berlin”.
Setting the time zone will also take care of the summer and winter time adjustments automatically.
ZonedDateTime
What if you want to set the parts of the date individually and set the time zone at the same time? We need to turn to the ZonedDateTime class. The static “of” method has many overloads for granular access. Here’s an example that takes a LocalDateTime instance and a ZoneId, we convert the Budapest time to the Brisbane time zone:
ZoneId zoneId = ZoneId.of("Europe/Budapest"); LocalDateTime now = LocalDateTime.now(zoneId); ZoneId brisbane = ZoneId.of("Australia/Adelaide"); ZonedDateTime zonedDate = ZonedDateTime.of(now, brisbane);
Here’s another example that builds a zoned time out of LocalDate and LocalTime:
ZoneId canadaTz = ZoneId.of("Canada/Central"); LocalDate canadaDate = LocalDate.of(2014, Month.MARCH, 15); LocalTime canadaTime = LocalTime.of(13, 24, 12); ZonedDateTime canadaZonedTime = ZonedDateTime.of(canadaDate, canadaTime, canadaTz);
The ZonedDateTime class behaves in much the same way as LocalDateTime and has very similar methods, like “plus”, “minus”, “get” etc. I won’t repeat them here, you can check out the following posts to see how they behave:
- The Instant class
- The LocalDate class
- The LocalTime class
- The LocalDateTime class
You can find the difference in minutes between two zoned times as follows:
ZoneId canadaTz = ZoneId.of("Canada/Central"); LocalDate canadaDate = LocalDate.of(2014, Month.MARCH, 15); LocalTime canadaTime = LocalTime.of(13, 24, 12); ZonedDateTime canadaZonedTime = ZonedDateTime.of(canadaDate, canadaTime, canadaTz); ZoneId santoDomingoTz = ZoneId.of("America/Santo_Domingo"); LocalDate santoDomingoDate = LocalDate.of(2014, Month.MARCH, 15); LocalTime santoDomingoTime = LocalTime.of(13, 24, 12); ZonedDateTime santoDomingoZonedTime = ZonedDateTime.of(santoDomingoDate, santoDomingoTime, santoDomingoTz); long until = santoDomingoZonedTime.until(canadaZonedTime, ChronoUnit.MINUTES);
“until” will be 60 minutes at the time of writing this post as Canada observes Daylight Saving Time whereas Dominica in the Caribbean region does not. “until” will be 120 minutes as soon as DST is over.
You can easily switch the time zone of a ZonedDateTime instance:
ZonedDateTime converted = santoDomingoZonedTime.withZoneSameInstant(ZoneId.systemDefault());
View the next post here which takes up formatting zoned date times.
View all posts related to Java here.