Java and Time Zones
Here's what I've discovered from playing with the date and time functions
available in Java 1.1 and from reading the class documentation for
java.util.Date, java.text.DateFormat, and java.util.TimeZone (using JAVA.EXE
full version "JDK 1.1.8 IBM build o118-19991204 (JIT enabled: javax
V3.5-IBMJDK1.1-19991204)").
Java always uses GMT, storing both the date and the time as a single
value consisting of the number of milliseconds that have elapsed since January
1, 1970 (not counting leap seconds).
Java parses the system's TZ variable into three parts: The time zone ID,
the standard offset from GMT, and the optional daylight savings indicator.
The time zone ID consists of three (3) characters and is sometimes called a
triliteral (but not by Java). The java.util.Date class recognizes the time zone
IDs listed here (a parenthetical D follows the time zone IDs that Java applies
daylight savings time to): GMT, UTC, ECT (D), EET (D), ART (D), EAT, MET (D),
NET, PLT, IST (D), BST, VST, CTT, JST, AET, SST, MIT, HST, AST (D), PST (D),
PNT, MST (D), CST (D), EST (D), IET, CNT (D), AGT, and BET (D). The
java.util.TimeZone class also recognizes ACT, NST, PRT, and CAT. All time zone
IDs must be in upper case in order to be recognized by Java.
The standard offset from GMT is the negative offset between GMT and local
time when daylight savings time is notin effect (the offset being the
value that must be added to the GMT time in order to obtain the local time).
For example, the time zone that I am in is the US eastern standard zone (EST)
with daylight savings (EDT). When daylight savings is not in effect, if GMT is
13:30:00, then EST is 8:30:00, which is 5 hours behind (i.e., -5:00), which
results in a TZ offset of 5 (or +5, if the optional + sign is used).
The daylight savings indicator is only used to indicate that the local time
zone uses daylight savings time. It is not used to display the daylight savings
time zone ID. For example, I can set my OS/2 TZ variable to "EST5EDT" or
"EST5Z" and still get the correct time and daylight savings time zone ID
reported by Date.toString during daylight savings time.
There are two ways to obtain a human readable representation of the local
time in Java. One is to use the toString method in the Date class. The other is
to use the DateFormat class, which uses the TimeZone class.
Java obtains the GMT time by asking the system for the local time and then
adding the offset value that it derived from the TZ setting, adjusting for
daylight savings time if the optional daylight savings time indicator is
present in the TZ variable and daylight savings time is in effect.
The toString method returns the local date and time using six (6) fields.
The fields are as follows, in order for the US locale: Abbreviated day of week
name, abbreviated month name, 2-digit day of month, 24 hour time as hh:mm:ss,
time zone, and 4-digit year. For example: "Sat May 09 15:11:30 EDT 1998". Note:
The reported time zone is the "official" time zone, not the arbitrary time zone
ID. For example, if you have "TZ=EET-2ART", then the time zone is reported as
"GMT+03:00" if daylight savings are in effect, otherwise "GMT+02:00".
The DateFormat class is very flexible in reporting either the local time or
the time in any time zone supported by Java. If you tell it to report the time
zone ID, it does it in the same way as Date.toString(). You can also have it
report the full name of the time zone.
Java provides a SimpleTimeZone class that Java programmers can use to
provide extended time zone support, including when the daylight savings time
starts and ends. Unfortunately, Java does not use this class for its own
default time zone support. Java program users can only hope that programmers
who decide to use this class in their Java programs will do so by parsing the
system's extended TZ variable, so that if the daylight savings start and end
times change, it will only be necessary to change that information in one place.
The format for the extended TZ variable should be SET TZ=<time zone
ID><inverse GMT offset><daylight time zone ID>,<start
month>,<start day in month>,<start day of week>,<start
time in seconds>,<end month>,<end day in month>,<end day of
week>,<end time in seconds>,<daylight savings offset in
seconds>, which maps readily to the
SimpleTimeZone(int,String,int,int,int,int,int,int,int,int) constructor
(programmers: remember to subtract 1 from the months). An example for a time
zone with a 10 hour offset with a 1 hour daylight savings offset from the last
Sunday in October through the last Sunday in March (i.e., parts of Australia)
would be:
SET TZ=EST-10EDT,10,-1,0,7200,3,-1,0,7200,3600
SET TZ=EST-10EDT,10,-1,0,7200,3,-1,0,7200,3600
Show Current Date and Time Applet
The Java program
that I wrote for my testing can be downloaded in a ZIP file that has both the
ShowTime.java source file and the ShowTime.class run-time file. It uses no
windows, writing its output to the Java console instead. It first outputs a
table of all available TimeZone IDs, the default offset from GMT, if the
TimeZone uses daylight savings time, the time zone's representation of 13:00:00
local time for January 1, 1998 and for June 1, 1998. Finally, it outputs the
local time twice. Once using Date.toString and then using the DateFormat class.
To run the program, use either "java ShowTime" or "jre ShowTime" from a command
line prompt in the directory that you extracted the extract the contents of
showtime.zip into.
RFC822 Date Header Applet
I also wrote another Java program
that outputs the local time using the RFC822 date/time format as updated by
RFC 1123 (use 4-digit years instead of using 2-digit years) and RFC 2156 (use
numeric time zone offsets from GMT/UT instead of using time zone IDs). To run
the program, use either "java RFC822DT" or "jre RFC822DT" from a command line
prompt in the directory that you extracted the extract the contents of
showtime.zip into.