Tutorial for Changing Date and Time with Java – Part Two
First try at a Java solution
Continue the web design course about setting up your code. Based on information in the Javadocs and on the DateTest class’s output, I figured my best bet was to set the default time zone when the JVM first started.
To that end, I created an Initializer class I could run when my application launched. Here is my first effort:
import java.util.TimeZone;
import java.util.SimpleTimeZone;
public class ItsInitializer {
private static boolean s_initialized = false;
private ItsInitializer() {
}
public static synchronized void initialize() {
if (!s_initialized) {
// Modifies the default time zone, disables the Daylight Saving Time.
SimpleTimeZone dtz = (SimpleTimeZone) TimeZone.getDefault();
dtz.setStartRule(0,0,0,0);
dtz.setEndRule(0,0,0,0);
TimeZone.setDefault(dtz);
s_initialized = true;
}
}
}
In other words, I change the JVM’s default TimeZone so it doesn’t have DST rulesand won’t try to make an adjustment. (Its in the code above is an abbreviation for my employer’s name, InterSystems.)
Then J2SE 1.4 came out and I upgraded. Bang! ItsInitializer no longer worked.
I immediately investigated. Here is the DateTest class’s output for J2SE 1.4.1_01 on Windows 98:
Date = Tue May 06 05:31:03 IDT 2003
Calendar = java.util.GregorianCalendar[time=1052188263870,areFieldsSet=true,
areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id=”Asia/Jerusalem”,
offset=7200000,dstSavings=3600000,useDaylight=true,transitions=143,lastRule=
java.util.SimpleTimeZone[id=Asia/Jerusalem,offset=7200000,dstSavings=3600000,
useDaylight=true,startYear=0,startMode=1,startMonth=3,startDay=1,startDayOfWeek=
0,startTime=3600000,startTimeMode=0,endMode=1,endMonth=9,endDay=1,
endDayOfWeek=0,endTime=3600000,endTimeMode=0]],firstDayOfWeek=1,minimal
DaysInFirstWeek=1,ERA=1,YEAR=2003,MONTH=4,WEEK_OF_YEAR=19,
WEEK_OF_MONTH=2,DAY_OF_MONTH=6,DAY_OF_YEAR=126,DAY_OF_WEEK
=3,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=5,HOUR_OF_DAY=5,
MINUTE=31,SECOND=3,MILLISECOND=870,ZONE_OFFSET=
7200000,DST_OFFSET=3600000]
As you can see, the zone member in class TimeZone in J2SE 1.4 is no longer a
SimpleTimeZone instance. The sun.util.calendar.ZoneInfo class has replaced it.
Thus, I needed to change ItsInitializer to be compatible with J2SE 1.4:
import java.util.TimeZone;
import java.util.SimpleTimeZone;
public class ItsInitializer {
private static boolean s_initialized = false;
private ItsInitializer() {
}
public static synchronized void initialize() {
if (!s_initialized) {
// Modifies default time zone, disables Daylight Saving Time.
TimeZone l_defaultTimeZone = TimeZone.getDefault();
int l_rawOffset = l_defaultTimeZone.getRawOffset();
String l_id = l_defaultTimeZone.getID();
SimpleTimeZone l_simpleTimeZone = new SimpleTimeZone(l_rawOffset,
l_id,
0,
0,
0,
0,
0,
0,
0,
0);
TimeZone.setDefault(l_simpleTimeZone);
s_initialized = true;
}
}
}
I create a new SimpleTimeZone instance that doesn’t have a DST rule and assign it as the JVM’s default TimeZone.
The second implementation is better than the first because it assumes nothing about the actual Class of the zone member in class Calendar.
Note that this second version is also backward compatible—it works well with J2SE 1.3
There’s nothing like learning from experience, and I was going to gain even more experience before I finally resolved this issue.
I figured that during Daylight Saving Time, we always physically adjust the computer clock, so we never need to adjust for DST, and therefore always set the default time zone in the JVM without DST rules. Problem solved.
We happily continued developing our applications using the above strategy, and everything was fine. No more date and time discrepancies. When winter came and we physically readjusted our computer clocks back again, we still didn’t experience problems with incorrect dates and times in our application, thanks to the good old ItsInitializer class.
But, as I discovered later on, I had made another mistake, and it was inevitably oing to come back and bite me.
An unforeseen obstacle
Winter passed and summer came again, and with it, naturally, came Daylight Saving Time. No problem, I thought. Been there, done that.
On the very day we moved to DST, I got timestamp discrepancies. What happened?
This year, we didn’t physically adjust our computer clocks. We had configured our Sun computer so that we didn’t need to physically adjust the system clock. date is the Unix/Linux command for displaying the current system date and time. date’s Solaris version uses timezone configuration files that help it to automatically adjust the display for DST— similar to how Java’s Calendar class works.
So, if the timezone configuration files are installed, you don’t need to physically adjust your system clock. I believe Linux behaves in a similar way. Also, our Windows machines were now running Windows XP, and here again, we didn’t physically adjust the system clocks, since you can configure the time zone in Windows XP as well.
The problem is some time zones have the option of automatic daylight savings adjustment and some don’t, as shown in Figures 1 and 2 below.
zone with automa
Figure 2. Time zone without automatic DST adjustment
Rather than use our “real” time zone (Jerusalem), we used a time zone with the same difference from Greenwich Mean Time (GMT) as us, but with automatic DST adjustment capability, namely Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius.
On the Solaris operating system, you configure your locale data, including your time zone, in the /etc/TIMEZONE file. Our /etc/TIMEZONE file contains:
TZ=Israel
Israel is the name of a file in directory /usr/share/lib/zoneinfo/Asia. The /usr/share/lib/zoneinfo directory contains all the time zone data for all the different time zones in the world. This data is divided into files where each file has the data for a specific world region. Israel is the file with the time zone data for Israel.
This file contains the DST rules: when DST starts each year, when it ends, and by how much to adjust the clocks. In Israel, as in other places around the world, DST begins at a different time each year. This is partly due to the fact that we use the Hebrew calendar (as well as the Gregorian calendar), and partly due to Israeli politics.
In any case, up-to-date time zone information for different world regions is available on the Internet. One such Website is twinsun.com. Note that these files are data files and not text files. You cannot open them in your favorite text editor or word processor and study their contents.
However, for those interested, some Websites have the source data from which the time zone data files are created (see Resources). There are some open source Java classes for web designers that can read and interpret the time zone data files’ content.