 /*
*   Copyright (C) 1996-2009, 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;

/**
 * <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, Daylight Savings Time ends at the last
 * (dayOfWeekInMonth = -1) Sunday in October, at 2 AM in standard time.
 *
 * @see      Calendar
 * @see      GregorianCalendar
 * @see      TimeZone
 * @author   David 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) {
        construct(rawOffset, 0, 0, 0,
                0, WALL_TIME,
                0, 0, 0,
                0, WALL_TIME,
                Grego.MILLIS_PER_HOUR);
        super.setID(ID);
    }

    /**
     * Construct 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.
     * @exception 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) {
        construct(rawOffset,
                startMonth, startDay, startDayOfWeek,
                startTime, WALL_TIME,
                endMonth, endDay, endDayOfWeek,
                endTime, WALL_TIME,
                Grego.MILLIS_PER_HOUR);
        super.setID(ID);
    }

    /**
     * Construct 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.
     * @exception 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){
        construct(rawOffset,
                  startMonth, startDay, startDayOfWeek,
                  startTime, startTimeMode,
                  endMonth, endDay, endDayOfWeek,
                  endTime, endTimeMode,
                  dstSavings);
        super.setID(ID);
    }

    /**
     * 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.
     * @exception 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) {
        construct(rawOffset,
                startMonth, startDay, startDayOfWeek,
                startTime, WALL_TIME,
                endMonth, endDay, endDayOfWeek,
                endTime, WALL_TIME,
                dstSavings); 
        super.setID(ID);
    }
    

    /**
     * {@inheritDoc}
     * 
     * @stable ICU 3.8
     */
    public void setID(String ID) {
        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
     */
    public void setRawOffset(int offsetMillis) {
        raw = offsetMillis;

        transitionRulesInitialized = false;
    }
  
    /**
     * Overrides TimeZone
     * Gets the GMT offset for this time zone.
     * @return the raw offset
     * @stable ICU 2.0
     */
    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) {
        //unwrapSTZ().setStartYear(year);

        getSTZInfo().sy = year;
        this.startYear = year;

        transitionRulesInitialized = false;
    }

    /**
     * Sets the daylight savings starting rule. For example, Daylight Savings
     * Time starts at the first Sunday in April, at 2 AM in standard time.
     * Therefore, you can set the start rule by calling:
     * setStartRule(TimeFields.APRIL, 1, TimeFields.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.
     * @exception 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) {
        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 first Sunday in April, at 2 AM in standard time.
     * Therefore, you can set the start rule by calling:
     * setStartRule(TimeFields.APRIL, 1, TimeFields.SUNDAY, 2*60*60*1000);
     * 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)
    {
        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.
     * @exception IllegalArgumentException the month,
     * dayOfMonth, or time parameters are out of range
     * @stable ICU 2.0
     */
    public void setStartRule(int month, int dayOfMonth, int time) {
       // unwrapSTZ().setStartRule(month, dayOfMonth, time);

        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.
     * @exception 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) {
        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, Daylight Savings Time
     * ends at the last (-1) Sunday in October, at 2 AM in standard time.
     * Therefore, you can set the end rule by calling:
     * setEndRule(TimeFields.OCTOBER, -1, TimeFields.SUNDAY, 2*60*60*1000);
     *
     * @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.
     * @exception 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) {
        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.
     * @exception IllegalArgumentException the month,
     * dayOfMonth, or time parameters are out of range
     * @stable ICU 2.0
     */
    public void setEndRule(int month, int dayOfMonth, int time) {
        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.
     * @exception 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) {
        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){
        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 last (-1) Sunday in October, at 2 AM in standard time.
     * Therefore, you can set the end rule by calling:
     * setEndRule(TimeFields.OCTOBER, -1, TimeFields.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){
        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. A positive number, typically one hour (3600000).
     * @stable ICU 2.0
     */
    public void setDSTSavings(int millisSavedDuringDST) {
        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. A positive number, typically one hour (3600000).
     * @stable ICU 2.0
     */
    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 3.6
     */
    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
     */
    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.
     */
    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));
    }

    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();
            }
        } 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.
     */
    public void getOffsetFromLocal(long date,
            int nonExistingTimeOpt, int duplicatedTimeOpt, int[] offsets) {
        offsets[0] = getRawOffset();
        int fields[] = new int[4];
        long day = floorDivide(date, Grego.MILLIS_PER_DAY, fields);
        int millis = fields[0];

        computeGregorianFields(day, fields);
        offsets[1] = getOffset(GregorianCalendar.AD,
              fields[0], fields[1], fields[2],
              fields[3], millis) - 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) {
            day = floorDivide(date, Grego.MILLIS_PER_DAY, fields);
            millis = fields[0];
            computeGregorianFields(day, fields);
            offsets[1] = getOffset(GregorianCalendar.AD,
                    fields[0], fields[1], fields[2],
                    fields[3], millis) - 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
     */
    public boolean useDaylightTime(){
        return useDaylight;
    }

    /**
     * Overrides TimeZone
     * Queries if the give date is in Daylight Saving Time.
     * @stable ICU 2.0
     */
    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 = (boolean)((startDay != 0) && (endDay != 0) ? true : false  );
        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 = (int)-startDayOfWeek;
                    if (startDay > 0) {
                        startMode = DOW_GE_DOM_MODE;
                    } else {
                        startDay = (int)-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 = (boolean)((startDay != 0) && (endDay != 0) ? true : false);
        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 = (int)-endDayOfWeek;
                    if (endDay > 0) {
                        endMode = DOW_GE_DOM_MODE;
                    } else {
                        endDay = (int)-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();
            }
        }
    }

    /**
     * Return true if obj is a SimpleTimeZone equivalent to this.
     * @return true if obj is a SimpleTimeZone equivalent to this
     * @stable ICU 3.6
     */
    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;
    }

    /**
     * Return the hash code.
     * @return the hash code
     * @stable ICU 3.6
     */
    public int hashCode(){
        int ret = (int)( super.hashCode() +
                                         raw ^ (raw>>>8) +
                                         (useDaylight?0:1));
        if(!useDaylight){
                ret += (int)(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;
    }

    /**
     * Return a clone of this time zone.
     * @return a clone of this time zone
     * @stable ICU 3.6
     */
    public Object clone() {
        return super.clone();
    }

    /**
     * Return 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
     */
    public boolean hasSameRules(TimeZone othr) {
        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
     */
    public TimeZoneTransition getNextTransition(long base, boolean inclusive) {
        if (startMonth == 0) {
            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
     */
    public TimeZoneTransition getPreviousTransition(long base, boolean inclusive) {
        if (startMonth == 0) {
            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
     */
    public TimeZoneRule[] getTimeZoneRules() {
        initTransitionRules();

        int size = (startMonth == 0) ? 1 : 3;
        TimeZoneRule[] rules = new TimeZoneRule[size];
        rules[0] = initialRule;
        if (startMonth != 0) {
            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 (startMonth != 0) {
            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;
    }
}

