/*
 * @(#)TimeZone.java    1.51 00/01/19
 *
 * Copyright (C) 1996-2012, International Business Machines
 * Corporation and others.  All Rights Reserved.
 */

package com.ibm.icu.util;

import java.io.Serializable;
import java.util.Date;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.Set;
import java.util.logging.Logger;

import com.ibm.icu.impl.Grego;
import com.ibm.icu.impl.ICUConfig;
import com.ibm.icu.impl.JavaTimeZone;
import com.ibm.icu.impl.TimeZoneAdapter;
import com.ibm.icu.impl.ZoneMeta;
import com.ibm.icu.text.TimeZoneFormat;
import com.ibm.icu.text.TimeZoneFormat.Style;
import com.ibm.icu.text.TimeZoneFormat.TimeType;
import com.ibm.icu.text.TimeZoneNames;
import com.ibm.icu.text.TimeZoneNames.NameType;
import com.ibm.icu.util.ULocale.Category;

/**
 * {@icuenhanced java.util.TimeZone}.{@icu _usage_}
 *
 * <p><code>TimeZone</code> represents a time zone offset, and also computes daylight
 * savings.
 *
 * <p>Typically, you get a <code>TimeZone</code> using {@link #getDefault()}
 * which creates a <code>TimeZone</code> based on the time zone where the program
 * is running. For example, for a program running in Japan, <code>getDefault</code>
 * creates a <code>TimeZone</code> object based on Japanese Standard Time.
 *
 * <p>You can also get a <code>TimeZone</code> using {@link #getTimeZone(String)}
 * along with a time zone ID. For instance, the time zone ID for the
 * U.S. Pacific Time zone is "America/Los_Angeles". So, you can get a
 * U.S. Pacific Time <code>TimeZone</code> object with:
 *
 * <blockquote>
 * <pre>
 * TimeZone tz = TimeZone.getTimeZone("America/Los_Angeles");
 * </pre>
 * </blockquote>
 * You can use the {@link #getAvailableIDs()} method to iterate through
 * all the supported time zone IDs, or getCanonicalID method to check
 * if a time zone ID is supported or not. You can then choose a
 * supported ID to get a <code>TimeZone</code>.
 * If the time zone you want is not represented by one of the
 * supported IDs, then you can create a custom time zone ID with
 * the following syntax:
 *
 * <blockquote>
 * <pre>
 * GMT[+|-]hh[[:]mm]
 * </pre>
 * </blockquote>
 *
 * For example, you might specify GMT+14:00 as a custom
 * time zone ID.  The <code>TimeZone</code> that is returned
 * when you specify a custom time zone ID uses the specified
 * offset from GMT(=UTC) and does not observe daylight saving
 * time. For example, you might specify GMT+14:00 as a custom
 * time zone ID to create a TimeZone representing 14 hours ahead
 * of GMT (with no daylight saving time). In addition, 
 * <code>getCanonicalID</code> can also be used to
 * normalize a custom time zone ID.
 *
 * <p>For compatibility with JDK 1.1.x, some other three-letter time zone IDs
 * (such as "PST", "CTT", "AST") are also supported. However, <strong>their
 * use is deprecated</strong> because the same abbreviation is often used
 * for multiple time zones (for example, "CST" could be U.S. "Central Standard
 * Time" and "China Standard Time"), and the Java platform can then only
 * recognize one of them.
 *
 * <p><strong>Note:</strong> Starting from ICU4J 4.0, you can optionally choose
 * JDK <code>TimeZone</code> as the time zone implementation.  The TimeZone factory
 * method <code>getTimeZone</code> creates an instance of ICU's own <code>TimeZone</code>
 * subclass by default.  If you want to use the JDK implementation always, you can
 * set the default time zone implementation type by the new method
 * <code>setDefaultTimeZoneType</code>.  Alternatively, you can change the initial
 * default implementation type by setting a property below.
 *
 * <blockquote>
 * <pre>
 * #
 * # The default TimeZone implementation type used by the ICU TimeZone
 * # factory method. [ ICU | JDK ]
 * #
 * com.ibm.icu.util.TimeZone.DefaultTimeZoneType = ICU
 * </pre>
 * </blockquote>
 *
 * <p>This property is included in ICUConfig.properties in com.ibm.icu package.  When the
 * <code>TimeZone</code> class is loaded, the initialization code checks if the property
 * <code>com.ibm.icu.util.TimeZone.DefaultTimeZoneType=xxx</code> is defined by the system
 * properties.  If not available, then it loads ICUConfig.properties to get the default
 * time zone implementation type.  The property setting is only used for the initial
 * default value and you can change the default type by calling
 * <code>setDefaultTimeZoneType</code> at runtime.
 *
 * @see          Calendar
 * @see          GregorianCalendar
 * @see          SimpleTimeZone
 * @author       Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu
 * @stable ICU 2.0
 */
abstract public class TimeZone implements Serializable, Cloneable, Freezable<TimeZone> {
    /**
     * Logger instance for this class
     */
    private static final Logger LOGGER = Logger.getLogger("com.ibm.icu.util.TimeZone");

    // using serialver from jdk1.4.2_05
    private static final long serialVersionUID = -744942128318337471L;

    /**
     * Default constructor.  (For invocation by subclass constructors,
     * typically implicit.)
     * @stable ICU 2.8
     */
    public TimeZone() {
    }

