Set your Java clocks for the new DST

Solutions for adjusting your Java clock during time changes

When the DST (Daylight Saving Time) period starts or ends, do your Java-powered applications show the wrong time of day or even malfunction? Do your department managers and system administrators break out in a cold sweat whenever they hear "Java" in relation to a clock change? Are your production applications too mission critical to tolerate any downtime or data inconsistencies? Does your application business logic relate to U.S., Israel, or Brazil time zones? Do you want to prevent your application from running one hour behind other applications and services from March 11 till April 1, 2007 due to the new changes in U.S. DST rules?

If you find yourself answering yes to one or more of the previous questions, continue reading to understand how the Java platform handles time, time zones, and DST rules, and what you can do to keep your Java production systems up and running while protected from DST rule changes.

Operating systems' time zone and DST implementation

In ancient times, an OS administrator would have to manually set the clock for DST; nowadays, operating systems have an internal automatic mechanism for time zones and DST clock adjustments. This mechanism's moving cogs are the machine hardware clock, the operating system's local time zone setting, and the OS zoneinfo database, also called the tz database (TZDB).

Machine clocks are always kept in sync with the GMT/UTC, (Greenwich Mean Time/ Coordinated Universal Time; I use these terms interchangeably) using the NTP, or Network Time Protocol. Thus, in practice, all of the world's servers hold the same universal time.

But users don't care about GMT; they are more concerned with their local time. To compute the correct local time, the OS needs to know the local time zone in which it operates (OS local time zone settings) and have access to the information provided in the TZDB, which holds international time zone information and DST rules. With this information, the OS can compute and serve the correct local date and time to the user or to a process.

On Linux, the date command (with no arguments) will return local time compute as: GMT_TIME + LOCAL_TIME_ZONE_OFFSET + DST_OFFSET. (If you want to see the bare GMT time with no time zone adjustments use date -u).

The TZDB is a binary compilation of human readable text files; it is your OS administrator's responsibility to make sure that the TZDB is updated.

The local time zone file is:

  • In Linux: /etc/TIMEZONE
  • In Unix: /etc/localtime

The TZDB resides on:

  • In Linux: /usr/share/zoneinfo/
  • In Unix: /usr/share/lib/zoneinfo/

Java time zone and DST implementation

I came across Java's DST issue when I was providing application server consulting services for a large Israeli telecom operator. My client had been experiencing many application clock problems around the start and end of the DST period, complaining that the "Java clock," with a mind of its own, wouldn't make the hour shift alongside the OS clock.

Sun's Java Runtime Environment/JDK doesn't use the OS TZDB; instead, it has its own implementation of time zone information and DST rules. The JRE versions 1.4 and 1.5 implement the time zone and DST definitions in a similar fashion to Unix/Linux. And although the binary formats of an OS's TZDB and Java's time zone information differ, they are both compiled from the same TZDB text files.

On all platforms, Java's TZDB can be found at ${JRE_HOME}/lib/zi/. Version 1.3.X has its TZDB implementation hard-coded into its time framework classes.

The BEA JRockit JVM seems to use the same TZDB as Sun's JVM (keeping things compatible and simple), while IBM's JVM doesn't have a TZDB directory (even for 1.4.X versions).

As you are about to see next, the fact that the TZDB directory is decoupled from the JVM's classes and code can save us a lot of headaches.

The problem: A stale TZDB

Java's TZDB specification is quite flexible; it can apply a different DST rule for each year for each time zone (e.g., the U.S.'s 2007 DST rule will differ from the 2006 rule). The problems start when local governments unexpectedly change future DST rules, thus making the current DST rules in Java's TZDB obsolete. In countries like Israel and Brazil, this problem occurs almost yearly. Australia had the same problem when it changed its local DST settings in 2006 (see "Australian Time Zone Changes Affect Java Applications"). U.S. time zone DST rules will also become outdated due to the Energy Policy Act of 2005 (see "U.S. Daylight Saving Time Changes in 2007"): staring in 2007, the U.S. DST will last one month longer.

An outdated DST rule causes the JVM to add/subtract the DST time "delta" (usually one hour) at the wrong point in time, either sooner or later than expected. This will cause the JVM, and hence the application, to be out of sync with the underlying OS time (assuming the OS TZDB is updated) and other outside services, which can produce unexpected results ranging from an incorrect timestamp log entry to certain services ceasing to operate, or even a complete application failure.

So now that you are fully convinced that an updated TZDB is a desired goal, what can we do to keep it updated?

1 2 Page 1
Page 1 of 2