// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
 /*
*   Copyright (C) 1996-2016, International Business Machines
*   Corporation and others.  All Rights Reserved.
*/

package com.ibm.icu.util;

import java.io.IOException;
import java.util.Date;

import com.ibm.icu.impl.Grego;

/**
 * {@icuenhanced java.util.SimpleTimeZone}.{@icu _usage_}
 *
 * <p><code>SimpleTimeZone</code> is a concrete subclass of <code>TimeZone</code>
 * that represents a time zone for use with a Gregorian calendar. This
 * class does not handle historical changes.
 *
 * <p>Use a negative value for <code>dayOfWeekInMonth</code> to indicate that
 * <code>SimpleTimeZone</code> should count from the end of the month backwards.  For
 * example, if Daylight Savings Time starts or ends at the last Sunday in a month, use
 * <code>dayOfWeekInMonth = -1</code> along with <code>dayOfWeek = Calendar.SUNDAY</code>
 * to specify the rule.
 *
 * @see      Calendar
 * @see      GregorianCalendar
 * @see      TimeZone
 * @author   Deborah Goldsmith, Mark Davis, Chen-Lieh Huang, Alan Liu
 * @stable ICU 2.0
 */
public class SimpleTimeZone extends BasicTimeZone {
    private static final long serialVersionUID = -7034676239311322769L;

    /**
     * Constant for a mode of start or end time specified as local wall time.
     * @stable ICU 3.8
     */
    public static final int WALL_TIME = 0;

    /**
     * Constant for a mode of start or end time specified as local standard time.
     * @stable ICU 3.8
     */
    public static final int STANDARD_TIME = 1;

    /**
     * Constant for a mode of start or end time specified as UTC.
     * @stable ICU 3.8
     */
    public static final int UTC_TIME = 2;

    /**
     * Constructs a SimpleTimeZone with the given base time zone offset from GMT
     * and time zone ID. Timezone IDs can be obtained from
     * TimeZone.getAvailableIDs. Normally you should use TimeZone.getDefault to
     * construct a TimeZone.
     *
     * @param rawOffset  The given base time zone offset to GMT.
     * @param ID         The time zone ID which is obtained from
     *                   TimeZone.getAvailableIDs.
     * @stable ICU 2.0
     */
    public SimpleTimeZone(int rawOffset, String ID) {
        super(ID);
        construct(rawOffset, 0, 0, 0,
                0, WALL_TIME,
                0, 0, 0,
                0, WALL_TIME,
                Grego.MILLIS_PER_HOUR);
    }

    /**
     * Constructs a SimpleTimeZone with the given base time zone offset from
     * GMT, time zone ID, time to start and end the daylight time. Timezone IDs
     * can be obtained from TimeZone.getAvailableIDs. Normally you should use
     * TimeZone.getDefault to create a TimeZone. For a time zone that does not
     * use daylight saving time, do not use this constructor; instead you should
     * use SimpleTimeZone(rawOffset, ID).
     *
     * By default, this constructor specifies day-of-week-in-month rules. That
     * is, if the startDay is 1, and the startDayOfWeek is SUNDAY, then this
     * indicates the first Sunday in the startMonth. A startDay of -1 likewise
     * indicates the last Sunday. However, by using negative or zero values for
     * certain parameters, other types of rules can be specified.
     *
     * Day of month. To specify an exact day of the month, such as March 1, set
     * startDayOfWeek to zero.
     *
     * Day of week after day of month. To specify the first day of the week
     * occurring on or after an exact day of the month, make the day of the week
     * negative. For example, if startDay is 5 and startDayOfWeek is -MONDAY,
     * this indicates the first Monday on or after the 5th day of the
     * startMonth.
     *
     * Day of week before day of month. To specify the last day of the week
     * occurring on or before an exact day of the month, make the day of the
     * week and the day of the month negative. For example, if startDay is -21
     * and startDayOfWeek is -WEDNESDAY, this indicates the last Wednesday on or
     * before the 21st of the startMonth.
     *
     * The above examples refer to the startMonth, startDay, and startDayOfWeek;
     * the same applies for the endMonth, endDay, and endDayOfWeek.
     *
     * @param rawOffset       The given base time zone offset to GMT.
     * @param ID              The time zone ID which is obtained from
     *                        TimeZone.getAvailableIDs.
     * @param startMonth      The daylight savings starting month. Month is
     *                        0-based. eg, 0 for January.
     * @param startDay        The daylight savings starting
     *                        day-of-week-in-month. Please see the member
     *                        description for an example.
     * @param startDayOfWeek  The daylight savings starting day-of-week. Please
     *                        see the member description for an example.
     * @param startTime       The daylight savings starting time in local wall
     *                        time, which is standard time in this case. Please see the
     *                        member description for an example.
     * @param endMonth        The daylight savings ending month. Month is
     *                        0-based. eg, 0 for January.
     * @param endDay          The daylight savings ending day-of-week-in-month.
     *                        Please see the member description for an example.
     * @param endDayOfWeek    The daylight savings ending day-of-week. Please
     *                        see the member description for an example.
     * @param endTime         The daylight savings ending time in local wall time,
     *                        which is daylight time in this case. Please see the
     *                        member description for an example.
     * @throws IllegalArgumentException the month, day, dayOfWeek, or time
     * parameters are out of range for the start or end rule
     * @stable ICU 2.0
     */
    public SimpleTimeZone(int rawOffset, String ID,
                          int startMonth, int startDay, int startDayOfWeek, int startTime,
                          int endMonth, int endDay, int endDayOfWeek, int endTime) {
        super(ID);
        construct(rawOffset,
                startMonth, startDay, startDayOfWeek,
                startTime, WALL_TIME,
                endMonth, endDay, endDayOfWeek,
                endTime, WALL_TIME,
                Grego.MILLIS_PER_HOUR);
    }