    /**
     * Constructing a TimeZone with the given time zone ID.
     * @param ID the time zone ID.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    protected TimeZone(String ID) {
        if (ID == null) {
            throw new NullPointerException();
        }
        this.ID = ID;
    }

    /**
     * {@icu} A time zone implementation type indicating ICU's own TimeZone used by
     * <code>getTimeZone</code>, <code>setDefaultTimeZoneType</code>
     * and <code>getDefaultTimeZoneType</code>.
     * @stable ICU 4.0
     */
    public static final int TIMEZONE_ICU = 0;
    /**
     * {@icu} A time zone implementation type indicating JDK TimeZone used by
     * <code>getTimeZone</code>, <code>setDefaultTimeZoneType</code>
     * and <code>getDefaultTimeZoneType</code>.
     * @stable ICU 4.0
     */
    public static final int TIMEZONE_JDK = 1;

    /**
     * A style specifier for <code>getDisplayName()</code> indicating
     * a short name, such as "PST."
     * @see #LONG
     * @stable ICU 2.0
     */
    public static final int SHORT = 0;

    /**
     * A style specifier for <code>getDisplayName()</code> indicating
     * a long name, such as "Pacific Standard Time."
     * @see #SHORT
     * @stable ICU 2.0
     */
    public static final int LONG  = 1;

    /**
     * {@icu} A style specifier for <code>getDisplayName()</code> indicating
     * a short generic name, such as "PT."
     * @see #LONG_GENERIC
     * @stable ICU 4.4
     */
    public static final int SHORT_GENERIC = 2;

    /**
     * {@icu} A style specifier for <code>getDisplayName()</code> indicating
     * a long generic name, such as "Pacific Time."
     * @see #SHORT_GENERIC
     * @stable ICU 4.4
     */
    public static final int LONG_GENERIC = 3;

    /**
     * {@icu} A style specifier for <code>getDisplayName()</code> indicating
     * a short name derived from the timezone's offset, such as "-0800."
     * @see #LONG_GMT
     * @stable ICU 4.4
     */
    public static final int SHORT_GMT = 4;

    /**
     * {@icu} A style specifier for <code>getDisplayName()</code> indicating
     * a long name derived from the timezone's offset, such as "GMT-08:00."
     * @see #SHORT_GMT
     * @stable ICU 4.4
     */
    public static final int LONG_GMT = 5;

    /**
     * {@icu} A style specifier for <code>getDisplayName()</code> indicating
     * a short name derived from the timezone's short standard or daylight
     * timezone name ignoring commonlyUsed, such as "PDT."
     * @stable ICU 4.4
     */

    public static final int SHORT_COMMONLY_USED = 6;

    /**
     * {@icu} A style specifier for <code>getDisplayName()</code> indicating
     * a long name derived from the timezone's fallback name, such as
     * "United States (Los Angeles)."
     * @stable ICU 4.4
     */
    public static final int GENERIC_LOCATION = 7;

    /**
     * {@icu} The time zone ID reserved for unknown time zone.
     * @see #getTimeZone(String)
     * 
     * @stable ICU 4.8
     */
    public static final String UNKNOWN_ZONE_ID = "Etc/Unknown";

    /**
     * The canonical ID for GMT(UTC) time zone.
     */
    static final String GMT_ZONE_ID = "Etc/GMT";

    /**
     * {@icu} The immutable (frozen) "unknown" time zone.
     * It behaves like the GMT/UTC time zone but has the UNKNOWN_ZONE_ID = "Etc/Unknown".
     * {@link TimeZone#getTimeZone(String)} returns a mutable clone of this
     * time zone if the input ID is not recognized.
     *
     * @see #UNKNOWN_ZONE_ID
     * @see #getTimeZone(String)
     * 
     * @draft ICU 49
     * @provisional This API might change or be removed in a future release.
     */
    public static final TimeZone UNKNOWN_ZONE = new SimpleTimeZone(0, UNKNOWN_ZONE_ID).freeze();

    /**
     * {@icu} The immutable GMT (=UTC) time zone. Its ID is "Etc/GMT".
     *
     * @draft ICU 49
     * @provisional This API might change or be removed in a future release.
     */
    public static final TimeZone GMT_ZONE = new SimpleTimeZone(0, GMT_ZONE_ID).freeze();

    /**
     * {@icu} System time zone type constants used by filtering zones in
     * {@link TimeZone#getAvailableIDs(SystemTimeZoneType, String, Integer)}
     *
     * @stable ICU 4.8
     */
    public enum SystemTimeZoneType {
        /**
         * Any system zones.
         * @stable ICU 4.8
         * @provisional This API might change or be removed in a future release.
         */
        ANY,

        /**
         * Canonical system zones.
         * @stable ICU 4.8
         * @provisional This API might change or be removed in a future release.
         */
        CANONICAL,

        /**
         * Canonical system zones associated with actual locations.
         * @stable ICU 4.8
         * @provisional This API might change or be removed in a future release.
         */
        CANONICAL_LOCATION,
    }

    /**
     * Gets the time zone offset, for current date, modified in case of
     * daylight savings. This is the offset to add *to* UTC to get local time.
     * @param era the era of the given date.
     * @param year the year in the given date.
     * @param month the month in the given date.
     * Month is 0-based. e.g., 0 for January.
     * @param day the day-in-month of the given date.
     * @param dayOfWeek the day-of-week of the given date.
     * @param milliseconds the millis in day in <em>standard</em> local time.
     * @return the offset to add *to* GMT to get local time.
     * @stable ICU 2.0
     */
    abstract public int getOffset(int era, int year, int month, int day,
                                  int dayOfWeek, int milliseconds);


