1. Introduction to TimeZone
TimeZone represents the time zone offset, and can also calculate daylight saving time.
TimeZone is often used when operating objects representing dates/times such as Date, Calendar, etc.; because different time zones have different times.
Let’s talk about two common ways to create TimeZone objects.
1. Get the default TimeZone object
How to use:
TimeZone tz = TimeZone.getDefault()
2. Use the getTimeZone(String id) method to get TimeZone object
How to use:
// Get the time zone corresponding to "GMT+08:00" TimeZone china = TimeZone.getTimeZone("GMT+:08:00");// Get the time zone corresponding to "China/Chongqing" TimeZone chongqing = TimeZone.getTimeZone("Asia/Chongqing"); For the values of all id parameters supported by getTimeZone(String id) you can find them in the following ways:
String[] ids = TimeZone.getAvailableIDs(); for (String id:ids) System.out.printf(id+", ");
Output result:
Etc/GMT+12, Etc/GMT+11, Pacific/Midway, Pacific/Niue... etc.For example, create the TimeZone corresponding to the second print value "Etc/GMT+11" above. The method is as follows:
TimeZone tz = TimeZone.getTimeZone("Etc/GMT+11");TimeZone's function interface // constructor TimeZone():Object clone()synchronized static String[] getAvailableIDs()synchronized static String[] getAvailableIDs(int offsetMillis)int getDSTSavings()synchronized static TimeZone getDefault()final String getDisplayName(Locale locale)String getDisplayName(boolean daylightTime, int style, Locale locale)final String getDisplayName()final String getDisplayName(boolean daylightTime, int style)String getID()abstract int getOffset(int era, int year, int month, int day, int dayOfWeek, int timeOfDayMillis)int getOffset(long time)abstract int getRawOffset()synchronized static TimeZone getTimeZone(String id)boolean hasSameRules(TimeZone timeZone)abstract boolean inDaylightTime(Date time)synchronized static void setDefault(TimeZone timeZone)void setID(String id)abstract void setRawOffset(int offsetMillis)abstract boolean useDaylightTime()
2. TimeZone example:
The following is an example to demonstrate using TimeZone in Date.
The reference code is as follows (TimeZoneTest.java):
import java.text.DateFormat;import java.util.Date;import java.util.TimeZone;/** * TimeZone's test program*/public class TimeZoneTest { public static void main(String[] args) { // Test 3 methods for creating TimeZone object showUsageOfTimeZones(); // Test other APIs of TimeZone testOtherAPIs(); // Print all ids supported by getTimeZone(String id) //printAllTimeZones() ; } /** * Test 3 methods for creating TimeZone objects*/ public static void showUsageOfTimeZones() { TimeZone tz; // (01) Default time zone tz = TimeZone.getDefault(); printDateIn(tz) ; // (02) Set the time zone to "GMT+08:00" tz = TimeZone.getTimeZone("GMT+08:00"); printDateIn(tz) ; // (03) Set the time zone to "" tz = TimeZone.getTimeZone("Asia/Chongqing"); printDateIn(tz) ; } /** * Print the date/time corresponding to tz*/ private static void printDateIn(TimeZone tz) { // date is 2013-09-19 14:22:30 Date date = new Date(113, 8, 19, 14, 22, 30); // Get the default DateFormat for formatting Date DateFormat df = DateFormat.getInstance(); // Set the time zone to tz df.setTimeZone(tz); // Get the formatted string String str = df.format(date); System.out.println(tz.getID()+" :"+str); } /** * Test TimeZone's other APIs */ public static void testOtherAPIs() { // Default time zone TimeZone tz = TimeZone.getDefault(); // Get "id" String id = tz.getID(); // Get "display name" String name = tz.getDisplayName(); // Get "time offset". The offset relative to the "primary meridian" is ms. int offset = tz.getRawOffset(); // Get the corresponding hour of "time offset" int gmt = offset/(3600*1000); System.out.printf("id=%s, name=%s, offset=%s(ms), gmt=%s/n", id, name, offset, gmt); } /** * Print all ids supported by getTimeZone(String id) */ public static void printAllTimeZones() { String[] ids = TimeZone.getAvailableIDs(); for (String id:ids) { //int offset = TimeZone.getTimeZone(avaIds[i]).getRawOffset(); //System.out.println(i+" "+avaIds[i]+" "+offset / (3600 * 1000) + "/t"); System.out.printf(id+", "); } System.out.println(); }}
3. About TimeZone and Time Calibration
Java and Solaris are very similar when it comes to information about time zones. Each time zone has a time zone ID identifier. In J2SE 1.3 and 1.4, this ID is a string, which is a list of these IDs located in the jre/lib subdirectory of the J2SE installer. J2SE 1.3 only contains tzmappings files, but J2SE 1.4 contains time zone data files in different regions of the world. jre/lib/zi stores these files. In J2SE 1.4, sun.util.calendar.ZoneInfo obtains DST rules from these files. In Solaris, these time zone data files are stored in binary form and are not text files, so you can't look at them. The time zone data file in J2SE 1.4 is different from that in Solaris.
The source code of the getDefault method in the java.util.TimeZone class shows that it will eventually call the getTimeZone method of the sun.util.calendar.ZoneInfo class. This method returns a String parameter as ID for the required time area. This default time zone ID is obtained from the user.timezone (system) property. If user.timezone is not defined, it will try to get the ID from the user.country and java.home (System) properties. If it does not successfully find a time zone ID, it uses a "fallback" GMT value. In other words, if it does not calculate your time zone ID, it will use GMT as your default time zone.
Note that the System property is initialized in the initProperties method of the java.lang.System class. This is a local method. Therefore the source code is not available--unless you dig into the local code base in the J2SE distribution package to study. However, in Windows systems, the System attribute is initialized from the Windows registry, while in Linux/Unix it is initialized by environment variables. The Javadoc declaration of the initProperties method, certain properties "must be guaranteed to be defined" and list them. Of the three System properties used by the getDefault method of the java.util.TimeZone class, only java.home is listed in Javadoc as a "guaranteed" property.
Recommended solutions:
So, how do you make sure that JAVA gives you the right time and date? The best way is to confirm that the default TimeZone class of JAVA virtual machine (JVM) is correct and is suitable for your geographical scope (Locale). How do you make sure that the default TimeZone is correct and suitable? This is another new problem. Like most problems dealt with, this has many solutions. According to the source code of the java.util.TimeZone.getDefault method, the best way is to correctly set the user.timezone property. When starting the JAVA virtual machine, you can easily override the value set in the java.lang.System.initProperties method by using the -D command-line parameter. For example:
java -Duser.timezone=Asia/Shanghai DateTest
This command starts the DateTest class and sets the user.timezone property to Asia/Shanghai. You can also set the user.timezone property by using the setProperty method of the java.lang.System class:
System.setProperty("user.timezone","Asia/Shanghai");If there is no available time zone ID for you, then you can create a custom TimeZone using the setDefault method of the java.util.TimeZone class to set it to the default time zone-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Remember that in J2SE, most date and time-related classes contain time zone information, including those format classes, such as java.text.DateFormat, so they are all affected by the default time zone of the JVM. However, when you create instances of these classes, you can ensure the correct time zone information for them, making it easier for you to set the default time zone of the entire JVM. And once set up, you can ensure that all these classes will use the same default time zone.