Help with Java Time Zones and Dates

In keeping with its WORA (Write Once Run Anywhere) goal, a first for popular programming languages, Java creators realized that "Anywhere" includes a huge list of countries and languages. The internationalization (i18n for short) initiative attempts to deal with getting our programs to run normally regardless of language or country.

C++ programmers writing operating systems and native applications encountered several problems over the past dozen or so years, all of which Java tries to solve:

1. How to localize the display of text by a program?
2. How to localize the display of numbers and currency by a program?
3. How to localize the display of dates and time by a program?

For displayed text, Java offers a convenient API for resource bundles and lists that can be used in combination with the MessageFormat class. For numbers and currency, Java offers wrapper classes for all the primitive number types, organized as subclasses of java.lang.Number, and the remarkable NumberFormat class that looks at the country and language before deciding which currency symbol to use, whether to use comma, dot or space for grouping separators, and so on.

For display of dates and times, Java provides Date to represent an instant in time, the Calendar class (and GregorianCalendar) to do the date math we are familiar with from spreadsheet programs like 1-2-3, and the DateFormat class to display dates and times after first checking the country and language.

In displaying strings or numbers, the user's Java runtime must be pre-set to use a specific language-country combination, known in Java as a locale. But when displaying dates and times, a third independent variable, the time zone, is needed for those large (and populous) countries that span multiple time zones.

Java's i18n code gets these three variables from the client's OS or JVM. Here they are on my system:

  user.language=en
  user.region=US
  user.timezone=PST

Use this applet to show the value of these variables on your own system, followed by the current date and time in the DateFormat.LONG display mode. Note that if your system is correctly set up, the time and date displayed here will be correct for the location of your machine, regardless of whether you're in New Zealand or Canada. The applet then "walks around the world" listing all the available time zone ID's with the current time and date in each time zone. Note how the Java time zone ID's may differ from the usual name for a particular time zone.

It is also important to realize how the same bytecode can produce different times, depending on where it runs. When the local Java code starts running, that is, when the Java Virtual Machine (JVM) starts, the three user.* properties mentioned above (and others) are initialized. If the applet or application needs the user's local time, it is obtained (via the JVM) from the operating system. The JVM converts this value to UTC (coordinated universal time), using the locale and time zone obtained from the local system's properties file.

The question keeps coming up in the Internet newsgroups as to what bug in java accounts for "my system showing the wrong date or time?" In fact a Java user or programmer who gets a wrong default date or time has not (normally) found a bug. If they look, they'll usually find that they have some kind of operating system setting wrong. How can that be? Why aren't native programs displaying the wrong date and time? Well, there are several ways to get the time zone and the actual time setting out of synch. But here's a typical scenario.

You or your retailer buy a computer in San Jose, California. It has MS Windows pre-installed. You then fly back to your home in, for example, Spain. You boot up and find that the time is off by about 10 hours, so you use a graphical or command-line method for resetting the date and time. Now all seems well. All your native applications show the correct date and time.

But now you try to run a Java program that checks or displays the time. Since the pre-install was done in California for sale there, the default properties file for Java will show PST to be the time zone ID. The Java virtual machine cannot know that you moved the machine to Spain, so it adjusts the time it gets from the operating system by some 10 or 11 hours and uses the adjusted value for the current UTC date and time. That value is not UTC but the JVM "thinks it is," so all times displayed by that JVM will be off by 10 or 11 hours.

Even if you reset the language and country to es_ES (Spain) the "user.timezone" will still specify "PST." Clearly, that final step of resetting the time zone, is needed. Unfortunately, each operating system has its own methods for setting locale and time zone. With OS/2 you set the LANG and TZ environment variables. Unix is similar. With Windows it is more complicated and may require you to reboot(check with Microsoft). Good luck!


Your feedback is welcome.

Link to my Programs Page