    /**
     * Returns the offset of this time zone from UTC at the specified
     * date. If Daylight Saving Time is in effect at the specified
     * date, the offset value is adjusted with the amount of daylight
     * saving.
     *
     * @param date the date represented in milliseconds since January 1, 1970 00:00:00 GMT
     * @return the amount of time in milliseconds to add to UTC to get local time.
     *
     * @see Calendar#ZONE_OFFSET
     * @see Calendar#DST_OFFSET
     * @see #getOffset(long, boolean, int[])
     * @stable ICU 2.8
     */
    public int getOffset(long date) {
        int[] result = new int[2];
        getOffset(date, false, result);
        return result[0]+result[1];
    }

    /**
     * Returns the time zone raw and GMT offset for the given moment
     * in time.  Upon return, local-millis = GMT-millis + rawOffset +
     * dstOffset.  All computations are performed in the proleptic
     * Gregorian calendar.  The default implementation in the TimeZone
     * class delegates to the 8-argument getOffset().
     *
     * @param date moment in time for which to return offsets, in
     * units of milliseconds from January 1, 1970 0:00 GMT, either GMT
     * time or local wall time, depending on `local'.
     * @param local if true, `date' is local wall time; otherwise it
     * is in GMT time.
     * @param offsets output parameter to receive the raw offset, that
     * is, the offset not including DST adjustments, in offsets[0],
     * and the DST offset, that is, the offset to be added to
     * `rawOffset' to obtain the total offset between local and GMT
     * time, in offsets[1]. If DST is not in effect, the DST offset is
     * zero; otherwise it is a positive value, typically one hour.
     *
     * @stable ICU 2.8
     */
    public void getOffset(long date, boolean local, int[] offsets) {
        offsets[0] = getRawOffset();
        if (!local) {
            date += offsets[0]; // now in local standard millis
        }

        // When local == true, date might not be in local standard
        // millis.  getOffset taking 6 parameters used here assume
        // the given time in day is local standard time.
        // At STD->DST transition, there is a range of time which
        // does not exist.  When 'date' is in this time range
        // (and local == true), this method interprets the specified
        // local time as DST.  At DST->STD transition, there is a
        // range of time which occurs twice.  In this case, this
        // method interprets the specified local time as STD.
        // To support the behavior above, we need to call getOffset
        // (with 6 args) twice when local == true and DST is
        // detected in the initial call.
        int fields[] = new int[6];
        for (int pass = 0; ; pass++) {
            Grego.timeToFields(date, fields);
            offsets[1] = getOffset(GregorianCalendar.AD,
                                    fields[0], fields[1], fields[2],
                                    fields[3], fields[5]) - offsets[0];

            if (pass != 0 || !local || offsets[1] == 0) {
                break;
            }
            // adjust to local standard millis
            date -= offsets[1];
        }
    }

    /**
     * Sets the base time zone offset to GMT.
     * This is the offset to add *to* UTC to get local time.
     * @param offsetMillis the given base time zone offset to GMT.
     * @stable ICU 2.0
     */
    abstract public void setRawOffset(int offsetMillis);

    /**
     * Gets unmodified offset, NOT modified in case of daylight savings.
     * This is the offset to add *to* UTC to get local time.
     * @return the unmodified offset to add *to* UTC to get local time.
     * @stable ICU 2.0
     */
    abstract public int getRawOffset();

    /**
     * Gets the ID of this time zone.
     * @return the ID of this time zone.
     * @stable ICU 2.0
     */
    public String getID() {
        return ID;
    }

