Java和时区(Time zones and Java)
Time zones and Java
Java应用程序的时区,默认地取user.timezone系统属性,如果没有定义,那么结合user.country和java.home系统属性取一个时区ID,如果不成功则用GMT作为缺省时区
Java is similar to Solaris when it comes to time zone information. A zone ID identifies each time zone. This ID is a String
, and in J2SE 1.3 and 1.4, the tzmappings
file, which is located in the J2SE installation's jre/lib
subdirectory, stores the list of IDs. J2SE 1.3 only contains the tzmappings
file, but J2SE 1.4 also contains the actual time zone data files for various world regions. The jre/lib/zi
subdirectory stores these files. In J2SE 1.4, the sun.util.calendar.ZoneInfo
class gets its DST rules from these files. Also, as with Solaris, these time zone data files are binary data files, not text files, so you can't look at them. Note that the time zone data in J2SE 1.4 is different from that in Solaris.
The source code for the java.util.TimeZone
class's getDefault
method shows it eventually invokes the sun.util.calendar.ZoneInfo
class's getTimeZone
method. This method takes a String
parameter that is the ID for the required time zone. The default time zone ID is obtained from the user.timezone
(System
) property. If the user.timezone
property is not defined, it tries to get the ID using a combination of the user.country
and java.home
(System
) properties. If it doesn't succeed in finding a time zone ID, it uses a "fallback" GMT value. In other words, if it can't figure out your time zone ID, it uses GMT as your default time zone.
Note that the System
properties are initialized in the java.lang.System
class's initProperties
method. This is a native method, so the source code is unavailable—unless you want to dig into the native code libraries that come with the J2SE distribution. However, I believe that the System
properties are initialized from the Windows registry on Windows systems and from environment variables on Linux/Unix systems. The initProperties
method's Javadoc claims that certain properties are "guaranteed to be defined" and lists them. Of the three System
properties used by the java.util.TimeZone
class's getDefault
method, only java.home
is listed as a guaranteed property in the Javadoc.
The (proposed) solution
So how do you ensure Java gives you the correct date and time? In my opinion, the best way is to make sure the JVM's default TimeZone
class is correct and suitable for your locale. How you ensure the default TimeZone
is correct and suitable is a different question. Like most problems in computing, this one has several possible solutions. According to the source code for the java.util.TimeZone.getDefault
method, the best way is to set the user.timezone
property correctly. You can easily override the value set in the java.lang.System.initProperties
method by using the -D
command-line option when launching your JVM, for example:
java -Duser.timezone=Asia/Shanghai DateTest
This command launches the DateTest
class (listed at the beginning of this article) and sets the user.timezone
property to Asia/Shanghai
. You can also set the user.timezone
property by using the java.lang.System
class's setProperty
method:
System.setProperty("user.timezone","Asia/Jerusalem");
If none of the available time zone IDs is suitable for you, then you can create a custom TimeZone
and set it as the default time zone using the java.util.TimeZone
class's setDefault
method—as I did in my ItsInitializer
class previously listed in this article.
Remember, most time- and date-related classes in J2SE contain time zone information, including the formatting classes, like java.text.DateFormat
, so they are all affected by the JVM's default time zone. While you can ensure correct time zone information for these classes when you create instances of them, it's easier to set the default time zone for the entire JVM once, which ensures that all these classes will use the same default time zone. But, as they say in the classics, "your mileage may vary" (YMMV).
So get to it and tame those date/time Java classes!
Author Bio
Avi Abrami works as a senior software engineer at InterSystems, a company that develops airport information systems in Java using J2SE/J2EE. He has been writing software since 1989, and writing in Java since 1999. He has a bachelor's degree in education and a graduate diploma in computer studies. He is married with three children (and a dog) and lives in Israel.
Resources
- Sources for time zone and Daylight Saving Time data
http://www.twinsun.com/tz/tz-link.htm - zoneinfo source files
http://openbsd.secsup.org/src/share/zoneinfo - Java Notes
http://www.bmsi.com/java/#TZ - "Calculating Java Dates," Robert Nielsen (JavaWorld, December 2000)
http://www.javaworld.com/jw-12-2000/jw-1229-dates.html - "Working in Java Time," Robert Nielsen (JavaWorld, March 2001)
http://www.javaworld.com/javaworld/jw-03-2001/jw-0330-time.html - Browse the Java 2 Platform, Standard Edition (J2SE) section of JavaWorld's Topical Index
http://www.javaworld.com/channel_content/jw-j2se-index.shtml - Visit the JavaWorld Forum
http://www.javaworld.com/javaforums/ubbthreads.php?Cat=&C=2 - Sign up for JavaWorld's free weekly email newsletters
http://www.javaworld.com/subscribe