    /**
     * Constructs a SimpleTimeZone with the given base time zone offset from
     * GMT, time zone ID, time and its mode to start and end the daylight time.
     * The mode specifies either {@link #WALL_TIME} or {@link #STANDARD_TIME}
     * or {@link #UTC_TIME}.
     *
     * @param rawOffset       The given base time zone offset to GMT.
     * @param ID              The time zone ID which is obtained from
     *                        TimeZone.getAvailableIDs.
     * @param startMonth      The daylight savings starting month. Month is
     *                        0-based. eg, 0 for January.
     * @param startDay        The daylight savings starting
     *                        day-of-week-in-month. Please see the member
     *                        description for an example.
     * @param startDayOfWeek  The daylight savings starting day-of-week. Please
     *                        see the member description for an example.
     * @param startTime       The daylight savings starting time in local wall
     *                        time, which is standard time in this case. Please see the
     *                        member description for an example.
     * @param startTimeMode   The mode of the start time specified by startTime.
     * @param endMonth        The daylight savings ending month. Month is
     *                        0-based. eg, 0 for January.
     * @param endDay          The daylight savings ending day-of-week-in-month.
     *                        Please see the member description for an example.
     * @param endDayOfWeek    The daylight savings ending day-of-week. Please
     *                        see the member description for an example.
     * @param endTime         The daylight savings ending time in local wall time,
     *                        which is daylight time in this case. Please see the
     *                        member description for an example.
     * @param endTimeMode     The mode of the end time specified by endTime.
     * @param dstSavings      The amount of time in ms saved during DST.
     * @throws IllegalArgumentException the month, day, dayOfWeek, or time
     * parameters are out of range for the start or end rule
     * @stable ICU 3.8
     */
    public SimpleTimeZone(int rawOffset,  String ID,
                          int startMonth, int startDay,
                          int startDayOfWeek, int startTime,
                          int startTimeMode,
                          int endMonth, int endDay,
                          int endDayOfWeek, int endTime,
                          int endTimeMode,int dstSavings){
        super(ID);
        construct(rawOffset,
                  startMonth, startDay, startDayOfWeek,
                  startTime, startTimeMode,
                  endMonth, endDay, endDayOfWeek,
                  endTime, endTimeMode,
                  dstSavings);
    }

    /**
     * Constructor.  This constructor is identical to the 10-argument
     * constructor, but also takes a dstSavings parameter.
     * @param rawOffset       The given base time zone offset to GMT.
     * @param ID              The time zone ID which is obtained from
     *                        TimeZone.getAvailableIDs.
     * @param startMonth      The daylight savings starting month. Month is
     *                        0-based. eg, 0 for January.
     * @param startDay        The daylight savings starting
     *                        day-of-week-in-month. Please see the member
     *                        description for an example.
     * @param startDayOfWeek  The daylight savings starting day-of-week. Please
     *                        see the member description for an example.
     * @param startTime       The daylight savings starting time in local wall
     *                        time, which is standard time in this case. Please see the
     *                        member description for an example.
     * @param endMonth        The daylight savings ending month. Month is
     *                        0-based. eg, 0 for January.
     * @param endDay          The daylight savings ending day-of-week-in-month.
     *                        Please see the member description for an example.
     * @param endDayOfWeek    The daylight savings ending day-of-week. Please
     *                        see the member description for an example.
     * @param endTime         The daylight savings ending time in local wall time,
     *                        which is daylight time in this case. Please see the
     *                        member description for an example.
     * @param dstSavings      The amount of time in ms saved during DST.
     * @throws IllegalArgumentException the month, day, dayOfWeek, or time
     * parameters are out of range for the start or end rule
     * @stable ICU 2.0
     */
    public SimpleTimeZone(int rawOffset, String ID,
                          int startMonth, int startDay, int startDayOfWeek, int startTime,
                          int endMonth, int endDay, int endDayOfWeek, int endTime,
                          int dstSavings) {
        super(ID);
        construct(rawOffset,
                startMonth, startDay, startDayOfWeek,
                startTime, WALL_TIME,
                endMonth, endDay, endDayOfWeek,
                endTime, WALL_TIME,
                dstSavings);
    }

