About Johannes Brodwall

Johannes is the chief scientist of the software offshore company Exilesoft. He's got close to 15 years programming Java, C# and a long time ago other languages as well. He believes that programming is about more than just writing the code, but that too many people lose touch with the coding as well. He has been organizing software development activities in Oslo for many years. In addition, he often speaks at conferences all over Europe.

The lepidopterist’s curse: Playing with java.time

Pop quiz: What will be the output of this little program?
 
 
 
 
 
 
 
 
 
 

public class DateFun {
 
    public static void main(String[] args) {
        long hours = getHoursOfDay(LocalDate.now(), ZoneId.systemDefault());
        System.out.println(hours);
    }
 
    private static long getHoursOfDay(LocalDate date, ZoneId zoneId) {
        ZonedDateTime startOfDay = date.atStartOfDay(zoneId);
        Duration duration = Duration.between(startOfDay, startOfDay.plusDays(1));
        return duration.toHours();
    }
}

The answer is, like with most interesting questions, “it depends”. How can it depend? Well, let’s try a few examples:

  • getHoursOfDay(LocalDate.of(2014, 7, 15), ZoneId.of("Asia/Colombo")) returns 24. As expected
  • getHoursOfDay(LocalDate.of(2014, 7, 15), ZoneId.of("Europe/Oslo")) also returns 24.
  • But here comes a funny version: getHoursOfDay(LocalDate.of(2014, 3, 30), ZoneId.of("Europe/Oslo")) returns 23! This is daylight saving time.
  • Similarly: getHoursOfDay(LocalDate.of(2014, 10, 26), ZoneId.of("Europe/Oslo")) also returns 25
  • And of course, down under, everything is upside down: getHoursOfDay(LocalDate.of(2014, 10, 5), ZoneId.of("Australia/Melbourne")) gives 23.
  • Except, of course, in Queensland: getHoursOfDay(LocalDate.of(2014, 10, 5), ZoneId.of("Australia/Queensland")) => 24.

Daylight saving hours: The bane of programmers!

Daylight saving hours were instituted with the stated purpose of improving worker productivity by providing more working hours with light. Numerous studies have failed to prove that it works as intended.

Instead, when I examined the history of daylight saving hours in Norway, it turns out that it was lobbied by a golfer and a butterfly collector (“lepidopterist”) so that they could better pursue their hobbies after working hours. Thus the name of this blog post.

Most of the time, you can ignore daylight saving hours. But when you can’t, it can really bite you in the behind. For example: What does the hour by hour production of a power plan look like on the day that changes from daylight saving hours to standard time? Another example given to me by a colleague: TV schedules. It turns out that some TV channels just can’t be bothered to show programming during the extra hour in the fall. Or they will show the same hour of programming twice.

The Joda-Time API and now, the Java 8 time API java.time can help. If you use it correctly. Here is the code to display a table of values per hour:

void displayHourlyTable(LocalDate date, ZoneId zoneId) {
    ZonedDateTime startOfDay = date.atStartOfDay(zoneId);
    ZonedDateTime end = startOfDay.plusDays(1);
 
    for (ZonedDateTime current = startOfDay; current.isBefore(end); current = current.plusHours(1)) {
        System.out.println(current.toLocalTime() + ": " + current.toInstant());
    }
}

Given 2014/10/26 and Oslo, this prints:

00:00: 2014-10-25T22:00:00Z
01:00: 2014-10-25T23:00:00Z
02:00: 2014-10-26T00:00:00Z
02:00: 2014-10-26T01:00:00Z
03:00: 2014-10-26T02:00:00Z
....

And on 2014/3/30, it prints:

00:00: 2014-03-29T23:00:00Z
01:00: 2014-03-30T00:00:00Z
03:00: 2014-03-30T01:00:00Z
04:00: 2014-03-30T02:00:00Z
....

So, if you ever find yourself writing code like this: for (int hour=0; hour<24; hour++) doSomething(midnight.plusHours(hour)); you may want to reconsider! This code will (probably) break twice a year.

At the face of it, time is an easy concept. When you start looking into the details, there’s a reason that the java.time library contains 20 classes (if you don’t count the subpackages). When used correctly, time calculations are simple. When used incorrectly, time calculations look simple, but contain subtle bugs.

Next time, perhaps I should ruminate on the finer points of Week Numbers.

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

JPA Mini Book

Learn how to leverage the power of JPA in order to create robust and flexible Java applications. With this Mini Book, you will get introduced to JPA and smoothly transition to more advanced concepts.

JVM Troubleshooting Guide

The Java virtual machine is really the foundation of any Java EE platform. Learn how to master it with this advanced guide!

Given email address is already subscribed, thank you!
Oops. Something went wrong. Please try again later.
Please provide a valid email address.
Thank you, your sign-up request was successful! Please check your e-mail inbox.
Please complete the CAPTCHA.
Please fill in the required fields.

Leave a Reply


six × 8 =



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy | Contact
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below:
Close