jtulach@1334: /* jtulach@1334: * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. jtulach@1334: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. jtulach@1334: * jtulach@1334: * This code is free software; you can redistribute it and/or modify it jtulach@1334: * under the terms of the GNU General Public License version 2 only, as jtulach@1334: * published by the Free Software Foundation. Oracle designates this jtulach@1334: * particular file as subject to the "Classpath" exception as provided jtulach@1334: * by Oracle in the LICENSE file that accompanied this code. jtulach@1334: * jtulach@1334: * This code is distributed in the hope that it will be useful, but WITHOUT jtulach@1334: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or jtulach@1334: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License jtulach@1334: * version 2 for more details (a copy is included in the LICENSE file that jtulach@1334: * accompanied this code). jtulach@1334: * jtulach@1334: * You should have received a copy of the GNU General Public License version jtulach@1334: * 2 along with this work; if not, write to the Free Software Foundation, jtulach@1334: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. jtulach@1334: * jtulach@1334: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA jtulach@1334: * or visit www.oracle.com if you need additional information or have any jtulach@1334: * questions. jtulach@1334: */ jtulach@1334: jtulach@1334: /* jtulach@1334: * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved jtulach@1334: * (C) Copyright IBM Corp. 1996 - All Rights Reserved jtulach@1334: * jtulach@1334: * The original version of this source code and documentation is copyrighted jtulach@1334: * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These jtulach@1334: * materials are provided under terms of a License Agreement between Taligent jtulach@1334: * and Sun. This technology is protected by multiple US and International jtulach@1334: * patents. This notice and attribution to Taligent may not be removed. jtulach@1334: * Taligent is a registered trademark of Taligent, Inc. jtulach@1334: * jtulach@1334: */ jtulach@1334: jtulach@1334: package java.util; jtulach@1334: jtulach@1334: import java.io.Serializable; jtulach@1334: import java.lang.ref.SoftReference; jtulach@1334: import java.security.AccessController; jtulach@1334: import java.security.PrivilegedAction; jtulach@1334: import java.util.concurrent.ConcurrentHashMap; jtulach@1334: jtulach@1334: /** jtulach@1334: * TimeZone represents a time zone offset, and also figures out daylight jtulach@1334: * savings. jtulach@1334: * jtulach@1334: *

jtulach@1334: * Typically, you get a TimeZone using getDefault jtulach@1334: * which creates a TimeZone based on the time zone where the program jtulach@1334: * is running. For example, for a program running in Japan, getDefault jtulach@1334: * creates a TimeZone object based on Japanese Standard Time. jtulach@1334: * jtulach@1334: *

jtulach@1334: * You can also get a TimeZone using getTimeZone jtulach@1334: * along with a time zone ID. For instance, the time zone ID for the jtulach@1334: * U.S. Pacific Time zone is "America/Los_Angeles". So, you can get a jtulach@1334: * U.S. Pacific Time TimeZone object with: jtulach@1334: *

jtulach@1334:  * TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
jtulach@1334:  * 
jtulach@1334: * You can use the getAvailableIDs method to iterate through jtulach@1334: * all the supported time zone IDs. You can then choose a jtulach@1334: * supported ID to get a TimeZone. jtulach@1334: * If the time zone you want is not represented by one of the jtulach@1334: * supported IDs, then a custom time zone ID can be specified to jtulach@1334: * produce a TimeZone. The syntax of a custom time zone ID is: jtulach@1334: * jtulach@1334: *
jtulach@1334:  * CustomID:
jtulach@1334:  *         GMT Sign Hours : Minutes
jtulach@1334:  *         GMT Sign Hours Minutes
jtulach@1334:  *         GMT Sign Hours
jtulach@1334:  * Sign: one of
jtulach@1334:  *         + -
jtulach@1334:  * Hours:
jtulach@1334:  *         Digit
jtulach@1334:  *         Digit Digit
jtulach@1334:  * Minutes:
jtulach@1334:  *         Digit Digit
jtulach@1334:  * Digit: one of
jtulach@1334:  *         0 1 2 3 4 5 6 7 8 9
jtulach@1334:  * 
jtulach@1334: * jtulach@1334: * Hours must be between 0 to 23 and Minutes must be jtulach@1334: * between 00 to 59. For example, "GMT+10" and "GMT+0010" mean ten jtulach@1334: * hours and ten minutes ahead of GMT, respectively. jtulach@1334: *

jtulach@1334: * The format is locale independent and digits must be taken from the jtulach@1334: * Basic Latin block of the Unicode standard. No daylight saving time jtulach@1334: * transition schedule can be specified with a custom time zone ID. If jtulach@1334: * the specified string doesn't match the syntax, "GMT" jtulach@1334: * is used. jtulach@1334: *

jtulach@1334: * When creating a TimeZone, the specified custom time jtulach@1334: * zone ID is normalized in the following syntax: jtulach@1334: *

jtulach@1334:  * NormalizedCustomID:
jtulach@1334:  *         GMT Sign TwoDigitHours : Minutes
jtulach@1334:  * Sign: one of
jtulach@1334:  *         + -
jtulach@1334:  * TwoDigitHours:
jtulach@1334:  *         Digit Digit
jtulach@1334:  * Minutes:
jtulach@1334:  *         Digit Digit
jtulach@1334:  * Digit: one of
jtulach@1334:  *         0 1 2 3 4 5 6 7 8 9
jtulach@1334:  * 
jtulach@1334: * For example, TimeZone.getTimeZone("GMT-8").getID() returns "GMT-08:00". jtulach@1334: * jtulach@1334: *

Three-letter time zone IDs

jtulach@1334: * jtulach@1334: * For compatibility with JDK 1.1.x, some other three-letter time zone IDs jtulach@1334: * (such as "PST", "CTT", "AST") are also supported. However, their jtulach@1334: * use is deprecated because the same abbreviation is often used jtulach@1334: * for multiple time zones (for example, "CST" could be U.S. "Central Standard jtulach@1334: * Time" and "China Standard Time"), and the Java platform can then only jtulach@1334: * recognize one of them. jtulach@1334: * jtulach@1334: * jtulach@1334: * @see Calendar jtulach@1334: * @see GregorianCalendar jtulach@1334: * @see SimpleTimeZone jtulach@1334: * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu jtulach@1334: * @since JDK1.1 jtulach@1334: */ jtulach@1334: abstract public class TimeZone implements Serializable, Cloneable { jtulach@1334: /** jtulach@1334: * Sole constructor. (For invocation by subclass constructors, typically jtulach@1334: * implicit.) jtulach@1334: */ jtulach@1334: public TimeZone() { jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * A style specifier for getDisplayName() indicating jtulach@1334: * a short name, such as "PST." jtulach@1334: * @see #LONG jtulach@1334: * @since 1.2 jtulach@1334: */ jtulach@1334: public static final int SHORT = 0; jtulach@1334: jtulach@1334: /** jtulach@1334: * A style specifier for getDisplayName() indicating jtulach@1334: * a long name, such as "Pacific Standard Time." jtulach@1334: * @see #SHORT jtulach@1334: * @since 1.2 jtulach@1334: */ jtulach@1334: public static final int LONG = 1; jtulach@1334: jtulach@1334: // Constants used internally; unit is milliseconds jtulach@1334: private static final int ONE_MINUTE = 60*1000; jtulach@1334: private static final int ONE_HOUR = 60*ONE_MINUTE; jtulach@1334: private static final int ONE_DAY = 24*ONE_HOUR; jtulach@1334: jtulach@1334: // Proclaim serialization compatibility with JDK 1.1 jtulach@1334: static final long serialVersionUID = 3581463369166924961L; jtulach@1334: jtulach@1334: /** jtulach@1334: * Gets the time zone offset, for current date, modified in case of jtulach@1334: * daylight savings. This is the offset to add to UTC to get local time. jtulach@1334: *

jtulach@1334: * This method returns a historically correct offset if an jtulach@1334: * underlying TimeZone implementation subclass jtulach@1334: * supports historical Daylight Saving Time schedule and GMT jtulach@1334: * offset changes. jtulach@1334: * jtulach@1334: * @param era the era of the given date. jtulach@1334: * @param year the year in the given date. jtulach@1334: * @param month the month in the given date. jtulach@1334: * Month is 0-based. e.g., 0 for January. jtulach@1334: * @param day the day-in-month of the given date. jtulach@1334: * @param dayOfWeek the day-of-week of the given date. jtulach@1334: * @param milliseconds the milliseconds in day in standard jtulach@1334: * local time. jtulach@1334: * jtulach@1334: * @return the offset in milliseconds to add to GMT to get local time. jtulach@1334: * jtulach@1334: * @see Calendar#ZONE_OFFSET jtulach@1334: * @see Calendar#DST_OFFSET jtulach@1334: */ jtulach@1334: public abstract int getOffset(int era, int year, int month, int day, jtulach@1334: int dayOfWeek, int milliseconds); jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns the offset of this time zone from UTC at the specified jtulach@1334: * date. If Daylight Saving Time is in effect at the specified jtulach@1334: * date, the offset value is adjusted with the amount of daylight jtulach@1334: * saving. jtulach@1334: *

jtulach@1334: * This method returns a historically correct offset value if an jtulach@1334: * underlying TimeZone implementation subclass supports historical jtulach@1334: * Daylight Saving Time schedule and GMT offset changes. jtulach@1334: * jtulach@1334: * @param date the date represented in milliseconds since January 1, 1970 00:00:00 GMT jtulach@1334: * @return the amount of time in milliseconds to add to UTC to get local time. jtulach@1334: * jtulach@1334: * @see Calendar#ZONE_OFFSET jtulach@1334: * @see Calendar#DST_OFFSET jtulach@1334: * @since 1.4 jtulach@1334: */ jtulach@1334: public int getOffset(long date) { jtulach@1334: if (inDaylightTime(new Date(date))) { jtulach@1334: return getRawOffset() + getDSTSavings(); jtulach@1334: } jtulach@1334: return getRawOffset(); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Gets the raw GMT offset and the amount of daylight saving of this jtulach@1334: * time zone at the given time. jtulach@1334: * @param date the milliseconds (since January 1, 1970, jtulach@1334: * 00:00:00.000 GMT) at which the time zone offset and daylight jtulach@1334: * saving amount are found jtulach@1334: * @param offset an array of int where the raw GMT offset jtulach@1334: * (offset[0]) and daylight saving amount (offset[1]) are stored, jtulach@1334: * or null if those values are not needed. The method assumes that jtulach@1334: * the length of the given array is two or larger. jtulach@1334: * @return the total amount of the raw GMT offset and daylight jtulach@1334: * saving at the specified date. jtulach@1334: * jtulach@1334: * @see Calendar#ZONE_OFFSET jtulach@1334: * @see Calendar#DST_OFFSET jtulach@1334: */ jtulach@1334: int getOffsets(long date, int[] offsets) { jtulach@1334: int rawoffset = getRawOffset(); jtulach@1334: int dstoffset = 0; jtulach@1334: if (inDaylightTime(new Date(date))) { jtulach@1334: dstoffset = getDSTSavings(); jtulach@1334: } jtulach@1334: if (offsets != null) { jtulach@1334: offsets[0] = rawoffset; jtulach@1334: offsets[1] = dstoffset; jtulach@1334: } jtulach@1334: return rawoffset + dstoffset; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Sets the base time zone offset to GMT. jtulach@1334: * This is the offset to add to UTC to get local time. jtulach@1334: *

jtulach@1334: * If an underlying TimeZone implementation subclass jtulach@1334: * supports historical GMT offset changes, the specified GMT jtulach@1334: * offset is set as the latest GMT offset and the difference from jtulach@1334: * the known latest GMT offset value is used to adjust all jtulach@1334: * historical GMT offset values. jtulach@1334: * jtulach@1334: * @param offsetMillis the given base time zone offset to GMT. jtulach@1334: */ jtulach@1334: abstract public void setRawOffset(int offsetMillis); jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns the amount of time in milliseconds to add to UTC to get jtulach@1334: * standard time in this time zone. Because this value is not jtulach@1334: * affected by daylight saving time, it is called raw jtulach@1334: * offset. jtulach@1334: *

jtulach@1334: * If an underlying TimeZone implementation subclass jtulach@1334: * supports historical GMT offset changes, the method returns the jtulach@1334: * raw offset value of the current date. In Honolulu, for example, jtulach@1334: * its raw offset changed from GMT-10:30 to GMT-10:00 in 1947, and jtulach@1334: * this method always returns -36000000 milliseconds (i.e., -10 jtulach@1334: * hours). jtulach@1334: * jtulach@1334: * @return the amount of raw offset time in milliseconds to add to UTC. jtulach@1334: * @see Calendar#ZONE_OFFSET jtulach@1334: */ jtulach@1334: public abstract int getRawOffset(); jtulach@1334: jtulach@1334: /** jtulach@1334: * Gets the ID of this time zone. jtulach@1334: * @return the ID of this time zone. jtulach@1334: */ jtulach@1334: public String getID() jtulach@1334: { jtulach@1334: return ID; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Sets the time zone ID. This does not change any other data in jtulach@1334: * the time zone object. jtulach@1334: * @param ID the new time zone ID. jtulach@1334: */ jtulach@1334: public void setID(String ID) jtulach@1334: { jtulach@1334: if (ID == null) { jtulach@1334: throw new NullPointerException(); jtulach@1334: } jtulach@1334: this.ID = ID; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns a long standard time name of this {@code TimeZone} suitable for jtulach@1334: * presentation to the user in the default locale. jtulach@1334: * jtulach@1334: *

This method is equivalent to: jtulach@1334: *

jtulach@1334: * getDisplayName(false, {@link #LONG}, jtulach@1334: * Locale.getDefault({@link Locale.Category#DISPLAY})) jtulach@1334: *
jtulach@1334: * jtulach@1334: * @return the human-readable name of this time zone in the default locale. jtulach@1334: * @since 1.2 jtulach@1334: * @see #getDisplayName(boolean, int, Locale) jtulach@1334: * @see Locale#getDefault(Locale.Category) jtulach@1334: * @see Locale.Category jtulach@1334: */ jtulach@1334: public final String getDisplayName() { jtulach@1334: return getDisplayName(false, LONG, jtulach@1334: Locale.getDefault(Locale.Category.DISPLAY)); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns a long standard time name of this {@code TimeZone} suitable for jtulach@1334: * presentation to the user in the specified {@code locale}. jtulach@1334: * jtulach@1334: *

This method is equivalent to: jtulach@1334: *

jtulach@1334: * getDisplayName(false, {@link #LONG}, locale) jtulach@1334: *
jtulach@1334: * jtulach@1334: * @param locale the locale in which to supply the display name. jtulach@1334: * @return the human-readable name of this time zone in the given locale. jtulach@1334: * @exception NullPointerException if {@code locale} is {@code null}. jtulach@1334: * @since 1.2 jtulach@1334: * @see #getDisplayName(boolean, int, Locale) jtulach@1334: */ jtulach@1334: public final String getDisplayName(Locale locale) { jtulach@1334: return getDisplayName(false, LONG, locale); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns a name in the specified {@code style} of this {@code TimeZone} jtulach@1334: * suitable for presentation to the user in the default locale. If the jtulach@1334: * specified {@code daylight} is {@code true}, a Daylight Saving Time name jtulach@1334: * is returned (even if this {@code TimeZone} doesn't observe Daylight Saving jtulach@1334: * Time). Otherwise, a Standard Time name is returned. jtulach@1334: * jtulach@1334: *

This method is equivalent to: jtulach@1334: *

jtulach@1334: * getDisplayName(daylight, style, jtulach@1334: * Locale.getDefault({@link Locale.Category#DISPLAY})) jtulach@1334: *
jtulach@1334: * jtulach@1334: * @param daylight {@code true} specifying a Daylight Saving Time name, or jtulach@1334: * {@code false} specifying a Standard Time name jtulach@1334: * @param style either {@link #LONG} or {@link #SHORT} jtulach@1334: * @return the human-readable name of this time zone in the default locale. jtulach@1334: * @exception IllegalArgumentException if {@code style} is invalid. jtulach@1334: * @since 1.2 jtulach@1334: * @see #getDisplayName(boolean, int, Locale) jtulach@1334: * @see Locale#getDefault(Locale.Category) jtulach@1334: * @see Locale.Category jtulach@1334: * @see java.text.DateFormatSymbols#getZoneStrings() jtulach@1334: */ jtulach@1334: public final String getDisplayName(boolean daylight, int style) { jtulach@1334: return getDisplayName(daylight, style, jtulach@1334: Locale.getDefault(Locale.Category.DISPLAY)); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns a name in the specified {@code style} of this {@code TimeZone} jtulach@1334: * suitable for presentation to the user in the specified {@code jtulach@1334: * locale}. If the specified {@code daylight} is {@code true}, a Daylight jtulach@1334: * Saving Time name is returned (even if this {@code TimeZone} doesn't jtulach@1334: * observe Daylight Saving Time). Otherwise, a Standard Time name is jtulach@1334: * returned. jtulach@1334: * jtulach@1334: *

When looking up a time zone name, the {@linkplain jtulach@1334: * ResourceBundle.Control#getCandidateLocales(String,Locale) default jtulach@1334: * Locale search path of ResourceBundle} derived jtulach@1334: * from the specified {@code locale} is used. (No {@linkplain jtulach@1334: * ResourceBundle.Control#getFallbackLocale(String,Locale) fallback jtulach@1334: * Locale} search is performed.) If a time zone name in any jtulach@1334: * {@code Locale} of the search path, including {@link Locale#ROOT}, is jtulach@1334: * found, the name is returned. Otherwise, a string in the jtulach@1334: * normalized custom ID format is returned. jtulach@1334: * jtulach@1334: * @param daylight {@code true} specifying a Daylight Saving Time name, or jtulach@1334: * {@code false} specifying a Standard Time name jtulach@1334: * @param style either {@link #LONG} or {@link #SHORT} jtulach@1334: * @param locale the locale in which to supply the display name. jtulach@1334: * @return the human-readable name of this time zone in the given locale. jtulach@1334: * @exception IllegalArgumentException if {@code style} is invalid. jtulach@1334: * @exception NullPointerException if {@code locale} is {@code null}. jtulach@1334: * @since 1.2 jtulach@1334: * @see java.text.DateFormatSymbols#getZoneStrings() jtulach@1334: */ jtulach@1334: public String getDisplayName(boolean daylight, int style, Locale locale) { jtulach@1334: if (style != SHORT && style != LONG) { jtulach@1334: throw new IllegalArgumentException("Illegal style: " + style); jtulach@1334: } jtulach@1334: jtulach@1334: String id = getID(); jtulach@1334: String[] names = getDisplayNames(id, locale); jtulach@1334: if (names == null) { jtulach@1334: if (id.startsWith("GMT")) { jtulach@1334: char sign = id.charAt(3); jtulach@1334: if (sign == '+' || sign == '-') { jtulach@1334: return id; jtulach@1334: } jtulach@1334: } jtulach@1334: int offset = getRawOffset(); jtulach@1334: if (daylight) { jtulach@1334: offset += getDSTSavings(); jtulach@1334: } jaroslav@1340: // return ZoneInfoFile.toCustomID(offset); jtulach@1334: } jtulach@1334: jtulach@1334: int index = daylight ? 3 : 1; jtulach@1334: if (style == SHORT) { jtulach@1334: index++; jtulach@1334: } jtulach@1334: return names[index]; jtulach@1334: } jtulach@1334: jtulach@1334: private static class DisplayNames { jtulach@1334: // Cache for managing display names per timezone per locale jtulach@1334: // The structure is: jtulach@1334: // Map(key=id, value=SoftReference(Map(key=locale, value=displaynames))) jtulach@1334: private static final Map>> CACHE = jtulach@1334: new ConcurrentHashMap>>(); jtulach@1334: } jtulach@1334: jtulach@1334: private static final String[] getDisplayNames(String id, Locale locale) { jtulach@1334: Map>> displayNames = DisplayNames.CACHE; jtulach@1334: jtulach@1334: SoftReference> ref = displayNames.get(id); jtulach@1334: if (ref != null) { jtulach@1334: Map perLocale = ref.get(); jtulach@1334: if (perLocale != null) { jtulach@1334: String[] names = perLocale.get(locale); jtulach@1334: if (names != null) { jtulach@1334: return names; jtulach@1334: } jaroslav@1340: names = null; // TimeZoneNameUtility.retrieveDisplayNames(id, locale); jtulach@1334: if (names != null) { jtulach@1334: perLocale.put(locale, names); jtulach@1334: } jtulach@1334: return names; jtulach@1334: } jtulach@1334: } jtulach@1334: jaroslav@1340: String[] names = null; // TimeZoneNameUtility.retrieveDisplayNames(id, locale); jtulach@1334: if (names != null) { jtulach@1334: Map perLocale = new ConcurrentHashMap(); jtulach@1334: perLocale.put(locale, names); jtulach@1334: ref = new SoftReference>(perLocale); jtulach@1334: displayNames.put(id, ref); jtulach@1334: } jtulach@1334: return names; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns the amount of time to be added to local standard time jtulach@1334: * to get local wall clock time. jtulach@1334: * jtulach@1334: *

The default implementation returns 3600000 milliseconds jtulach@1334: * (i.e., one hour) if a call to {@link #useDaylightTime()} jtulach@1334: * returns {@code true}. Otherwise, 0 (zero) is returned. jtulach@1334: * jtulach@1334: *

If an underlying {@code TimeZone} implementation subclass jtulach@1334: * supports historical and future Daylight Saving Time schedule jtulach@1334: * changes, this method returns the amount of saving time of the jtulach@1334: * last known Daylight Saving Time rule that can be a future jtulach@1334: * prediction. jtulach@1334: * jtulach@1334: *

If the amount of saving time at any given time stamp is jtulach@1334: * required, construct a {@link Calendar} with this {@code jtulach@1334: * TimeZone} and the time stamp, and call {@link Calendar#get(int) jtulach@1334: * Calendar.get}{@code (}{@link Calendar#DST_OFFSET}{@code )}. jtulach@1334: * jtulach@1334: * @return the amount of saving time in milliseconds jtulach@1334: * @since 1.4 jtulach@1334: * @see #inDaylightTime(Date) jtulach@1334: * @see #getOffset(long) jtulach@1334: * @see #getOffset(int,int,int,int,int,int) jtulach@1334: * @see Calendar#ZONE_OFFSET jtulach@1334: */ jtulach@1334: public int getDSTSavings() { jtulach@1334: if (useDaylightTime()) { jtulach@1334: return 3600000; jtulach@1334: } jtulach@1334: return 0; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Queries if this {@code TimeZone} uses Daylight Saving Time. jtulach@1334: * jtulach@1334: *

If an underlying {@code TimeZone} implementation subclass jtulach@1334: * supports historical and future Daylight Saving Time schedule jtulach@1334: * changes, this method refers to the last known Daylight Saving Time jtulach@1334: * rule that can be a future prediction and may not be the same as jtulach@1334: * the current rule. Consider calling {@link #observesDaylightTime()} jtulach@1334: * if the current rule should also be taken into account. jtulach@1334: * jtulach@1334: * @return {@code true} if this {@code TimeZone} uses Daylight Saving Time, jtulach@1334: * {@code false}, otherwise. jtulach@1334: * @see #inDaylightTime(Date) jtulach@1334: * @see Calendar#DST_OFFSET jtulach@1334: */ jtulach@1334: public abstract boolean useDaylightTime(); jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns {@code true} if this {@code TimeZone} is currently in jtulach@1334: * Daylight Saving Time, or if a transition from Standard Time to jtulach@1334: * Daylight Saving Time occurs at any future time. jtulach@1334: * jtulach@1334: *

The default implementation returns {@code true} if jtulach@1334: * {@code useDaylightTime()} or {@code inDaylightTime(new Date())} jtulach@1334: * returns {@code true}. jtulach@1334: * jtulach@1334: * @return {@code true} if this {@code TimeZone} is currently in jtulach@1334: * Daylight Saving Time, or if a transition from Standard Time to jtulach@1334: * Daylight Saving Time occurs at any future time; {@code false} jtulach@1334: * otherwise. jtulach@1334: * @since 1.7 jtulach@1334: * @see #useDaylightTime() jtulach@1334: * @see #inDaylightTime(Date) jtulach@1334: * @see Calendar#DST_OFFSET jtulach@1334: */ jtulach@1334: public boolean observesDaylightTime() { jtulach@1334: return useDaylightTime() || inDaylightTime(new Date()); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Queries if the given {@code date} is in Daylight Saving Time in jtulach@1334: * this time zone. jtulach@1334: * jtulach@1334: * @param date the given Date. jtulach@1334: * @return {@code true} if the given date is in Daylight Saving Time, jtulach@1334: * {@code false}, otherwise. jtulach@1334: */ jtulach@1334: abstract public boolean inDaylightTime(Date date); jtulach@1334: jtulach@1334: /** jtulach@1334: * Gets the TimeZone for the given ID. jtulach@1334: * jtulach@1334: * @param ID the ID for a TimeZone, either an abbreviation jtulach@1334: * such as "PST", a full name such as "America/Los_Angeles", or a custom jtulach@1334: * ID such as "GMT-8:00". Note that the support of abbreviations is jtulach@1334: * for JDK 1.1.x compatibility only and full names should be used. jtulach@1334: * jtulach@1334: * @return the specified TimeZone, or the GMT zone if the given ID jtulach@1334: * cannot be understood. jtulach@1334: */ jtulach@1334: public static synchronized TimeZone getTimeZone(String ID) { jtulach@1334: return getTimeZone(ID, true); jtulach@1334: } jtulach@1334: jtulach@1334: private static TimeZone getTimeZone(String ID, boolean fallback) { jaroslav@1340: // TimeZone tz = ZoneInfo.getTimeZone(ID); jaroslav@1340: // if (tz == null) { jaroslav@1340: // tz = parseCustomTimeZone(ID); jaroslav@1340: // if (tz == null && fallback) { jaroslav@1340: // tz = new ZoneInfo(GMT_ID, 0); jaroslav@1340: // } jaroslav@1340: // } jaroslav@1340: // return tz; jaroslav@1340: return TimeZone.NO_TIMEZONE; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Gets the available IDs according to the given time zone offset in milliseconds. jtulach@1334: * jtulach@1334: * @param rawOffset the given time zone GMT offset in milliseconds. jtulach@1334: * @return an array of IDs, where the time zone for that ID has jtulach@1334: * the specified GMT offset. For example, "America/Phoenix" and "America/Denver" jtulach@1334: * both have GMT-07:00, but differ in daylight saving behavior. jtulach@1334: * @see #getRawOffset() jtulach@1334: */ jtulach@1334: public static synchronized String[] getAvailableIDs(int rawOffset) { jaroslav@1340: return new String[0];//ZoneInfo.getAvailableIDs(rawOffset); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Gets all the available IDs supported. jtulach@1334: * @return an array of IDs. jtulach@1334: */ jtulach@1334: public static synchronized String[] getAvailableIDs() { jaroslav@1340: return new String[0];//return ZoneInfo.getAvailableIDs(); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Gets the platform defined TimeZone ID. jtulach@1334: **/ jtulach@1334: private static native String getSystemTimeZoneID(String javaHome, jtulach@1334: String country); jtulach@1334: jtulach@1334: /** jtulach@1334: * Gets the custom time zone ID based on the GMT offset of the jtulach@1334: * platform. (e.g., "GMT+08:00") jtulach@1334: */ jtulach@1334: private static native String getSystemGMTOffsetID(); jtulach@1334: jtulach@1334: /** jtulach@1334: * Gets the default TimeZone for this host. jtulach@1334: * The source of the default TimeZone jtulach@1334: * may vary with implementation. jtulach@1334: * @return a default TimeZone. jtulach@1334: * @see #setDefault jtulach@1334: */ jtulach@1334: public static TimeZone getDefault() { jtulach@1334: return (TimeZone) getDefaultRef().clone(); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns the reference to the default TimeZone object. This jtulach@1334: * method doesn't create a clone. jtulach@1334: */ jtulach@1334: static TimeZone getDefaultRef() { jaroslav@1340: TimeZone defaultZone = null;//defaultZoneTL.get(); jtulach@1334: if (defaultZone == null) { jtulach@1334: defaultZone = defaultTimeZone; jtulach@1334: if (defaultZone == null) { jtulach@1334: // Need to initialize the default time zone. jaroslav@1340: defaultZone = TimeZone.NO_TIMEZONE; jtulach@1334: assert defaultZone != null; jtulach@1334: } jtulach@1334: } jtulach@1334: // Don't clone here. jtulach@1334: return defaultZone; jtulach@1334: } jtulach@1334: jtulach@1334: private static boolean hasPermission() { jaroslav@1340: boolean hasPermission = false; jtulach@1334: return hasPermission; jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Sets the TimeZone that is jtulach@1334: * returned by the getDefault method. If zone jtulach@1334: * is null, reset the default to the value it had originally when the jtulach@1334: * VM first started. jtulach@1334: * @param zone the new default time zone jtulach@1334: * @see #getDefault jtulach@1334: */ jtulach@1334: public static void setDefault(TimeZone zone) jtulach@1334: { jtulach@1334: if (hasPermission()) { jtulach@1334: synchronized (TimeZone.class) { jtulach@1334: defaultTimeZone = zone; jaroslav@1340: // defaultZoneTL.set(null); jtulach@1334: } jtulach@1334: } else { jaroslav@1340: //defaultZoneTL.set(zone); jtulach@1334: } jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Returns true if this zone has the same rule and offset as another zone. jtulach@1334: * That is, if this zone differs only in ID, if at all. Returns false jtulach@1334: * if the other zone is null. jtulach@1334: * @param other the TimeZone object to be compared with jtulach@1334: * @return true if the other zone is not null and is the same as this one, jtulach@1334: * with the possible exception of the ID jtulach@1334: * @since 1.2 jtulach@1334: */ jtulach@1334: public boolean hasSameRules(TimeZone other) { jtulach@1334: return other != null && getRawOffset() == other.getRawOffset() && jtulach@1334: useDaylightTime() == other.useDaylightTime(); jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * Creates a copy of this TimeZone. jtulach@1334: * jtulach@1334: * @return a clone of this TimeZone jtulach@1334: */ jtulach@1334: public Object clone() jtulach@1334: { jtulach@1334: try { jtulach@1334: TimeZone other = (TimeZone) super.clone(); jtulach@1334: other.ID = ID; jtulach@1334: return other; jtulach@1334: } catch (CloneNotSupportedException e) { jtulach@1334: throw new InternalError(); jtulach@1334: } jtulach@1334: } jtulach@1334: jtulach@1334: /** jtulach@1334: * The null constant as a TimeZone. jtulach@1334: */ jtulach@1334: static final TimeZone NO_TIMEZONE = null; jtulach@1334: jtulach@1334: // =======================privates=============================== jtulach@1334: jtulach@1334: /** jtulach@1334: * The string identifier of this TimeZone. This is a jtulach@1334: * programmatic identifier used internally to look up TimeZone jtulach@1334: * objects from the system table and also to map them to their localized jtulach@1334: * display names. ID values are unique in the system jtulach@1334: * table but may not be for dynamically created zones. jtulach@1334: * @serial jtulach@1334: */ jtulach@1334: private String ID; jtulach@1334: private static volatile TimeZone defaultTimeZone; jtulach@1334: jtulach@1334: static final String GMT_ID = "GMT"; jtulach@1334: private static final int GMT_ID_LENGTH = 3; jtulach@1334: jtulach@1334: /** jtulach@1334: * Parses a custom time zone identifier and returns a corresponding zone. jtulach@1334: * This method doesn't support the RFC 822 time zone format. (e.g., +hhmm) jtulach@1334: * jtulach@1334: * @param id a string of the custom ID form. jtulach@1334: * @return a newly created TimeZone with the given offset and jtulach@1334: * no daylight saving time, or null if the id cannot be parsed. jtulach@1334: */ jtulach@1334: private static final TimeZone parseCustomTimeZone(String id) { jaroslav@1340: return null; jtulach@1334: } jtulach@1334: }