    /**
     * Sets the time zone ID. This does not change any other data in
     * the time zone object.
     * @param ID the new time zone ID.
     * @stable ICU 2.0
     */
    public void setID(String ID) {
        if (ID == null) {
            throw new NullPointerException();
        }
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify a frozen TimeZone instance.");
        }
        this.ID = ID;
    }

    /**
     * Returns a name of this time zone suitable for presentation to the user
     * in the default <code>DISPLAY</code> locale.
     * This method returns the long generic name.
     * If the display name is not available for the locale,
     * a fallback based on the country, city, or time zone id will be used.
     * @return the human-readable name of this time zone in the default locale.
     * @see Category#DISPLAY
     * @stable ICU 2.0
     */
    public final String getDisplayName() {
        return _getDisplayName(LONG_GENERIC, false, ULocale.getDefault(Category.DISPLAY));
    }

    /**
     * Returns a name of this time zone suitable for presentation to the user
     * in the specified locale.
     * This method returns the long generic name.
     * If the display name is not available for the locale,
     * a fallback based on the country, city, or time zone id will be used.
     * @param locale the locale in which to supply the display name.
     * @return the human-readable name of this time zone in the given locale
     * or in the default locale if the given locale is not recognized.
     * @stable ICU 2.0
     */
    public final String getDisplayName(Locale locale) {
        return _getDisplayName(LONG_GENERIC, false, ULocale.forLocale(locale));
    }

    /**
     * Returns a name of this time zone suitable for presentation to the user
     * in the specified locale.
     * This method returns the long name, not including daylight savings.
     * If the display name is not available for the locale,
     * a fallback based on the country, city, or time zone id will be used.
     * @param locale the ulocale in which to supply the display name.
     * @return the human-readable name of this time zone in the given locale
     * or in the default ulocale if the given ulocale is not recognized.
     * @stable ICU 3.2
     */
    public final String getDisplayName(ULocale locale) {
        return _getDisplayName(LONG_GENERIC, false, locale);
    }

    /**
     * Returns a name of this time zone suitable for presentation to the user
     * in the default <code>DISPLAY</code> locale.
     * If the display name is not available for the locale,
     * then this method returns a string in the localized GMT offset format
     * such as <code>GMT[+-]HH:mm</code>.
     * @param daylight if true, return the daylight savings name.
     * @param style the output style of the display name.  Valid styles are
     * <code>SHORT</code>, <code>LONG</code>, <code>SHORT_GENERIC</code>,
     * <code>LONG_GENERIC</code>, <code>SHORT_GMT</code>, <code>LONG_GMT</code>,
     * <code>SHORT_COMMONLY_USED</code> or <code>GENERIC_LOCATION</code>.
     * @return the human-readable name of this time zone in the default locale.
     * @see Category#DISPLAY
     * @stable ICU 2.0
     */
    public final String getDisplayName(boolean daylight, int style) {
        return getDisplayName(daylight, style, ULocale.getDefault(Category.DISPLAY));
    }

    /**
     * Returns a name of this time zone suitable for presentation to the user
     * in the specified locale.
     * If the display name is not available for the locale,
     * then this method returns a string in the localized GMT offset format
     * such as <code>GMT[+-]HH:mm</code>.
     * @param daylight if true, return the daylight savings name.
     * @param style the output style of the display name.  Valid styles are
     * <code>SHORT</code>, <code>LONG</code>, <code>SHORT_GENERIC</code>,
     * <code>LONG_GENERIC</code>, <code>SHORT_GMT</code>, <code>LONG_GMT</code>,
     * <code>SHORT_COMMONLY_USED</code> or <code>GENERIC_LOCATION</code>.
     * @param locale the locale in which to supply the display name.
     * @return the human-readable name of this time zone in the given locale
     * or in the default locale if the given locale is not recognized.
     * @exception IllegalArgumentException style is invalid.
     * @stable ICU 2.0
     */
    public String getDisplayName(boolean daylight, int style, Locale locale) {
        return getDisplayName(daylight, style, ULocale.forLocale(locale));
    }

    /**
     * Returns a name of this time zone suitable for presentation to the user
     * in the specified locale.
     * If the display name is not available for the locale,
     * then this method returns a string in the localized GMT offset format
     * such as <code>GMT[+-]HH:mm</code>.
     * @param daylight if true, return the daylight savings name.
     * @param style the output style of the display name.  Valid styles are
     * <code>SHORT</code>, <code>LONG</code>, <code>SHORT_GENERIC</code>,
     * <code>LONG_GENERIC</code>, <code>SHORT_GMT</code>, <code>LONG_GMT</code>,
     * <code>SHORT_COMMONLY_USED</code> or <code>GENERIC_LOCATION</code>.
     * @param locale the locale in which to supply the display name.
     * @return the human-readable name of this time zone in the given locale
     * or in the default locale if the given locale is not recognized.
     * @exception IllegalArgumentException style is invalid.
     * @stable ICU 3.2
     */
    public String getDisplayName(boolean daylight, int style, ULocale locale) {
        if (style < SHORT || style > GENERIC_LOCATION) {
            throw new IllegalArgumentException("Illegal style: " + style);
        }
        
        return _getDisplayName(style, daylight, locale);
    }

    /**
     * internal version (which is called by public APIs) accepts
     * SHORT, LONG, SHORT_GENERIC, LONG_GENERIC, SHORT_GMT, LONG_GMT,
     * SHORT_COMMONLY_USED and GENERIC_LOCATION.
     */
    private String _getDisplayName(int style, boolean daylight, ULocale locale) {
        if (locale == null) {
            throw new NullPointerException("locale is null");
        }

        String result = null;

        if (style == GENERIC_LOCATION || style == LONG_GENERIC || style == SHORT_GENERIC) {
            // Generic format
            TimeZoneFormat tzfmt = TimeZoneFormat.getInstance(locale);
            long date = System.currentTimeMillis();
            Output<TimeType> timeType = new Output<TimeType>(TimeType.UNKNOWN);

            switch (style) {
            case GENERIC_LOCATION:
                result = tzfmt.format(Style.GENERIC_LOCATION, this, date, timeType);
                break;
            case LONG_GENERIC:
                result = tzfmt.format(Style.GENERIC_LONG, this, date, timeType);
                break;
            case SHORT_GENERIC:
                result = tzfmt.format(Style.GENERIC_SHORT, this, date, timeType);
                break;
            }

            // Generic format many use Localized GMT as the final fallback.
            // When Localized GMT format is used, the result might not be
            // appropriate for the requested daylight value.
            if (daylight && timeType.value == TimeType.STANDARD ||
                    !daylight && timeType.value == TimeType.DAYLIGHT) {
                int offset = daylight ? getRawOffset() + getDSTSavings() : getRawOffset();
                result = tzfmt.formatOffsetLocalizedGMT(offset);
            }

        } else if (style == LONG_GMT || style == SHORT_GMT) {
            // Offset format
            TimeZoneFormat tzfmt = TimeZoneFormat.getInstance(locale);
            int offset = daylight && useDaylightTime() ? getRawOffset() + getDSTSavings() : getRawOffset();
            switch (style) {
            case LONG_GMT:
                result = tzfmt.formatOffsetLocalizedGMT(offset);
                break;
            case SHORT_GMT:
                result = tzfmt.formatOffsetRFC822(offset);
                break;
            }
        } else {
            // Specific format
            assert(style == LONG || style == SHORT || style == SHORT_COMMONLY_USED);

            // Gets the name directly from TimeZoneNames
            long date = System.currentTimeMillis();
            TimeZoneNames tznames = TimeZoneNames.getInstance(locale);
            NameType nameType = null;
            switch (style) {
            case LONG:
                nameType = daylight ? NameType.LONG_DAYLIGHT : NameType.LONG_STANDARD;
                break;
            case SHORT:
            case SHORT_COMMONLY_USED:
                nameType = daylight ? NameType.SHORT_DAYLIGHT : NameType.SHORT_STANDARD;
                break;
            }
            result = tznames.getDisplayName(ZoneMeta.getCanonicalCLDRID(this), nameType, date);
            if (result == null) {
                // Fallback to localized GMT
                TimeZoneFormat tzfmt = TimeZoneFormat.getInstance(locale);
                int offset = daylight && useDaylightTime() ? getRawOffset() + getDSTSavings() : getRawOffset();
                result = tzfmt.formatOffsetLocalizedGMT(offset);
            }
        }
        assert(result != null);

        return result;
    }

    /**
     * Returns the amount of time to be added to local standard time
     * to get local wall clock time.
     * <p>
     * The default implementation always returns 3600000 milliseconds
     * (i.e., one hour) if this time zone observes Daylight Saving
     * Time. Otherwise, 0 (zero) is returned.
     * <p>
     * If an underlying TimeZone implementation subclass supports
     * historical Daylight Saving Time changes, this method returns
     * the known latest daylight saving value.
     *
     * @return the amount of saving time in milliseconds
     * @stable ICU 2.8
     */
    public int getDSTSavings() {
        if (useDaylightTime()) {
            return 3600000;
        }
        return 0;
    }

    /**
     * Queries if this time zone uses daylight savings time.
     * @return true if this time zone uses daylight savings time,
     * false, otherwise.
     * <p><strong>Note:</strong>The default implementation of
     * ICU TimeZone uses the tz database, which supports historic
     * rule changes, for system time zones. With the implementation,
     * there are time zones that used daylight savings time in the
     * past, but no longer used currently. For example, Asia/Tokyo has
     * never used daylight savings time since 1951. Most clients would
     * expect that this method to return <code>false</code> for such case.
     * The default implementation of this method returns <code>true</code>
     * when the time zone uses daylight savings time in the current
     * (Gregorian) calendar year.
     * @stable ICU 2.0
     */
    abstract public boolean useDaylightTime();

    /**
     * Queries if this time zone is in daylight saving time or will observe
     * daylight saving time at any future time.
     * <p>The default implementation in this class returns <code>true</code> if {@link #useDaylightTime()}
     * or {@link #inDaylightTime(Date) inDaylightTime(new Date())} returns <code>true</code>.
     * <p>
     * <strong>Note:</strong> This method was added for JDK compatibility support.
     * The JDK's <code>useDaylightTime()</code> only checks the last known rule(s), therefore
     * it may return false even the zone observes daylight saving time currently. JDK added
     * <code>observesDaylightTime()</code> to resolve the issue. In ICU, {@link #useDaylightTime()}
     * works differently. The ICU implementation checks if the zone uses daylight saving time
     * in the current calendar year. Therefore, it will never return <code>false</code> if
     * daylight saving time is currently used.
     * <p>
     * ICU's TimeZone subclass implementations override this method to support the same behavior
     * with JDK's <code>observesDaylightSavingTime()</code>. Unlike {@link #useDaylightTime()},
     * the implementation does not take past daylight saving time into account, so
     * that this method may return <code>false</code> even when {@link #useDaylightTime()} returns
     * <code>true</code>.
     * 
     * @return <code>true</code> if this time zone is in daylight saving time or will observe
     * daylight saving time at any future time.
     * @see #useDaylightTime
     * @stable ICU 49
     */
    public boolean observesDaylightTime() {
        return useDaylightTime() || inDaylightTime(new Date());
    }

    /**
     * Queries if the given date is in daylight savings time in
     * this time zone.
     * @param date the given Date.
     * @return true if the given date is in daylight savings time,
     * false, otherwise.
     * @stable ICU 2.0
     */
    abstract public boolean inDaylightTime(Date date);

    /**
     * Gets the <code>TimeZone</code> for the given ID.
     *
     * @param ID the ID for a <code>TimeZone</code>, such as "America/Los_Angeles",
     * or a custom ID such as "GMT-8:00". Note that the support of abbreviations,
     * such as "PST", is for JDK 1.1.x compatibility only and full names should be used.
     *
     * @return the specified <code>TimeZone</code>, or a mutable clone of the UNKNOWN_ZONE
     * if the given ID cannot be understood or if the given ID is "Etc/Unknown".
     * @see #UNKNOWN_ZONE
     * @stable ICU 2.0
     */
    public static TimeZone getTimeZone(String ID) {
        return getTimeZone(ID, TZ_IMPL, false);
    }

    /**
     * Gets the <code>TimeZone</code> for the given ID. The instance of <code>TimeZone</code>
     * returned by this method is immutable. Any methods mutate the instance({@link #setID(String)},
     * {@link #setRawOffset(int)}) will throw <code>UnsupportedOperationException</code> upon its
     * invocation.
     *
     * @param ID the ID for a <code>TimeZone</code>, such as "America/Los_Angeles",
     * or a custom ID such as "GMT-8:00". Note that the support of abbreviations,
     * such as "PST", is for JDK 1.1.x compatibility only and full names should be used.
     *
     * @return the specified <code>TimeZone</code>, or the UNKNOWN_ZONE
     * if the given ID cannot be understood.
     * @see #UNKNOWN_ZONE
     * @draft ICU 49
     * @provisional This API might change or be removed in a future release.
     */
    public static TimeZone getFrozenTimeZone(String ID) {
        return getTimeZone(ID, TZ_IMPL, true);
    }

    /**
     * Gets the <code>TimeZone</code> for the given ID and the timezone type.
     * @param ID the ID for a <code>TimeZone</code>, such as "America/Los_Angeles", or a
     * custom ID such as "GMT-8:00". Note that the support of abbreviations, such as
     * "PST", is for JDK 1.1.x compatibility only and full names should be used.
     * @param type Time zone type, either <code>TIMEZONE_ICU</code> or
     * <code>TIMEZONE_JDK</code>.
     * @return the specified <code>TimeZone</code>, or a mutable clone of the UNKNOWN_ZONE if the given ID
     * cannot be understood or if the given ID is "Etc/Unknown".
     * @see #UNKNOWN_ZONE
     * @stable ICU 4.0
     */
    public static TimeZone getTimeZone(String ID, int type) {
        return getTimeZone(ID, type, false);
    }

    /**
     * Gets the <code>TimeZone</code> for the given ID and the timezone type.
     * @param ID time zone ID
     * @param type time zone implementation type, TIMEZONE_JDK or TIMEZONE_ICU 
     * @param frozen specify if the returned object can be frozen
     * @return the specified <code>TimeZone</code> or UNKNOWN_ZONE if the given ID
     * cannot be understood.
     */
    private static synchronized TimeZone getTimeZone(String ID, int type, boolean frozen) {
        TimeZone result;
        if (type == TIMEZONE_JDK) {
            result = JavaTimeZone.createTimeZone(ID);
            if (result != null) {
                return frozen ? result.freeze() : result;
            }
        } else {
            /* We first try to lookup the zone ID in our system list.  If this
             * fails, we try to parse it as a custom string GMT[+-]HH:mm.  If
             * all else fails, we return GMT, which is probably not what the
             * user wants, but at least is a functioning TimeZone object.
             *
             * We cannot return NULL, because that would break compatibility
             * with the JDK.
             */
            if(ID==null){
                throw new NullPointerException();
            }
            result = ZoneMeta.getSystemTimeZone(ID);
        }

        if (result == null) {
            result = ZoneMeta.getCustomTimeZone(ID);
        }

        if (result == null) {
            LOGGER.fine("\"" +ID + "\" is a bogus id so timezone is falling back to Etc/Unknown(GMT).");
            result = UNKNOWN_ZONE;
        }

        return frozen ? result : result.cloneAsThawed();
    }

    /**
     * Sets the default time zone type used by <code>getTimeZone</code>.
     * @param type time zone type, either <code>TIMEZONE_ICU</code> or
     * <code>TIMEZONE_JDK</code>.
     * @stable ICU 4.0
     */
    public static synchronized void setDefaultTimeZoneType(int type) {
        if (type != TIMEZONE_ICU && type != TIMEZONE_JDK) {
            throw new IllegalArgumentException("Invalid timezone type");
        }
        TZ_IMPL = type;
    }

    /**
     * {@icu} Returns the default time zone type currently used.
     * @return The default time zone type, either <code>TIMEZONE_ICU</code> or
     * <code>TIMEZONE_JDK</code>.
     * @stable ICU 4.0
     */
    public static int getDefaultTimeZoneType() {
        return TZ_IMPL;
    }

    /** 
     * {@icu} Returns a set of time zone ID strings with the given filter conditions. 
     * <p><b>Note:</b>A <code>Set</code> returned by this method is
     * immutable.
     * @param zoneType      The system time zone type.
     * @param region        The ISO 3166 two-letter country code or UN M.49 three-digit area code. 
     *                      When null, no filtering done by region. 
     * @param rawOffset     An offset from GMT in milliseconds, ignoring the effect of daylight savings 
     *                      time, if any. When null, no filtering done by zone offset. 
     * @return an immutable set of system time zone IDs.
     * @see SystemTimeZoneType
     * 
     * @stable ICU 4.8
     */ 
    public static Set<String> getAvailableIDs(SystemTimeZoneType zoneType,
            String region, Integer rawOffset) {
        return ZoneMeta.getAvailableIDs(zoneType, region, rawOffset);
    }

    /**
     * Return a new String array containing all system TimeZone IDs
     * with the given raw offset from GMT.  These IDs may be passed to
     * <code>get()</code> to construct the corresponding TimeZone
     * object.
     * @param rawOffset the offset in milliseconds from GMT
     * @return an array of IDs for system TimeZones with the given
     * raw offset.  If there are none, return a zero-length array.
     * @see #getAvailableIDs(SystemTimeZoneType, String, Integer)
     * 
     * @stable ICU 2.0
     */
    public static String[] getAvailableIDs(int rawOffset) {
        Set<String> ids = getAvailableIDs(SystemTimeZoneType.ANY, null, Integer.valueOf(rawOffset));
        return ids.toArray(new String[0]);
    }

    /**
     * Return a new String array containing all system TimeZone IDs
     * associated with the given country.  These IDs may be passed to
     * <code>get()</code> to construct the corresponding TimeZone
     * object.
     * @param country a two-letter ISO 3166 country code, or <code>null</code>
     * to return zones not associated with any country
     * @return an array of IDs for system TimeZones in the given
     * country.  If there are none, return a zero-length array.
     * @see #getAvailableIDs(SystemTimeZoneType, String, Integer)
     * 
     * @stable ICU 2.0
     */
    public static String[] getAvailableIDs(String country) {
        Set<String> ids = getAvailableIDs(SystemTimeZoneType.ANY, country, null);
        return ids.toArray(new String[0]);
    }

    /**
     * Return a new String array containing all system TimeZone IDs.
     * These IDs (and only these IDs) may be passed to
     * <code>get()</code> to construct the corresponding TimeZone
     * object.
     * @return an array of all system TimeZone IDs
     * @see #getAvailableIDs(SystemTimeZoneType, String, Integer)
     * 
     * @stable ICU 2.0
     */
    public static String[] getAvailableIDs() {
        Set<String> ids = getAvailableIDs(SystemTimeZoneType.ANY, null, null);
        return ids.toArray(new String[0]);
    }

    /**
     * {@icu} Returns the number of IDs in the equivalency group that
     * includes the given ID.  An equivalency group contains zones
     * that have the same GMT offset and rules.
     *
     * <p>The returned count includes the given ID; it is always >= 1
     * for valid IDs.  The given ID must be a system time zone.  If it
     * is not, returns zero.
     * @param id a system time zone ID
     * @return the number of zones in the equivalency group containing
     * 'id', or zero if 'id' is not a valid system ID
     * @see #getEquivalentID
     * @stable ICU 2.0
     */
    public static int countEquivalentIDs(String id) {
        return ZoneMeta.countEquivalentIDs(id);
    }

    /**
     * Returns an ID in the equivalency group that
     * includes the given ID.  An equivalency group contains zones
     * that have the same GMT offset and rules.
     *
     * <p>The given index must be in the range 0..n-1, where n is the
     * value returned by <code>countEquivalentIDs(id)</code>.  For
     * some value of 'index', the returned value will be equal to the
     * given id.  If the given id is not a valid system time zone, or
     * if 'index' is out of range, then returns an empty string.
     * @param id a system time zone ID
     * @param index a value from 0 to n-1, where n is the value
     * returned by <code>countEquivalentIDs(id)</code>
     * @return the ID of the index-th zone in the equivalency group
     * containing 'id', or an empty string if 'id' is not a valid
     * system ID or 'index' is out of range
     * @see #countEquivalentIDs
     * @stable ICU 2.0
     */
    public static String getEquivalentID(String id, int index) {
        return ZoneMeta.getEquivalentID(id, index);
    }

    /**
     * Gets the default <code>TimeZone</code> for this host.
     * The source of the default <code>TimeZone</code>
     * may vary with implementation.
     * @return a default <code>TimeZone</code>.
     * @stable ICU 2.0
     */
    public static synchronized TimeZone getDefault() {
        if (defaultZone == null) {
            if (TZ_IMPL == TIMEZONE_JDK) {
                defaultZone = new JavaTimeZone();
            } else {
                java.util.TimeZone temp = java.util.TimeZone.getDefault();
                defaultZone = getFrozenTimeZone(temp.getID());
            }
        }
        return defaultZone.cloneAsThawed();
    }

    /**
     * Sets the <code>TimeZone</code> that is
     * returned by the <code>getDefault</code> method.  If <code>zone</code>
     * is null, reset the default to the value it had originally when the
     * VM first started.
     * @param tz the new default time zone
     * @stable ICU 2.0
     */
    public static synchronized void setDefault(TimeZone tz) {
        defaultZone = tz;
        java.util.TimeZone jdkZone = null;
        if (defaultZone instanceof JavaTimeZone) {
            jdkZone = ((JavaTimeZone)defaultZone).unwrap();
        } else {
            // Keep java.util.TimeZone default in sync so java.util.Date
            // can interoperate with com.ibm.icu.util classes.

            if (tz != null) {
                if (tz instanceof com.ibm.icu.impl.OlsonTimeZone) {
                    // Because of the lack of APIs supporting historic
                    // zone offset/dst saving in JDK TimeZone,
                    // wrapping ICU TimeZone with JDK TimeZone will
                    // cause historic offset calculation in Calendar/Date.
                    // JDK calendar implementation calls getRawOffset() and
                    // getDSTSavings() when the instance of JDK TimeZone
                    // is not an instance of JDK internal TimeZone subclass
                    // (sun.util.calendar.ZoneInfo).  Ticket#6459
                    String icuID = tz.getID();
                    jdkZone = java.util.TimeZone.getTimeZone(icuID);
                    if (!icuID.equals(jdkZone.getID())) {
                        // JDK does not know the ID..
                        jdkZone = null;
                    }
                }
                if (jdkZone == null) {
                    jdkZone = TimeZoneAdapter.wrap(tz);
                }
            }
        }
        java.util.TimeZone.setDefault(jdkZone);
    }

    /**
     * Returns true if this zone has the same rule and offset as another zone.
     * That is, if this zone differs only in ID, if at all.  Returns false
     * if the other zone is null.
     * @param other the <code>TimeZone</code> object to be compared with
     * @return true if the other zone is not null and is the same as this one,
     * with the possible exception of the ID
     * @stable ICU 2.0
     */
    public boolean hasSameRules(TimeZone other) {
        return other != null &&
            getRawOffset() == other.getRawOffset() &&
            useDaylightTime() == other.useDaylightTime();
    }

    /**
     * Overrides clone.
     * @stable ICU 2.0
     */
    public Object clone() {
        if (isFrozen()) {
            return this;
        }
        return cloneAsThawed();
    }

    /**
     * Overrides equals.
     * @stable ICU 3.6
     */
    public boolean equals(Object obj){
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        return (ID.equals(((TimeZone)obj).ID));
    }

    /**
     * Overrides hashCode.
     * @stable ICU 3.6
     */
    public int hashCode(){
        return ID.hashCode();
    }

    /**
     * {@icu} Returns the time zone data version currently used by ICU.
     *
     * @return the version string, such as "2007f"
     * @throws MissingResourceException if ICU time zone resource bundle
     * is missing or the version information is not available.
     *
     * @stable ICU 3.8
     */
    public static synchronized String getTZDataVersion() {
        if (TZDATA_VERSION == null) {
            UResourceBundle tzbundle = UResourceBundle.getBundleInstance(
                    "com/ibm/icu/impl/data/icudt" + VersionInfo.ICU_DATA_VERSION_PATH, "zoneinfo64");
            TZDATA_VERSION = tzbundle.getString("TZVersion");
        }
        return TZDATA_VERSION;
    }

    /**
     * {@icu} Returns the canonical system time zone ID or the normalized
     * custom time zone ID for the given time zone ID.
     * @param id The input time zone ID to be canonicalized.
     * @return The canonical system time zone ID or the custom time zone ID
     * in normalized format for the given time zone ID.  When the given time zone ID
     * is neither a known system time zone ID nor a valid custom time zone ID,
     * null is returned.
     * @stable ICU 4.0
     */
    public static String getCanonicalID(String id) {
        return getCanonicalID(id, null);
    }

    /**
     * {@icu} Returns the canonical system time zone ID or the normalized
     * custom time zone ID for the given time zone ID.
     * @param id The input time zone ID to be canonicalized.
     * @param isSystemID When non-null boolean array is specified and
     * the given ID is a known system time zone ID, true is set to <code>isSystemID[0]</code>
     * @return The canonical system time zone ID or the custom time zone ID
     * in normalized format for the given time zone ID.  When the given time zone ID
     * is neither a known system time zone ID nor a valid custom time zone ID,
     * null is returned.
     * @stable ICU 4.0
     */
    public static String getCanonicalID(String id, boolean[] isSystemID) {
        String canonicalID = null;
        boolean systemTzid = false;
        if (id != null && id.length() != 0) {
            if (id.equals(TimeZone.UNKNOWN_ZONE_ID)) {
                // special case - Etc/Unknown is a canonical ID, but not system ID
                canonicalID = TimeZone.UNKNOWN_ZONE_ID;
                systemTzid = false;
            } else {
                canonicalID = ZoneMeta.getCanonicalCLDRID(id);
                if (canonicalID != null) {
                    systemTzid = true;
                } else {
                    canonicalID = ZoneMeta.getCustomID(id);
                }
            }
        }
        if (isSystemID != null) {
            isSystemID[0] = systemTzid;
        }
        return canonicalID;
    }

    /** 
     * {@icu} Returns the region code associated with the given 
     * system time zone ID. The region code is either ISO 3166 
     * 2-letter country code or UN M.49 3-digit area code. 
     * When the time zone is not associated with a specific location, 
     * for example - "Etc/UTC", "EST5EDT", then this method returns 
     * "001" (UN M.49 area code for World). 
     * @param id the system time zone ID. 
     * @return the region code associated with the given 
     * system time zone ID. 
     * @throws IllegalArgumentException if <code>id</code> is not a known system ID. 
     * @see #getAvailableIDs(String) 
     * 
     * @stable ICU 4.8
     */ 
    public static String getRegion(String id) {
        String region = null;
        // "Etc/Unknown" is not a system time zone ID,
        // but in the zone data.
        if (!id.equals(UNKNOWN_ZONE_ID)) {
            region = ZoneMeta.getRegion(id);
        }
        if (region == null) {
            // unknown id
            throw new IllegalArgumentException("Unknown system zone id: " + id);
        }
        return region;
    }

    // Freezable stuffs

    /**
     * {@inheritDoc}
     * @draft ICU 49
     * @provisional This API might change or be removed in a future release.
     */
    public boolean isFrozen() {
        return false;
    }

    /**
     * {@inheritDoc}
     * @draft ICU 49
     * @provisional This API might change or be removed in a future release.
     */
    public TimeZone freeze() {
        throw new UnsupportedOperationException("Needs to be implemented by the subclass.");
    }

    /**
     * {@inheritDoc}
     * @draft ICU 49
     * @provisional This API might change or be removed in a future release.
     */
    public TimeZone cloneAsThawed() {
        try {
            TimeZone other = (TimeZone) super.clone();
            return other;
        } catch (CloneNotSupportedException e) {
            throw new RuntimeException(e);
        }
    }

    // =======================privates===============================

    /**
     * The string identifier of this <code>TimeZone</code>.  This is a
     * programmatic identifier used internally to look up <code>TimeZone</code>
     * objects from the system table and also to map them to their localized
     * display names.  <code>ID</code> values are unique in the system
     * table but may not be for dynamically created zones.
     * @serial
     */
    private String           ID;

    /**
     * The default time zone, or null if not set.
     */
    private static TimeZone  defaultZone = null;

    /**
     * The tzdata version
     */
    private static String TZDATA_VERSION = null;

    /**
     * TimeZone implementation type
     */
    private static int TZ_IMPL = TIMEZONE_ICU;

    /**
     * TimeZone implementation type initialization
     */
    private static final String TZIMPL_CONFIG_KEY = "com.ibm.icu.util.TimeZone.DefaultTimeZoneType";
    private static final String TZIMPL_CONFIG_ICU = "ICU";
    private static final String TZIMPL_CONFIG_JDK = "JDK";

    static {
        String type = ICUConfig.get(TZIMPL_CONFIG_KEY, TZIMPL_CONFIG_ICU);
        if (type.equalsIgnoreCase(TZIMPL_CONFIG_JDK)) {
            TZ_IMPL = TIMEZONE_JDK;
        }
    }
}

//eof