    /**
     * {@inheritDoc}
     *
     * @stable ICU 3.8
     */
    @Override
    public void setID(String ID) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify a frozen SimpleTimeZone instance.");
        }
        super.setID(ID);
        transitionRulesInitialized = false;
    }

    /**
     * Overrides TimeZone
     * Sets the base time zone offset to GMT.
     * This is the offset to add "to" UTC to get local time.
     * @param offsetMillis the raw offset of the time zone
     * @stable ICU 2.0
     */
    @Override
    public void setRawOffset(int offsetMillis) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify a frozen SimpleTimeZone instance.");
        }

        raw = offsetMillis;
        transitionRulesInitialized = false;
    }

    /**
     * Overrides TimeZone
     * Gets the GMT offset for this time zone.
     * @return the raw offset
     * @stable ICU 2.0
     */
    @Override
    public int getRawOffset() {
        return raw;
    }

    /**
     * Sets the daylight savings starting year.
     *
     * @param year  The daylight savings starting year.
     * @stable ICU 2.0
     */
    public void setStartYear(int year) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify a frozen SimpleTimeZone instance.");
        }

        getSTZInfo().sy = year;
        this.startYear = year;
        transitionRulesInitialized = false;
    }

    /**
     * Sets the daylight savings starting rule. For example, Daylight Savings
     * Time starts at the second Sunday in March, at 2 AM in standard time.
     * Therefore, you can set the start rule by calling:
     * setStartRule(Calendar.MARCH, 2, Calendar.SUNDAY, 2*60*60*1000);
     *
     * @param month             The daylight savings starting month. Month is
     *                          0-based. eg, 0 for January.
     * @param dayOfWeekInMonth  The daylight savings starting
     *                          day-of-week-in-month. Please see the member
     *                          description for an example.
     * @param dayOfWeek         The daylight savings starting day-of-week.
     *                          Please see the member description for an
     *                          example.
     * @param time              The daylight savings starting time in local wall
     *                          time, which is standard time in this case. Please see
     *                          the member description for an example.
     * @throws IllegalArgumentException the month, dayOfWeekInMonth,
     * dayOfWeek, or time parameters are out of range
     * @stable ICU 2.0
     */
    public void setStartRule(int month, int dayOfWeekInMonth, int dayOfWeek,
                             int time) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify a frozen SimpleTimeZone instance.");
        }

        getSTZInfo().setStart(month, dayOfWeekInMonth, dayOfWeek, time, -1, false);
        setStartRule(month, dayOfWeekInMonth, dayOfWeek, time, WALL_TIME);
    }

    /**
     * Sets the daylight savings starting rule. For example, in the U.S., Daylight Savings
     * Time starts at the second Sunday in March, at 2 AM in standard time.
     * Therefore, you can set the start rule by calling:
     * <code>setStartRule(Calendar.MARCH, 2, Calendar.SUNDAY, 2*60*60*1000);</code>
     * The dayOfWeekInMonth and dayOfWeek parameters together specify how to calculate
     * the exact starting date.  Their exact meaning depend on their respective signs,
     * allowing various types of rules to be constructed, as follows:<ul>
     *   <li>If both dayOfWeekInMonth and dayOfWeek are positive, they specify the
     *       day of week in the month (e.g., (2, WEDNESDAY) is the second Wednesday
     *       of the month).
     *   <li>If dayOfWeek is positive and dayOfWeekInMonth is negative, they specify
     *       the day of week in the month counting backward from the end of the month.
     *       (e.g., (-1, MONDAY) is the last Monday in the month)
     *   <li>If dayOfWeek is zero and dayOfWeekInMonth is positive, dayOfWeekInMonth
     *       specifies the day of the month, regardless of what day of the week it is.
     *       (e.g., (10, 0) is the tenth day of the month)
     *   <li>If dayOfWeek is zero and dayOfWeekInMonth is negative, dayOfWeekInMonth
     *       specifies the day of the month counting backward from the end of the
     *       month, regardless of what day of the week it is (e.g., (-2, 0) is the
     *       next-to-last day of the month).
     *   <li>If dayOfWeek is negative and dayOfWeekInMonth is positive, they specify the
     *       first specified day of the week on or after the specfied day of the month.
     *       (e.g., (15, -SUNDAY) is the first Sunday after the 15th of the month
     *       [or the 15th itself if the 15th is a Sunday].)
     *   <li>If dayOfWeek and DayOfWeekInMonth are both negative, they specify the
     *       last specified day of the week on or before the specified day of the month.
     *       (e.g., (-20, -TUESDAY) is the last Tuesday before the 20th of the month
     *       [or the 20th itself if the 20th is a Tuesday].)</ul>
     * @param month the daylight savings starting month. Month is 0-based.
     * eg, 0 for January.
     * @param dayOfWeekInMonth the daylight savings starting
     * day-of-week-in-month. Please see the member description for an example.
     * @param dayOfWeek the daylight savings starting day-of-week. Please see
     * the member description for an example.
     * @param time the daylight savings starting time. Please see the member
     * description for an example.
     */
    private void setStartRule(int month, int dayOfWeekInMonth, int dayOfWeek, int time, int mode) {
        assert (!isFrozen());

        startMonth     =  month;
        startDay       = dayOfWeekInMonth;
        startDayOfWeek = dayOfWeek;
        startTime      = time;
        startTimeMode  = mode;
        decodeStartRule();

        transitionRulesInitialized = false;
    }

    /**
     * Sets the DST start rule to a fixed date within a month.
     *
     * @param month         The month in which this rule occurs (0-based).
     * @param dayOfMonth    The date in that month (1-based).
     * @param time          The time of that day (number of millis after midnight)
     *                      when DST takes effect in local wall time, which is
     *                      standard time in this case.
     * @throws IllegalArgumentException the month,
     * dayOfMonth, or time parameters are out of range
     * @stable ICU 2.0
     */
    public void setStartRule(int month, int dayOfMonth, int time) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify a frozen SimpleTimeZone instance.");
        }

        getSTZInfo().setStart(month, -1, -1, time, dayOfMonth, false);
        setStartRule(month, dayOfMonth, 0, time, WALL_TIME);
    }

    /**
     * Sets the DST start rule to a weekday before or after a give date within
     * a month, e.g., the first Monday on or after the 8th.
     *
     * @param month         The month in which this rule occurs (0-based).
     * @param dayOfMonth    A date within that month (1-based).
     * @param dayOfWeek     The day of the week on which this rule occurs.
     * @param time          The time of that day (number of millis after midnight)
     *                      when DST takes effect in local wall time, which is
     *                      standard time in this case.
     * @param after         If true, this rule selects the first dayOfWeek on
     *                      or after dayOfMonth.  If false, this rule selects
     *                      the last dayOfWeek on or before dayOfMonth.
     * @throws IllegalArgumentException the month, dayOfMonth,
     * dayOfWeek, or time parameters are out of range
     * @stable ICU 2.0
     */
    public void setStartRule(int month, int dayOfMonth, int dayOfWeek, int time, boolean after) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify a frozen SimpleTimeZone instance.");
        }

        getSTZInfo().setStart(month, -1, dayOfWeek, time, dayOfMonth, after);
        setStartRule(month, after ? dayOfMonth : -dayOfMonth,
                -dayOfWeek, time, WALL_TIME);
    }

    /**
     * Sets the daylight savings ending rule. For example, if Daylight Savings Time
     * ends at the last (-1) Sunday in October, at 2 AM in standard time,
     * you can set the end rule by calling:
     * <code>setEndRule(Calendar.OCTOBER, -1, Calendar.SUNDAY, 2*60*60*1000);</code>
     *
     * @param month             The daylight savings ending month. Month is
     *                          0-based. eg, 0 for January.
     * @param dayOfWeekInMonth  The daylight savings ending
     *                          day-of-week-in-month. Please see the member
     *                          description for an example.
     * @param dayOfWeek         The daylight savings ending day-of-week. Please
     *                          see the member description for an example.
     * @param time              The daylight savings ending time in local wall time,
     *                          which is daylight time in this case. Please see the
     *                          member description for an example.
     * @throws IllegalArgumentException the month, dayOfWeekInMonth,
     * dayOfWeek, or time parameters are out of range
     * @stable ICU 2.0
     */
    public void setEndRule(int month, int dayOfWeekInMonth, int dayOfWeek, int time) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify a frozen SimpleTimeZone instance.");
        }

        getSTZInfo().setEnd(month, dayOfWeekInMonth, dayOfWeek, time, -1, false);
        setEndRule(month, dayOfWeekInMonth, dayOfWeek, time, WALL_TIME);
    }

    /**
     * Sets the DST end rule to a fixed date within a month.
     *
     * @param month         The month in which this rule occurs (0-based).
     * @param dayOfMonth    The date in that month (1-based).
     * @param time          The time of that day (number of millis after midnight)
     *                      when DST ends in local wall time, which is daylight
     *                      time in this case.
     * @throws IllegalArgumentException the month,
     * dayOfMonth, or time parameters are out of range
     * @stable ICU 2.0
     */
    public void setEndRule(int month, int dayOfMonth, int time) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify a frozen SimpleTimeZone instance.");
        }

        getSTZInfo().setEnd(month, -1, -1, time, dayOfMonth, false);
        setEndRule(month, dayOfMonth, WALL_TIME, time);
    }

    /**
     * Sets the DST end rule to a weekday before or after a give date within
     * a month, e.g., the first Monday on or after the 8th.
     *
     * @param month         The month in which this rule occurs (0-based).
     * @param dayOfMonth    A date within that month (1-based).
     * @param dayOfWeek     The day of the week on which this rule occurs.
     * @param time          The time of that day (number of millis after midnight)
     *                      when DST ends in local wall time, which is daylight
     *                      time in this case.
     * @param after         If true, this rule selects the first dayOfWeek on
     *                      or after dayOfMonth.  If false, this rule selects
     *                      the last dayOfWeek on or before dayOfMonth.
     * @throws IllegalArgumentException the month, dayOfMonth,
     * dayOfWeek, or time parameters are out of range
     * @stable ICU 2.0
     */
    public void setEndRule(int month, int dayOfMonth, int dayOfWeek, int time, boolean after) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify a frozen SimpleTimeZone instance.");
        }

        getSTZInfo().setEnd(month, -1, dayOfWeek, time, dayOfMonth, after);
        setEndRule(month, dayOfMonth, dayOfWeek, time, WALL_TIME, after);
    }

    private void setEndRule(int month, int dayOfMonth, int dayOfWeek,
                                                int time, int mode, boolean after){
        assert (!isFrozen());
        setEndRule(month, after ? dayOfMonth : -dayOfMonth, -dayOfWeek, time, mode);
    }

    /**
     * Sets the daylight savings ending rule. For example, in the U.S., Daylight
     * Savings Time ends at the first Sunday in November, at 2 AM in standard time.
     * Therefore, you can set the end rule by calling:
     * setEndRule(Calendar.NOVEMBER, 1, Calendar.SUNDAY, 2*60*60*1000);
     * Various other types of rules can be specified by manipulating the dayOfWeek
     * and dayOfWeekInMonth parameters.  For complete details, see the documentation
     * for setStartRule().
     * @param month the daylight savings ending month. Month is 0-based.
     * eg, 0 for January.
     * @param dayOfWeekInMonth the daylight savings ending
     * day-of-week-in-month. See setStartRule() for a complete explanation.
     * @param dayOfWeek the daylight savings ending day-of-week. See setStartRule()
     * for a complete explanation.
     * @param time the daylight savings ending time. Please see the member
     * description for an example.
     */
    private void setEndRule(int month, int dayOfWeekInMonth, int dayOfWeek, int time, int mode){
        assert (!isFrozen());

        endMonth     = month;
        endDay       = dayOfWeekInMonth;
        endDayOfWeek = dayOfWeek;
        endTime      = time;
        endTimeMode  = mode;
        decodeEndRule();

        transitionRulesInitialized = false;
    }

    /**
     * Sets the amount of time in ms that the clock is advanced during DST.
     * @param millisSavedDuringDST the number of milliseconds the time is
     * advanced with respect to standard time when the daylight savings rules
     * are in effect. Typically one hour (+3600000). The amount could be negative,
     * but not 0.
     * @stable ICU 2.0
     */
    public void setDSTSavings(int millisSavedDuringDST) {
        if (isFrozen()) {
            throw new UnsupportedOperationException("Attempt to modify a frozen SimpleTimeZone instance.");
        }

        if (millisSavedDuringDST == 0) {
            throw new IllegalArgumentException();
        }
        dst = millisSavedDuringDST;

        transitionRulesInitialized = false;
    }

    /**
     * Returns the amount of time in ms that the clock is advanced during DST.
     * @return the number of milliseconds the time is
     * advanced with respect to standard time when the daylight savings rules
     * are in effect. Typically one hour (3600000). The amount could be negative,
     * but not 0.
     * @stable ICU 2.0
     */
    @Override
    public int getDSTSavings() {
        return dst;
    }

    /**
     * Returns the java.util.SimpleTimeZone that this class wraps.
     *
    java.util.SimpleTimeZone unwrapSTZ() {
        return (java.util.SimpleTimeZone) unwrap();
    }
    */

    // on JDK 1.4 and later, can't deserialize a SimpleTimeZone as a SimpleTimeZone...
    private void readObject(java.io.ObjectInputStream in) throws IOException,
        ClassNotFoundException {
        in.defaultReadObject();
        /*
        String id = getID();
        if (id!=null && !(zone instanceof java.util.SimpleTimeZone && zone.getID().equals(id))) {
            // System.out.println("*** readjust " + zone.getClass().getName() +
            // " " + zone.getID() + " ***");
            java.util.SimpleTimeZone stz =
                new java.util.SimpleTimeZone(raw, id);
            if (dst != 0) {
                stz.setDSTSavings(dst);
                // if it is 0, then there shouldn't be start/end rules and the default
                // behavior should be no dst
            }

            if (xinfo != null) {
                xinfo.applyTo(stz);
            }
            zoneJDK = stz;
        }
        */
        /* set all instance variables in this object
         * to the values in zone
         */
         if (xinfo != null) {
             xinfo.applyTo(this);
         }
    }

    /**
     * Returns a string representation of this object.
     * @return  a string representation of this object
     * @stable ICU 2.0
     */
    @Override
    public String toString() {
        return "SimpleTimeZone: " + getID();
    }

    private STZInfo getSTZInfo() {
        if (xinfo == null) {
            xinfo = new STZInfo();
        }
        return xinfo;
    }

    //  Use only for decodeStartRule() and decodeEndRule() where the year is not
    //  available. Set February to 29 days to accomodate rules with that date
    //  and day-of-week-on-or-before-that-date mode (DOW_LE_DOM_MODE).
    //  The compareToRule() method adjusts to February 28 in non-leap years.
    //
    //  For actual getOffset() calculations, use TimeZone::monthLength() and
    //  TimeZone::previousMonthLength() which take leap years into account.
    //  We handle leap years assuming always
    //  Gregorian, since we know they didn't have daylight time when
    //  Gregorian calendar started.
    private final static byte staticMonthLength[] = {31,29,31,30,31,30,31,31,30,31,30,31};

    /**
     * {@inheritDoc}
     * @stable ICU 2.0
     */
    @Override
    public int getOffset(int era, int year, int month, int day,
                         int dayOfWeek, int millis)
    {
        // Check the month before calling Grego.monthLength(). This
        // duplicates the test that occurs in the 7-argument getOffset(),
        // however, this is unavoidable. We don't mind because this method, in
        // fact, should not be called; internal code should always call the
        // 7-argument getOffset(), and outside code should use Calendar.get(int
        // field) with fields ZONE_OFFSET and DST_OFFSET. We can't get rid of
        // this method because it's public API. - liu 8/10/98
        if(month < Calendar.JANUARY || month > Calendar.DECEMBER) {
            throw new IllegalArgumentException();
        }

        return getOffset(era, year, month, day, dayOfWeek, millis, Grego.monthLength(year, month));
    }

    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public int getOffset(int era, int year, int month, int day,
                              int dayOfWeek, int millis,
                              int monthLength)  {
        // Check the month before calling Grego.monthLength(). This
        // duplicates a test that occurs in the 9-argument getOffset(),
        // however, this is unavoidable. We don't mind because this method, in
        // fact, should not be called; internal code should always call the
        // 9-argument getOffset(), and outside code should use Calendar.get(int
        // field) with fields ZONE_OFFSET and DST_OFFSET. We can't get rid of
        // this method because it's public API. - liu 8/10/98
        if(month < Calendar.JANUARY || month > Calendar.DECEMBER) {
            throw new IllegalArgumentException();
        }

        return getOffset(era, year, month, day, dayOfWeek, millis,
                         Grego.monthLength(year, month), Grego.previousMonthLength(year, month));
    }

    private int getOffset(int era, int year, int month, int day,
                  int dayOfWeek, int millis,
                  int monthLength, int prevMonthLength ){

        if (true) {
            /* Use this parameter checking code for normal operation.  Only one
             * of these two blocks should actually get compiled into the class
             * file.  */
            if ((era != GregorianCalendar.AD && era != GregorianCalendar.BC)
                || month < Calendar.JANUARY
                || month > Calendar.DECEMBER
                || day < 1
                || day > monthLength
                || dayOfWeek < Calendar.SUNDAY
                || dayOfWeek > Calendar.SATURDAY
                || millis < 0
                || millis >= Grego.MILLIS_PER_DAY
                || monthLength < 28
                || monthLength > 31
                || prevMonthLength < 28
                || prevMonthLength > 31) {
                throw new IllegalArgumentException();
            }
        }
        //Eclipse stated the following is "dead code"
        /*else {
            // This parameter checking code is better for debugging, but
            // overkill for normal operation.  Only one of these two blocks
            // should actually get compiled into the class file.
            if (era != GregorianCalendar.AD && era != GregorianCalendar.BC) {
                throw new IllegalArgumentException("Illegal era " + era);
            }
            if (month < Calendar.JANUARY
                || month > Calendar.DECEMBER) {
                throw new IllegalArgumentException("Illegal month " + month);
            }
            if (day < 1
                || day > monthLength) {
                throw new IllegalArgumentException("Illegal day " + day+" max month len: "+monthLength);
            }
            if (dayOfWeek < Calendar.SUNDAY
                || dayOfWeek > Calendar.SATURDAY) {
                throw new IllegalArgumentException("Illegal day of week " + dayOfWeek);
            }
            if (millis < 0
                || millis >= Grego.MILLIS_PER_DAY) {
                throw new IllegalArgumentException("Illegal millis " + millis);
            }
            if (monthLength < 28
                || monthLength > 31) {
                throw new IllegalArgumentException("Illegal month length " + monthLength);
            }
            if (prevMonthLength < 28
                || prevMonthLength > 31) {
                throw new IllegalArgumentException("Illegal previous month length " + prevMonthLength);
            }
        }*/

        int result = raw;

        // Bail out if we are before the onset of daylight savings time
        if (!useDaylight || year < startYear || era != GregorianCalendar.AD) return result;

        // Check for southern hemisphere.  We assume that the start and end
        // month are different.
        boolean southern = (startMonth > endMonth);

        // Compare the date to the starting and ending rules.+1 = date>rule, -1
        // = date<rule, 0 = date==rule.
        int startCompare = compareToRule(month, monthLength, prevMonthLength,
                                         day, dayOfWeek, millis,
                                         startTimeMode == UTC_TIME ? -raw : 0,
                                         startMode, startMonth, startDayOfWeek,
                                         startDay, startTime);
        int endCompare = 0;

        /* We don't always have to compute endCompare.  For many instances,
         * startCompare is enough to determine if we are in DST or not.  In the
         * northern hemisphere, if we are before the start rule, we can't have
         * DST.  In the southern hemisphere, if we are after the start rule, we
         * must have DST.  This is reflected in the way the next if statement
         * (not the one immediately following) short circuits. */
        if (southern != (startCompare >= 0)) {
            /* For the ending rule comparison, we add the dstSavings to the millis
             * passed in to convert them from standard to wall time.  We then must
             * normalize the millis to the range 0..millisPerDay-1. */
            endCompare = compareToRule(month, monthLength, prevMonthLength,
                                       day, dayOfWeek, millis,
                                       endTimeMode == WALL_TIME ? dst :
                                        (endTimeMode == UTC_TIME ? -raw : 0),
                                       endMode, endMonth, endDayOfWeek,
                                       endDay, endTime);
        }

        // Check for both the northern and southern hemisphere cases.  We
        // assume that in the northern hemisphere, the start rule is before the
        // end rule within the calendar year, and vice versa for the southern
        // hemisphere.
        if ((!southern && (startCompare >= 0 && endCompare < 0)) ||
            (southern && (startCompare >= 0 || endCompare < 0)))
            result += dst;

        return result;
    }

    /**
     * {@inheritDoc}
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Override
    @Deprecated
    public void getOffsetFromLocal(long date,
            int nonExistingTimeOpt, int duplicatedTimeOpt, int[] offsets) {
        offsets[0] = getRawOffset();
        int fields[] = new int[6];
        Grego.timeToFields(date, fields);
        offsets[1] = getOffset(GregorianCalendar.AD,
              fields[0], fields[1], fields[2],
              fields[3], fields[5]) - offsets[0];

        boolean recalc = false;

        // Now, we need some adjustment
        if (offsets[1] > 0) {
            if ((nonExistingTimeOpt & STD_DST_MASK) == LOCAL_STD
                || (nonExistingTimeOpt & STD_DST_MASK) != LOCAL_DST
                && (nonExistingTimeOpt & FORMER_LATTER_MASK) != LOCAL_LATTER) {
                date -= getDSTSavings();
                recalc = true;
            }
        } else {
            if ((duplicatedTimeOpt & STD_DST_MASK) == LOCAL_DST
                || (duplicatedTimeOpt & STD_DST_MASK) != LOCAL_STD
                && (duplicatedTimeOpt & FORMER_LATTER_MASK) == LOCAL_FORMER) {
                date -= getDSTSavings();
                recalc = true;
            }
        }

        if (recalc) {
            Grego.timeToFields(date, fields);
            offsets[1] = getOffset(GregorianCalendar.AD,
                    fields[0], fields[1], fields[2],
                    fields[3], fields[5]) - offsets[0];
        }
    }

    private static final int
        DOM_MODE = 1,
        DOW_IN_MONTH_MODE=2,
        DOW_GE_DOM_MODE=3,
        DOW_LE_DOM_MODE=4;

    /**
     * Compare a given date in the year to a rule. Return 1, 0, or -1, depending
     * on whether the date is after, equal to, or before the rule date. The
     * millis are compared directly against the ruleMillis, so any
     * standard-daylight adjustments must be handled by the caller.
     *
     * @return  1 if the date is after the rule date, -1 if the date is before
     *          the rule date, or 0 if the date is equal to the rule date.
     */
    private int compareToRule(int month, int monthLen, int prevMonthLen,
                                  int dayOfMonth,
                                  int dayOfWeek, int millis, int millisDelta,
                                  int ruleMode, int ruleMonth, int ruleDayOfWeek,
                                  int ruleDay, int ruleMillis)
    {
        // Make adjustments for startTimeMode and endTimeMode

        millis += millisDelta;

        while (millis >= Grego.MILLIS_PER_DAY) {
            millis -= Grego.MILLIS_PER_DAY;
            ++dayOfMonth;
            dayOfWeek = 1 + (dayOfWeek % 7); // dayOfWeek is one-based
            if (dayOfMonth > monthLen) {
                dayOfMonth = 1;
                /* When incrementing the month, it is desirable to overflow
                 * from DECEMBER to DECEMBER+1, since we use the result to
                 * compare against a real month. Wraparound of the value
                 * leads to bug 4173604. */
                ++month;
            }
        }
        /*
         * For some reasons, Sun Java 6 on Solaris/Linux has a problem with
         * the while loop below (at least Java 6 up to build 1.6.0_02-b08).
         * It looks the JRE messes up the variable 'millis' while executing
         * the code in the while block.  The problem is not reproduced with
         * JVM option -Xint, that is, it is likely a bug of the HotSpot
         * adaptive compiler.  Moving 'millis += Grego.MILLIS_PER_DAY'
         * to the end of this while block seems to resolve the problem.
         * See ticket#5887 about the problem in detail.
         */
        while (millis < 0) {
            //millis += Grego.MILLIS_PER_DAY;
            --dayOfMonth;
            dayOfWeek = 1 + ((dayOfWeek+5) % 7); // dayOfWeek is one-based
            if (dayOfMonth < 1) {
                dayOfMonth = prevMonthLen;
                --month;
            }
            millis += Grego.MILLIS_PER_DAY;
        }

        if (month < ruleMonth) return -1;
        else if (month > ruleMonth) return 1;

        int ruleDayOfMonth = 0;

        // Adjust the ruleDay to the monthLen, for non-leap year February 29 rule days.
        if (ruleDay > monthLen) {
            ruleDay = monthLen;
        }

        switch (ruleMode)
        {
        case DOM_MODE:
            ruleDayOfMonth = ruleDay;
            break;
        case DOW_IN_MONTH_MODE:
            // In this case ruleDay is the day-of-week-in-month
            if (ruleDay > 0)
                ruleDayOfMonth = 1 + (ruleDay - 1) * 7 +
                    (7 + ruleDayOfWeek - (dayOfWeek - dayOfMonth + 1)) % 7;
            else // Assume ruleDay < 0 here
            {
                ruleDayOfMonth = monthLen + (ruleDay + 1) * 7 -
                    (7 + (dayOfWeek + monthLen - dayOfMonth) - ruleDayOfWeek) % 7;
            }
            break;
        case DOW_GE_DOM_MODE:
            ruleDayOfMonth = ruleDay +
                (49 + ruleDayOfWeek - ruleDay - dayOfWeek + dayOfMonth) % 7;
            break;
        case DOW_LE_DOM_MODE:
            ruleDayOfMonth = ruleDay -
                (49 - ruleDayOfWeek + ruleDay + dayOfWeek - dayOfMonth) % 7;
            // Note at this point ruleDayOfMonth may be <1, although it will
            // be >=1 for well-formed rules.
            break;
        }

        if (dayOfMonth < ruleDayOfMonth) return -1;
        else if (dayOfMonth > ruleDayOfMonth) return 1;

        if (millis < ruleMillis){
                return -1;
        }else if (millis > ruleMillis){
                return 1;
        }else{
                return 0;
        }
    }

    // data needed for streaming mutated SimpleTimeZones in JDK14
    private int raw;// the TimeZone's raw GMT offset
    private int dst = 3600000;
    private STZInfo xinfo = null;
    private int startMonth, startDay, startDayOfWeek;   // the month, day, DOW, and time DST starts
    private int startTime;
    private int startTimeMode, endTimeMode; // Mode for startTime, endTime; see TimeMode
    private int endMonth, endDay, endDayOfWeek; // the month, day, DOW, and time DST ends
    private int endTime;
    private int startYear;  // the year these DST rules took effect
    private boolean useDaylight; // flag indicating whether this TimeZone uses DST
    private int startMode, endMode;   // flags indicating what kind of rules the DST rules are

    /**
     * Overrides TimeZone
     * Queries if this time zone uses Daylight Saving Time.
     * @stable ICU 2.0
     */
    @Override
    public boolean useDaylightTime(){
        return useDaylight;
    }

    /**
     * {@inheritDoc}
     * @stable ICU 49
     */
    @Override
    public boolean observesDaylightTime() {
        return useDaylight;
    }

    /**
     * Overrides TimeZone
     * Queries if the give date is in Daylight Saving Time.
     * @stable ICU 2.0
     */
    @Override
    public boolean inDaylightTime(Date date){
        GregorianCalendar gc = new GregorianCalendar(this);
        gc.setTime(date);
        return gc.inDaylightTime();
    }

    /**
     * Internal construction method.
     */
    private void construct(int _raw,
                           int _startMonth,
                           int _startDay,
                           int _startDayOfWeek,
                           int _startTime,
                           int _startTimeMode,
                           int _endMonth,
                           int _endDay,
                           int _endDayOfWeek,
                           int _endTime,
                           int _endTimeMode,
                           int _dst) {
        raw            = _raw;
        startMonth     = _startMonth;
        startDay       = _startDay;
        startDayOfWeek = _startDayOfWeek;
        startTime      = _startTime;
        startTimeMode  = _startTimeMode;
        endMonth       = _endMonth;
        endDay         = _endDay;
        endDayOfWeek   = _endDayOfWeek;
        endTime        = _endTime;
        endTimeMode    = _endTimeMode;
        dst            = _dst;
        startYear      = 0;
        startMode      = DOM_MODE;
        endMode        = DOM_MODE;

        decodeRules();

        if (_dst == 0) {
            throw new IllegalArgumentException();
        }
    }
    private void decodeRules(){
        decodeStartRule();
        decodeEndRule();
    }

    /**
     * Decode the start rule and validate the parameters.  The parameters are
     * expected to be in encoded form, which represents the various rule modes
     * by negating or zeroing certain values.  Representation formats are:
     * <p>
     * <pre>
     *            DOW_IN_MONTH  DOM    DOW>=DOM  DOW<=DOM  no DST
     *            ------------  -----  --------  --------  ----------
     * month       0..11        same    same      same     don't care
     * day        -5..5         1..31   1..31    -1..-31   0
     * dayOfWeek   1..7         0      -1..-7    -1..-7    don't care
     * time        0..ONEDAY    same    same      same     don't care
     * </pre>
     * The range for month does not include UNDECIMBER since this class is
     * really specific to GregorianCalendar, which does not use that month.
     * The range for time includes ONEDAY (vs. ending at ONEDAY-1) because the
     * end rule is an exclusive limit point.  That is, the range of times that
     * are in DST include those >= the start and < the end.  For this reason,
     * it should be possible to specify an end of ONEDAY in order to include the
     * entire day.  Although this is equivalent to time 0 of the following day,
     * it's not always possible to specify that, for example, on December 31.
     * While arguably the start range should still be 0..ONEDAY-1, we keep
     * the start and end ranges the same for consistency.
     */
    private void decodeStartRule() {
        useDaylight = (startDay != 0) && (endDay != 0);
        if (useDaylight && dst == 0) {
            dst = Grego.MILLIS_PER_DAY;
        }
        if (startDay != 0) {
            if (startMonth < Calendar.JANUARY || startMonth > Calendar.DECEMBER) {
                throw new IllegalArgumentException();
            }
            if (startTime < 0 || startTime > Grego.MILLIS_PER_DAY ||
                startTimeMode < WALL_TIME || startTimeMode > UTC_TIME) {
                throw new IllegalArgumentException();
            }
            if (startDayOfWeek == 0) {
                startMode = DOM_MODE;
            } else {
                if (startDayOfWeek > 0) {
                    startMode = DOW_IN_MONTH_MODE;
                } else {
                    startDayOfWeek = -startDayOfWeek;
                    if (startDay > 0) {
                        startMode = DOW_GE_DOM_MODE;
                    } else {
                        startDay = -startDay;
                        startMode = DOW_LE_DOM_MODE;
                    }
                }
                if (startDayOfWeek > Calendar.SATURDAY) {
                    throw new IllegalArgumentException();
                }
            }
            if (startMode == DOW_IN_MONTH_MODE) {
                if (startDay < -5 || startDay > 5) {
                    throw new IllegalArgumentException();
                }
            } else if (startDay < 1 || startDay > staticMonthLength[startMonth]) {
                throw new IllegalArgumentException();
            }
        }
    }

    /**
     * Decode the end rule and validate the parameters.  This method is exactly
     * analogous to decodeStartRule().
     * @see #decodeStartRule
     */
    private void decodeEndRule() {
        useDaylight = (startDay != 0) && (endDay != 0);
        if (useDaylight && dst == 0) {
            dst = Grego.MILLIS_PER_DAY;
        }
        if (endDay != 0) {
            if (endMonth < Calendar.JANUARY || endMonth > Calendar.DECEMBER) {
                throw new IllegalArgumentException();
            }
            if (endTime < 0 || endTime > Grego.MILLIS_PER_DAY ||
                endTimeMode < WALL_TIME || endTimeMode > UTC_TIME) {
                throw new IllegalArgumentException();
            }
            if (endDayOfWeek == 0) {
                endMode = DOM_MODE;
            } else {
                if (endDayOfWeek > 0) {
                    endMode = DOW_IN_MONTH_MODE;
                } else {
                    endDayOfWeek = -endDayOfWeek;
                    if (endDay > 0) {
                        endMode = DOW_GE_DOM_MODE;
                    } else {
                        endDay = -endDay;
                        endMode = DOW_LE_DOM_MODE;
                    }
                }
                if (endDayOfWeek > Calendar.SATURDAY) {
                    throw new IllegalArgumentException();
                }
            }
            if (endMode == DOW_IN_MONTH_MODE) {
                if (endDay < -5 || endDay > 5) {
                    throw new IllegalArgumentException();
                }
            } else if (endDay<1 || endDay > staticMonthLength[endMonth]) {
                throw new IllegalArgumentException();
            }
        }
    }

    /**
     * Overrides equals.
     * @return true if obj is a SimpleTimeZone equivalent to this
     * @stable ICU 2.0
     */
    @Override
    public boolean equals(Object obj){
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        SimpleTimeZone that = (SimpleTimeZone) obj;
        return raw     == that.raw &&
            useDaylight     == that.useDaylight &&
            idEquals(getID(),that.getID()) &&
            (!useDaylight
             // Only check rules if using DST
             || (dst            == that.dst &&
                 startMode      == that.startMode &&
                 startMonth     == that.startMonth &&
                 startDay       == that.startDay &&
                 startDayOfWeek == that.startDayOfWeek &&
                 startTime      == that.startTime &&
                 startTimeMode  == that.startTimeMode &&
                 endMode        == that.endMode &&
                 endMonth       == that.endMonth &&
                 endDay         == that.endDay &&
                 endDayOfWeek   == that.endDayOfWeek &&
                 endTime        == that.endTime &&
                 endTimeMode    == that.endTimeMode &&
                 startYear      == that.startYear ));

    }
    private boolean idEquals(String id1, String id2){
        if(id1==null && id2==null){
            return true;
        }
        if(id1!=null && id2!=null){
            return id1.equals(id2);
        }
        return false;
    }

    /**
     * Overrides hashCode.
     * @return a hash code value for this object.
     * @stable ICU 2.0
     */
    @Override
    public int hashCode(){
        int ret = super.hashCode()
                    + raw ^ (raw >>> 8)
                    + (useDaylight ? 0 : 1);
        if(!useDaylight){
                ret += dst ^ (dst >>> 10) +
                        startMode ^ (startMode>>>11) +
                        startMonth ^ (startMonth>>>12) +
                        startDay ^ (startDay>>>13) +
                        startDayOfWeek ^ (startDayOfWeek>>>14) +
                        startTime ^ (startTime>>>15) +
                        startTimeMode ^ (startTimeMode>>>16) +
                        endMode ^ (endMode>>>17) +
                        endMonth ^ (endMonth>>>18) +
                        endDay ^ (endDay>>>19) +
                        endDayOfWeek ^ (endDayOfWeek>>>20) +
                        endTime ^ (endTime>>>21) +
                        endTimeMode ^ (endTimeMode>>>22) +
                        startYear ^ (startYear>>>23);
        }
                return ret;
    }

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

    /**
     * Returns true if this zone has the same rules and offset as another zone.
     * @param othr the TimeZone object to be compared with
     * @return true if the given zone has the same rules and offset as this one
     * @stable ICU 2.0
     */
    @Override
    public boolean hasSameRules(TimeZone othr) {
        if (this == othr) {
            return true;
        }
        if(!(othr instanceof SimpleTimeZone)){
            return false;
        }
        SimpleTimeZone other = (SimpleTimeZone)othr;
        return other != null &&
        raw     == other.raw &&
        useDaylight     == other.useDaylight &&
        (!useDaylight
         // Only check rules if using DST
         || (dst     == other.dst &&
             startMode      == other.startMode &&
             startMonth     == other.startMonth &&
             startDay       == other.startDay &&
             startDayOfWeek == other.startDayOfWeek &&
             startTime      == other.startTime &&
             startTimeMode  == other.startTimeMode &&
             endMode        == other.endMode &&
             endMonth       == other.endMonth &&
             endDay         == other.endDay &&
             endDayOfWeek   == other.endDayOfWeek &&
             endTime        == other.endTime &&
             endTimeMode    == other.endTimeMode &&
             startYear      == other.startYear));
    }

    // BasicTimeZone methods

    /**
     * {@inheritDoc}
     * @stable ICU 3.8
     */
    @Override
    public TimeZoneTransition getNextTransition(long base, boolean inclusive) {
        if (!useDaylight) {
            return null;
        }

        initTransitionRules();
        long firstTransitionTime = firstTransition.getTime();
        if (base < firstTransitionTime || (inclusive && base == firstTransitionTime)) {
            return firstTransition;
        }
        Date stdDate = stdRule.getNextStart(base, dstRule.getRawOffset(), dstRule.getDSTSavings(),
                                            inclusive);
        Date dstDate = dstRule.getNextStart(base, stdRule.getRawOffset(), stdRule.getDSTSavings(),
                                            inclusive);
        if (stdDate != null && (dstDate == null || stdDate.before(dstDate))) {
            return new TimeZoneTransition(stdDate.getTime(), dstRule, stdRule);
        }
        if (dstDate != null && (stdDate == null || dstDate.before(stdDate))) {
            return new TimeZoneTransition(dstDate.getTime(), stdRule, dstRule);
        }
        return null;
    }

    /**
     * {@inheritDoc}
     * @stable ICU 3.8
     */
    @Override
    public TimeZoneTransition getPreviousTransition(long base, boolean inclusive) {
        if (!useDaylight) {
            return null;
        }

        initTransitionRules();
        long firstTransitionTime = firstTransition.getTime();
        if (base < firstTransitionTime || (!inclusive && base == firstTransitionTime)) {
            return null;
        }
        Date stdDate = stdRule.getPreviousStart(base, dstRule.getRawOffset(),
                                                dstRule.getDSTSavings(), inclusive);
        Date dstDate = dstRule.getPreviousStart(base, stdRule.getRawOffset(),
                                                stdRule.getDSTSavings(), inclusive);
        if (stdDate != null && (dstDate == null || stdDate.after(dstDate))) {
            return new TimeZoneTransition(stdDate.getTime(), dstRule, stdRule);
        }
        if (dstDate != null && (stdDate == null || dstDate.after(stdDate))) {
            return new TimeZoneTransition(dstDate.getTime(), stdRule, dstRule);
        }
        return null;
    }

    /**
     * {@inheritDoc}
     * @stable ICU 3.8
     */
    @Override
    public TimeZoneRule[] getTimeZoneRules() {
        initTransitionRules();

        int size = useDaylight ? 3 : 1;
        TimeZoneRule[] rules = new TimeZoneRule[size];
        rules[0] = initialRule;
        if (useDaylight) {
            rules[1] = stdRule;
            rules[2] = dstRule;
        }
        return rules;
    }

    private transient boolean transitionRulesInitialized;
    private transient InitialTimeZoneRule initialRule;
    private transient TimeZoneTransition firstTransition;
    private transient AnnualTimeZoneRule stdRule;
    private transient AnnualTimeZoneRule dstRule;

    private synchronized void initTransitionRules() {
        if (transitionRulesInitialized) {
            return;
        }
        if (useDaylight) {
            DateTimeRule dtRule = null;
            int timeRuleType;
            long firstStdStart, firstDstStart;

            // Create a TimeZoneRule for daylight saving time
            timeRuleType = (startTimeMode == STANDARD_TIME) ? DateTimeRule.STANDARD_TIME :
                ((startTimeMode == UTC_TIME) ? DateTimeRule.UTC_TIME : DateTimeRule.WALL_TIME);
            switch (startMode) {
            case DOM_MODE:
             dtRule = new DateTimeRule(startMonth, startDay, startTime, timeRuleType);
             break;
            case DOW_IN_MONTH_MODE:
             dtRule = new DateTimeRule(startMonth, startDay, startDayOfWeek, startTime,
                                       timeRuleType);
             break;
            case DOW_GE_DOM_MODE:
             dtRule = new DateTimeRule(startMonth, startDay, startDayOfWeek, true, startTime,
                                       timeRuleType);
             break;
            case DOW_LE_DOM_MODE:
             dtRule = new DateTimeRule(startMonth, startDay, startDayOfWeek, false, startTime,
                                       timeRuleType);
             break;
            }
            // For now, use ID + "(DST)" as the name
            dstRule = new AnnualTimeZoneRule(getID() + "(DST)", getRawOffset(), getDSTSavings(),
                 dtRule, startYear, AnnualTimeZoneRule.MAX_YEAR);

            // Calculate the first DST start time
            firstDstStart = dstRule.getFirstStart(getRawOffset(), 0).getTime();

            // Create a TimeZoneRule for standard time
            timeRuleType = (endTimeMode == STANDARD_TIME) ? DateTimeRule.STANDARD_TIME :
                ((endTimeMode == UTC_TIME) ? DateTimeRule.UTC_TIME : DateTimeRule.WALL_TIME);
            switch (endMode) {
            case DOM_MODE:
                dtRule = new DateTimeRule(endMonth, endDay, endTime, timeRuleType);
                break;
            case DOW_IN_MONTH_MODE:
                dtRule = new DateTimeRule(endMonth, endDay, endDayOfWeek, endTime, timeRuleType);
                break;
            case DOW_GE_DOM_MODE:
                dtRule = new DateTimeRule(endMonth, endDay, endDayOfWeek, true, endTime,
                                          timeRuleType);
                break;
            case DOW_LE_DOM_MODE:
                dtRule = new DateTimeRule(endMonth, endDay, endDayOfWeek, false, endTime,
                                          timeRuleType);
                break;
            }
            // For now, use ID + "(STD)" as the name
            stdRule = new AnnualTimeZoneRule(getID() + "(STD)", getRawOffset(), 0,
                    dtRule, startYear, AnnualTimeZoneRule.MAX_YEAR);

            // Calculate the first STD start time
            firstStdStart = stdRule.getFirstStart(getRawOffset(), dstRule.getDSTSavings()).getTime();

            // Create a TimeZoneRule for initial time
            if (firstStdStart < firstDstStart) {
                initialRule = new InitialTimeZoneRule(getID() + "(DST)", getRawOffset(),
                                                      dstRule.getDSTSavings());
                firstTransition = new TimeZoneTransition(firstStdStart, initialRule, stdRule);
            } else {
                initialRule = new InitialTimeZoneRule(getID() + "(STD)", getRawOffset(), 0);
                firstTransition = new TimeZoneTransition(firstDstStart, initialRule, dstRule);
            }

        } else {
            // Create a TimeZoneRule for initial time
            initialRule = new InitialTimeZoneRule(getID(), getRawOffset(), 0);
        }
        transitionRulesInitialized = true;
    }

    // Freezable stuffs
    private volatile transient boolean isFrozen = false;

    /**
     * {@inheritDoc}
     * @stable ICU 49
     */
    @Override
    public boolean isFrozen() {
        return isFrozen;
    }

    /**
     * {@inheritDoc}
     * @stable ICU 49
     */
    @Override
    public TimeZone freeze() {
        isFrozen = true;
        return this;
    }

    /**
     * {@inheritDoc}
     * @stable ICU 49
     */
    @Override
    public TimeZone cloneAsThawed() {
        SimpleTimeZone tz = (SimpleTimeZone)super.cloneAsThawed();
        tz.isFrozen = false;
        return tz;
    }
}
