/* java.util.SimpleTimeZone
   Copyright (C) 1998, 1999, 2000, 2003, 2004, 2005  Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package java.util;


/**
 * This class represents a simple time zone offset and handles
 * daylight savings.  It can only handle one daylight savings rule, so
 * it can't represent historical changes.
 *
 * This object is tightly bound to the Gregorian calendar.  It assumes
 * a regular seven days week, and the month lengths are that of the
 * Gregorian Calendar.  It can only handle daylight savings for years
 * lying in the AD era.
 *
 * @see Calendar
 * @see GregorianCalendar
 * @author Jochen Hoenicke
 */
public class SimpleTimeZone extends TimeZone
{
  /**
   * The raw time zone offset in milliseconds to GMT, ignoring
   * daylight savings.
   * @serial
   */
  private int rawOffset;

  /**
   * True, if this timezone uses daylight savings, false otherwise.
   * @serial
   */
  private boolean useDaylight;

  /**
   * The daylight savings offset.  This is a positive offset in
   * milliseconds with respect to standard time.  Typically this
   * is one hour, but for some time zones this may be half an hour.
   * @serial
   * @since JDK1.1.4
   */
  private int dstSavings = 60 * 60 * 1000;

  /**
   * The first year, in which daylight savings rules applies.
   * @serial
   */
  private int startYear;
  private static final int DOM_MODE = 1;
  private static final int DOW_IN_MONTH_MODE = 2;
  private static final int DOW_GE_DOM_MODE = 3;
  private static final int DOW_LE_DOM_MODE = 4;

  /**
   * The mode of the start rule. This takes one of the following values:
   * <dl>
   * <dt>DOM_MODE (1)</dt>
   * <dd> startDay contains the day in month of the start date,
   * startDayOfWeek is unused. </dd>
   * <dt>DOW_IN_MONTH_MODE (2)</dt>
   * <dd> The startDay gives the day of week in month, and
   * startDayOfWeek the day of week.  For example startDay=2 and
   * startDayOfWeek=Calender.SUNDAY specifies that the change is on
   * the second sunday in that month.  You must make sure, that this
   * day always exists (ie. don't specify the 5th sunday).
   * </dd>
   * <dt>DOW_GE_DOM_MODE (3)</dt>
   * <dd> The start is on the first startDayOfWeek on or after
   * startDay.  For example startDay=13 and
   * startDayOfWeek=Calendar.FRIDAY specifies that the daylight
   * savings start on the first FRIDAY on or after the 13th of that
   * Month. Make sure that the change is always in the given month, or
   * the result is undefined.
   * </dd>
   * <dt>DOW_LE_DOM_MONTH (4)</dt>
   * <dd> The start is on the first startDayOfWeek on or before the
   * startDay.  Make sure that the change is always in the given
   * month, or the result is undefined.
   </dd>
   * </dl>
   * @serial */
  private int startMode;

  /**
   * The month in which daylight savings start.  This is one of the
   * constants Calendar.JANUARY, ..., Calendar.DECEMBER.
   * @serial
   */
  private int startMonth;

  /**
   * This variable can have different meanings.  See startMode for details
   * @see #startMode
   * @serial
   */
  private int startDay;

  /**
   * This variable specifies the day of week the change takes place.  If
   * startMode == DOM_MODE, this is undefined.
   * @serial
   * @see #startMode
   */
  private int startDayOfWeek;

  /**
   * This variable specifies the time of change to daylight savings.
   * This time is given in milliseconds after midnight local
   * standard time.
   * @serial
   */
  private int startTime;

  /**
   * This variable specifies the mode that startTime is specified in.  By
   * default it is WALL_TIME, but can also be STANDARD_TIME or UTC_TIME.  For
   * startTime, STANDARD_TIME and WALL_TIME are equivalent.
   * @serial
   */
  private int startTimeMode = WALL_TIME;

  /**
   * The month in which daylight savings ends.  This is one of the
   * constants Calendar.JANUARY, ..., Calendar.DECEMBER.
   * @serial
   */
  private int endMonth;

  /**
   * This variable gives the mode for the end of daylight savings rule.
   * It can take the same values as startMode.
   * @serial
   * @see #startMode
   */
  private int endMode;

  /**
   * This variable can have different meanings.  See startMode for details
   * @serial
   * @see #startMode
   */
  private int endDay;

  /**
   * This variable specifies the day of week the change takes place.  If
   * endMode == DOM_MODE, this is undefined.
   * @serial
   * @see #startMode
   */
  private int endDayOfWeek;

  /**
   * This variable specifies the time of change back to standard time.
   * This time is given in milliseconds after midnight local
   * standard time.
   * @serial
   */
  private int endTime;

  /**
   * This variable specifies the mode that endTime is specified in.  By
   * default it is WALL_TIME, but can also be STANDARD_TIME or UTC_TIME.
   * @serial
   */
  private int endTimeMode = WALL_TIME;

  /**
   * This variable points to a deprecated array from JDK 1.1.  It is
   * ignored in JDK 1.2 but streamed out for compatibility with JDK 1.1.
   * The array contains the lengths of the months in the year and is
   * assigned from a private static final field to avoid allocating
   * the array for every instance of the object.
   * Note that static final fields are not serialized.
   * @serial
   */
  private byte[] monthLength = monthArr;
  private static final byte[] monthArr = 
                                         {
                                           31, 28, 31, 30, 31, 30, 31, 31, 30,
                                           31, 30, 31
                                         };

  /**
   * The version of the serialized data on the stream.
   * <dl>
   * <dt>0 or not present on stream</dt>
   * <dd> JDK 1.1.3 or earlier, only provides this fields:
   * rawOffset, startDay, startDayOfWeek, startMonth, startTime,
   * startYear, endDay, endDayOfWeek, endMonth, endTime
   * </dd>
   * <dd> JDK 1.1.4 or later. This includes three new fields, namely
   * startMode, endMode and dstSavings.  And there is a optional section
   * as described in writeObject.
   * </dd>
   * </dl>
   *
   * XXX - JDK 1.2 Beta 4 docu states 1.1.4, but my 1.1.5 has the old
   * version.
   *
   * When streaming out this class it is always written in the latest
   * version.
   * @serial
   * @since JDK1.1.4
   */
  private int serialVersionOnStream = 2;
  private static final long serialVersionUID = -403250971215465050L;

  /**
   * Constant to indicate that start and end times are specified in standard
   * time, without adjusting for daylight savings.
   */
  public static final int STANDARD_TIME = 1;

  /**
   * Constant to indicate that start and end times are specified in wall
   * time, adjusting for daylight savings.  This is the default.
   */
  public static final int WALL_TIME = 0;

  /**
   * Constant to indicate that start and end times are specified in UTC.
   */
  public static final int UTC_TIME = 2;

  /**
   * Create a <code>SimpleTimeZone</code> with the given time offset
   * from GMT and without daylight savings.
   * @param rawOffset the time offset from GMT in milliseconds.
   * @param id The identifier of this time zone.
   */
  public SimpleTimeZone(int rawOffset, String id)
  {
    this.rawOffset = rawOffset;
    setID(id);
    useDaylight = false;
    startYear = 0;
  }

  /**
   * Create a <code>SimpleTimeZone</code> with the given time offset
   * from GMT and with daylight savings.  The start/end parameters
   * can have different meaning (replace WEEKDAY with a real day of
   * week). Only the first two meanings were supported by earlier
   * versions of jdk.
   *
   * <dl>
   * <dt><code>day &gt; 0, dayOfWeek = Calendar.WEEKDAY</code></dt>
   * <dd>The start/end of daylight savings is on the <code>day</code>-th
   * <code>WEEKDAY</code> in the given month. </dd>
   * <dt><code>day &lt; 0, dayOfWeek = Calendar.WEEKDAY</code></dt>
   * <dd>The start/end of daylight savings is on the <code>-day</code>-th
   * <code>WEEKDAY</code> counted from the <i>end</i> of the month. </dd>
   * <dt><code>day &gt; 0, dayOfWeek = 0</code></dt>
   * <dd>The start/end of daylight is on the <code>day</code>-th day of
   * the month. </dd>
   * <dt><code>day &gt; 0, dayOfWeek = -Calendar.WEEKDAY</code></dt>
   * <dd>The start/end of daylight is on the first WEEKDAY on or after
   * the <code>day</code>-th day of the month.  You must make sure that
   * this day lies in the same month. </dd>
   * <dt><code>day &lt; 0, dayOfWeek = -Calendar.WEEKDAY</code></dt>
   * <dd>The start/end of daylight is on the first WEEKDAY on or
   * <i>before</i> the <code>-day</code>-th day of the month.  You
   * must make sure that this day lies in the same month. </dd>
   * </dl>
   *
   * If you give a non existing month, a day that is zero, or too big,
   * or a dayOfWeek that is too big,  the result is undefined.
   *
   * The start rule must have a different month than the end rule.
   * This restriction shouldn't hurt for all possible time zones.
   *
   * @param rawOffset The time offset from GMT in milliseconds.
   * @param id  The identifier of this time zone.
   * @param startMonth The start month of daylight savings; use the
   * constants in Calendar.
   * @param startDayOfWeekInMonth A day in month or a day of week number, as
   * described above.
   * @param startDayOfWeek The start rule day of week; see above.
   * @param startTime A time in millis in standard time.
   * @param endMonth The end month of daylight savings; use the
   * constants in Calendar.
   * @param endDayOfWeekInMonth A day in month or a day of week number, as
   * described above.
   * @param endDayOfWeek The end rule day of week; see above.
   * @param endTime A time in millis in standard time.
   * @throws IllegalArgumentException if parameters are invalid or out of
   * range.
   */
  public SimpleTimeZone(int rawOffset, String id, int startMonth,
                        int startDayOfWeekInMonth, int startDayOfWeek,
                        int startTime, int endMonth, int endDayOfWeekInMonth,
                        int endDayOfWeek, int endTime)
  {
    this.rawOffset = rawOffset;
    setID(id);
    useDaylight = true;

    setStartRule(startMonth, startDayOfWeekInMonth, startDayOfWeek, startTime);
    setEndRule(endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime);
    if (startMonth == endMonth)
      throw new IllegalArgumentException("startMonth and endMonth must be different");
    this.startYear = 0;
  }

  /**
   * This constructs a new SimpleTimeZone that supports a daylight savings
   * rule.  The parameter are the same as for the constructor above, except
   * there is the additional dstSavaings parameter.
   *
   * @param dstSavings the amount of savings for daylight savings
   * time in milliseconds.  This must be positive.
   * @since 1.2
   */
  public SimpleTimeZone(int rawOffset, String id, int startMonth,
                        int startDayOfWeekInMonth, int startDayOfWeek,
                        int startTime, int endMonth, int endDayOfWeekInMonth,
                        int endDayOfWeek, int endTime, int dstSavings)
  {
    this(rawOffset, id, startMonth, startDayOfWeekInMonth, startDayOfWeek,
         startTime, endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime);

    this.dstSavings = dstSavings;
  }

  /**
   * This constructs a new SimpleTimeZone that supports a daylight savings
   * rule.  The parameter are the same as for the constructor above, except
   * there are the additional startTimeMode, endTimeMode, and dstSavings
   * parameters.
   *
   * @param startTimeMode the mode that start times are specified in.  One of
   * WALL_TIME, STANDARD_TIME, or UTC_TIME.
   * @param endTimeMode the mode that end times are specified in.  One of
   * WALL_TIME, STANDARD_TIME, or UTC_TIME.
   * @param dstSavings the amount of savings for daylight savings
   * time in milliseconds.  This must be positive.
   * @throws IllegalArgumentException if parameters are invalid or out of
   * range.
   * @since 1.4
   */
  public SimpleTimeZone(int rawOffset, String id, int startMonth,
                        int startDayOfWeekInMonth, int startDayOfWeek,
                        int startTime, int startTimeMode, int endMonth,
                        int endDayOfWeekInMonth, int endDayOfWeek,
                        int endTime, int endTimeMode, int dstSavings)
  {
    this.rawOffset = rawOffset;
    setID(id);
    useDaylight = true;

    if (startTimeMode < WALL_TIME || startTimeMode > UTC_TIME)
      throw new IllegalArgumentException("startTimeMode must be one of WALL_TIME, STANDARD_TIME, or UTC_TIME");
    if (endTimeMode < WALL_TIME || endTimeMode > UTC_TIME)
      throw new IllegalArgumentException("endTimeMode must be one of WALL_TIME, STANDARD_TIME, or UTC_TIME");
    this.startTimeMode = startTimeMode;
    this.endTimeMode = endTimeMode;

    setStartRule(startMonth, startDayOfWeekInMonth, startDayOfWeek, startTime);
    setEndRule(endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime);
    if (startMonth == endMonth)
      throw new IllegalArgumentException("startMonth and endMonth must be different");
    this.startYear = 0;

    this.dstSavings = dstSavings;
  }

  /**
   * Sets the first year, where daylight savings applies.  The daylight
   * savings rule never apply for years in the BC era.  Note that this
   * is gregorian calendar specific.
   * @param year the start year.
   */
  public void setStartYear(int year)
  {
    startYear = year;
    useDaylight = true;
  }

  /**
   * Checks if the month, day, dayOfWeek arguments are in range and
   * returns the mode of the rule.
   * @param month the month parameter as in the constructor
   * @param day the day parameter as in the constructor
   * @param dayOfWeek the day of week parameter as in the constructor
   * @return the mode of this rule see startMode.
   * @exception IllegalArgumentException if parameters are out of range.
   * @see #SimpleTimeZone(int, String, int, int, int, int, int, int, int, int)
   * @see #startMode
   */
  private int checkRule(int month, int day, int dayOfWeek)
  {
    if (month < 0 || month > 11)
      throw new IllegalArgumentException("month out of range");

    int daysInMonth = getDaysInMonth(month, 1);
    if (dayOfWeek == 0)
      {
	if (day <= 0 || day > daysInMonth)
	  throw new IllegalArgumentException("day out of range");
	return DOM_MODE;
      }
    else if (dayOfWeek > 0)
      {
	if (Math.abs(day) > (daysInMonth + 6) / 7)
	  throw new IllegalArgumentException("dayOfWeekInMonth out of range");
	if (dayOfWeek > Calendar.SATURDAY)
	  throw new IllegalArgumentException("dayOfWeek out of range");
	return DOW_IN_MONTH_MODE;
      }
    else
      {
	if (day == 0 || Math.abs(day) > daysInMonth)
	  throw new IllegalArgumentException("day out of range");
	if (dayOfWeek < -Calendar.SATURDAY)
	  throw new IllegalArgumentException("dayOfWeek out of range");
	if (day < 0)
	  return DOW_LE_DOM_MODE;
	else
	  return DOW_GE_DOM_MODE;
      }
  }

  /**
   * Sets the daylight savings start rule.  You must also set the
   * end rule with <code>setEndRule</code> or the result of
   * getOffset is undefined.  For the parameters see the ten-argument
   * constructor above.
   *
   * @param month The month where daylight savings start, zero
   * based.  You should use the constants in Calendar.
   * @param day A day of month or day of week in month.
   * @param dayOfWeek The day of week where daylight savings start.
   * @param time The time in milliseconds standard time where daylight
   * savings start.
   * @exception IllegalArgumentException if parameters are out of range.
   * @see SimpleTimeZone
   */
  public void setStartRule(int month, int day, int dayOfWeek, int time)
  {
    this.startMode = checkRule(month, day, dayOfWeek);
    this.startMonth = month;
    this.startDay = day;
    this.startDayOfWeek = Math.abs(dayOfWeek);
    if (this.startTimeMode == WALL_TIME || this.startTimeMode == STANDARD_TIME)
      this.startTime = time;
    else
      // Convert from UTC to STANDARD
      this.startTime = time + this.rawOffset;
    useDaylight = true;
  }

  /**
   * Sets the daylight savings start rule.  You must also set the
   * end rule with <code>setEndRule</code> or the result of
   * getOffset is undefined.  For the parameters see the ten-argument
   * constructor above.
   *
   * Note that this API isn't incredibly well specified.  It appears that the
   * after flag must override the parameters, since normally, the day and
   * dayofweek can select this.  I.e., if day < 0 and dayOfWeek < 0, on or
   * before mode is chosen.  But if after == true, this implementation
   * overrides the signs of the other arguments.  And if dayOfWeek == 0, it
   * falls back to the behavior in the other APIs.  I guess this should be
   * checked against Sun's implementation.
   *
   * @param month The month where daylight savings start, zero
   * based.  You should use the constants in Calendar.
   * @param day A day of month or day of week in month.
   * @param dayOfWeek The day of week where daylight savings start.
   * @param time The time in milliseconds standard time where daylight
   * savings start.
   * @param after If true, day and dayOfWeek specify first day of week on or
   * after day, else first day of week on or before.
   * @since 1.2
   * @see SimpleTimeZone
   */
  public void setStartRule(int month, int day, int dayOfWeek, int time,
                           boolean after)
  {
    // FIXME: XXX: Validate that checkRule and offset processing work with on
    // or before mode.
    this.startDay = after ? Math.abs(day) : -Math.abs(day);
    this.startDayOfWeek = after ? Math.abs(dayOfWeek) : -Math.abs(dayOfWeek);
    this.startMode = (dayOfWeek != 0)
                     ? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE)
                     : checkRule(month, day, dayOfWeek);
    this.startDay = Math.abs(this.startDay);
    this.startDayOfWeek = Math.abs(this.startDayOfWeek);

    this.startMonth = month;

    if (this.startTimeMode == WALL_TIME || this.startTimeMode == STANDARD_TIME)
      this.startTime = time;
    else
      // Convert from UTC to STANDARD
      this.startTime = time + this.rawOffset;
    useDaylight = true;
  }

  /**
   * Sets the daylight savings start rule.  You must also set the
   * end rule with <code>setEndRule</code> or the result of
   * getOffset is undefined.  For the parameters see the ten-argument
   * constructor above.
   *
   * @param month The month where daylight savings start, zero
   * based.  You should use the constants in Calendar.
   * @param day A day of month or day of week in month.
   * @param time The time in milliseconds standard time where daylight
   * savings start.
   * @see SimpleTimeZone
   * @since 1.2
   */
  public void setStartRule(int month, int day, int time)
  {
    setStartRule(month, day, 0, time);
  }

  /**
   * Sets the daylight savings end rule.  You must also set the
   * start rule with <code>setStartRule</code> or the result of
   * getOffset is undefined. For the parameters see the ten-argument
   * constructor above.
   *
   * @param month The end month of daylight savings.
   * @param day A day in month, or a day of week in month.
   * @param dayOfWeek A day of week, when daylight savings ends.
   * @param time A time in millis in standard time.
   * @see #setStartRule(int, int, int, int)
   */
  public void setEndRule(int month, int day, int dayOfWeek, int time)
  {
    this.endMode = checkRule(month, day, dayOfWeek);
    this.endMonth = month;
    this.endDay = day;
    this.endDayOfWeek = Math.abs(dayOfWeek);
    if (this.endTimeMode == WALL_TIME)
      this.endTime = time;
    else if (this.endTimeMode == STANDARD_TIME)
      // Convert from STANDARD to DST
      this.endTime = time + this.dstSavings;
    else
      // Convert from UTC to DST
      this.endTime = time + this.rawOffset + this.dstSavings;
    useDaylight = true;
  }

  /**
   * Sets the daylight savings end rule.  You must also set the
   * start rule with <code>setStartRule</code> or the result of
   * getOffset is undefined. For the parameters see the ten-argument
   * constructor above.
   *
   * Note that this API isn't incredibly well specified.  It appears that the
   * after flag must override the parameters, since normally, the day and
   * dayofweek can select this.  I.e., if day < 0 and dayOfWeek < 0, on or
   * before mode is chosen.  But if after == true, this implementation
   * overrides the signs of the other arguments.  And if dayOfWeek == 0, it
   * falls back to the behavior in the other APIs.  I guess this should be
   * checked against Sun's implementation.
   *
   * @param month The end month of daylight savings.
   * @param day A day in month, or a day of week in month.
   * @param dayOfWeek A day of week, when daylight savings ends.
   * @param time A time in millis in standard time.
   * @param after If true, day and dayOfWeek specify first day of week on or
   * after day, else first day of week on or before.
   * @since 1.2
   * @see #setStartRule(int, int, int, int, boolean)
   */
  public void setEndRule(int month, int day, int dayOfWeek, int time,
                         boolean after)
  {
    // FIXME: XXX: Validate that checkRule and offset processing work with on
    // or before mode.
    this.endDay = after ? Math.abs(day) : -Math.abs(day);
    this.endDayOfWeek = after ? Math.abs(dayOfWeek) : -Math.abs(dayOfWeek);
    this.endMode = (dayOfWeek != 0)
                   ? (after ? DOW_GE_DOM_MODE : DOW_LE_DOM_MODE)
                   : checkRule(month, day, dayOfWeek);
    this.endDay = Math.abs(this.endDay);
    this.endDayOfWeek = Math.abs(endDayOfWeek);

    this.endMonth = month;

    if (this.endTimeMode == WALL_TIME)
      this.endTime = time;
    else if (this.endTimeMode == STANDARD_TIME)
      // Convert from STANDARD to DST
      this.endTime = time + this.dstSavings;
    else
      // Convert from UTC to DST
      this.endTime = time + this.rawOffset + this.dstSavings;
    useDaylight = true;
  }

  /**
   * Sets the daylight savings end rule.  You must also set the
   * start rule with <code>setStartRule</code> or the result of
   * getOffset is undefined. For the parameters see the ten-argument
   * constructor above.
   *
   * @param month The end month of daylight savings.
   * @param day A day in month, or a day of week in month.
   * @param time A time in millis in standard time.
   * @see #setStartRule(int, int, int)
   */
  public void setEndRule(int month, int day, int time)
  {
    setEndRule(month, day, 0, time);
  }

  /**
   * Gets the time zone offset, for current date, modified in case of
   * daylight savings.  This is the offset to add to UTC to get the local
   * time.
   *
   * In the standard JDK the results given by this method may result in
   * inaccurate results at the end of February or the beginning of March.
   * To avoid this, you should use Calendar instead:
   * <code>offset = cal.get(Calendar.ZONE_OFFSET)
   * + cal.get(Calendar.DST_OFFSET);</code>
   *
   * This version doesn't suffer this inaccuracy.
   *
   * The arguments don't follow the approach for setting start and end rules.
   * The day must be a positive number and dayOfWeek must be a positive value
   * from Calendar.  dayOfWeek is redundant, but must match the other values
   * or an inaccurate result may be returned.
   *
   * @param era the era of the given date
   * @param year the year of the given date
   * @param month the month of the given date, 0 for January.
   * @param day the day of month
   * @param dayOfWeek the day of week; this must match the other fields.
   * @param millis the millis in the day (in local standard time)
   * @return the time zone offset in milliseconds.
   * @throws IllegalArgumentException if arguments are incorrect.
   */
  public int getOffset(int era, int year, int month, int day, int dayOfWeek,
                       int millis)
  {
    int daysInMonth = getDaysInMonth(month, year);
    if (day < 1 || day > daysInMonth)
      throw new IllegalArgumentException("day out of range");
    if (dayOfWeek < Calendar.SUNDAY || dayOfWeek > Calendar.SATURDAY)
      throw new IllegalArgumentException("dayOfWeek out of range");
    if (month < Calendar.JANUARY || month > Calendar.DECEMBER)
      throw new IllegalArgumentException("month out of range:" + month);

    // This method is called by Calendar, so we mustn't use that class.
    int daylightSavings = 0;
    if (useDaylight && era == GregorianCalendar.AD && year >= startYear)
      {
	// This does only work for Gregorian calendars :-(
	// This is mainly because setStartYear doesn't take an era.
	boolean afterStart = ! isBefore(year, month, day, dayOfWeek, millis,
	                                startMode, startMonth, startDay,
	                                startDayOfWeek, startTime);
	boolean beforeEnd = isBefore(year, month, day, dayOfWeek,
				     millis + dstSavings,
	                             endMode, endMonth, endDay, endDayOfWeek,
	                             endTime);

	if (startMonth < endMonth)
	  // use daylight savings, if the date is after the start of
	  // savings, and before the end of savings.
	  daylightSavings = afterStart && beforeEnd ? dstSavings : 0;
	else
	  // use daylight savings, if the date is before the end of
	  // savings, or after the start of savings.
	  daylightSavings = beforeEnd || afterStart ? dstSavings : 0;
      }
    return rawOffset + daylightSavings;
  }

  /**
   * Returns the time zone offset to GMT in milliseconds, ignoring
   * day light savings.
   * @return the time zone offset.
   */
  public int getRawOffset()
  {
    return rawOffset;
  }

  /**
   * Sets the standard time zone offset to GMT.
   * @param rawOffset The time offset from GMT in milliseconds.
   */
  public void setRawOffset(int rawOffset)
  {
    this.rawOffset = rawOffset;
  }

  /**
   * Gets the daylight savings offset.  This is a positive offset in
   * milliseconds with respect to standard time.  Typically this
   * is one hour, but for some time zones this may be half an our.
   * @return the daylight savings offset in milliseconds.
   *
   * @since 1.2
   */
  public int getDSTSavings()
  {
    return dstSavings;
  }

  /**
   * Sets the daylight savings offset.  This is a positive offset in
   * milliseconds with respect to standard time.
   *
   * @param dstSavings the daylight savings offset in milliseconds.
   *
   * @since 1.2
   */
  public void setDSTSavings(int dstSavings)
  {
    if (dstSavings <= 0)
      throw new IllegalArgumentException("illegal value for dstSavings");

    this.dstSavings = dstSavings;
  }

  /**
   * Returns if this time zone uses daylight savings time.
   * @return true, if we use daylight savings time, false otherwise.
   */
  public boolean useDaylightTime()
  {
    return useDaylight;
  }

  /**
   * Returns the number of days in the given month.
   * Uses gregorian rules prior to 1582 (The default and earliest cutover)
   * @param month The month, zero based; use one of the Calendar constants.
   * @param year  The year.
   */
  private int getDaysInMonth(int month, int year)
  {    
    if (month == Calendar.FEBRUARY)
      {
	if ((year & 3) != 0)
	  return 28;

	// Assume default Gregorian cutover, 
	// all years prior to this must be Julian
	if (year < 1582)
	  return 29;

	// Gregorian rules 
	return ((year % 100) != 0 || (year % 400) == 0) ? 29 : 28;
      }
    else
      return monthArr[month];
  }

  /**
   * Checks if the date given in calXXXX, is before the change between
   * dst and standard time.
   * @param calYear the year of the date to check (for leap day checking).
   * @param calMonth the month of the date to check.
   * @param calDayOfMonth the day of month of the date to check.
   * @param calDayOfWeek the day of week of the date to check.
   * @param calMillis the millis of day of the date to check (standard time).
   * @param mode  the change mode; same semantic as startMode.
   * @param month the change month; same semantic as startMonth.
   * @param day   the change day; same semantic as startDay.
   * @param dayOfWeek the change day of week;
   * @param millis the change time in millis since midnight standard time.
   * same semantic as startDayOfWeek.
   * @return true, if cal is before the change, false if cal is on
   * or after the change.
   */
  private boolean isBefore(int calYear, int calMonth, int calDayOfMonth,
                           int calDayOfWeek, int calMillis, int mode,
                           int month, int day, int dayOfWeek, int millis)
  {
    // This method is called by Calendar, so we mustn't use that class.
    // We have to do all calculations by hand.
    // check the months:
    // XXX - this is not correct:
    // for the DOW_GE_DOM and DOW_LE_DOM modes the change date may
    // be in a different month.
    if (calMonth != month)
      return calMonth < month;

    // check the day:
    switch (mode)
      {
      case DOM_MODE:
	if (calDayOfMonth != day)
	  return calDayOfMonth < day;
	break;
      case DOW_IN_MONTH_MODE:
        {
	  // This computes the day of month of the day of type
	  // "dayOfWeek" that lies in the same (sunday based) week as cal.
	  calDayOfMonth += (dayOfWeek - calDayOfWeek);

	  // Now we convert it to 7 based number (to get a one based offset
	  // after dividing by 7).  If we count from the end of the
	  // month, we get want a -7 based number counting the days from 
	  // the end:
	  if (day < 0)
	    calDayOfMonth -= getDaysInMonth(calMonth, calYear) + 7;
	  else
	    calDayOfMonth += 6;

	  //  day > 0                    day < 0
	  //  S  M  T  W  T  F  S        S  M  T  W  T  F  S
	  //     7  8  9 10 11 12         -36-35-34-33-32-31
	  // 13 14 15 16 17 18 19      -30-29-28-27-26-25-24
	  // 20 21 22 23 24 25 26      -23-22-21-20-19-18-17
	  // 27 28 29 30 31 32 33      -16-15-14-13-12-11-10
	  // 34 35 36                   -9 -8 -7
	  // Now we calculate the day of week in month:
	  int week = calDayOfMonth / 7;

	  //  day > 0                    day < 0
	  //  S  M  T  W  T  F  S        S  M  T  W  T  F  S
	  //     1  1  1  1  1  1          -5 -5 -4 -4 -4 -4
	  //  1  2  2  2  2  2  2       -4 -4 -4 -3 -3 -3 -3
	  //  2  3  3  3  3  3  3       -3 -3 -3 -2 -2 -2 -2
	  //  3  4  4  4  4  4  4       -2 -2 -2 -1 -1 -1 -1
	  //  4  5  5                   -1 -1 -1
	  if (week != day)
	    return week < day;

	  if (calDayOfWeek != dayOfWeek)
	    return calDayOfWeek < dayOfWeek;

	  // daylight savings starts/ends  on the given day.
	  break;
        }
      case DOW_LE_DOM_MODE:
	// The greatest sunday before or equal December, 12
	// is the same as smallest sunday after or equal December, 6.
	day = Math.abs(day) - 6;
      case DOW_GE_DOM_MODE:
	// Calculate the day of month of the day of type
	// "dayOfWeek" that lies before (or on) the given date.
	calDayOfMonth -= (calDayOfWeek < dayOfWeek ? 7 : 0) + calDayOfWeek
	- dayOfWeek;
	if (calDayOfMonth < day)
	  return true;
	if (calDayOfWeek != dayOfWeek || calDayOfMonth >= day + 7)
	  return false;

	// now we have the same day
	break;
      }

    // the millis decides:
    return (calMillis < millis);
  }

  /**
   * Determines if the given date is in daylight savings time.
   * @return true, if it is in daylight savings time, false otherwise.
   */
  public boolean inDaylightTime(Date date)
  {
    Calendar cal = Calendar.getInstance(this);
    cal.setTime(date);
    return (cal.get(Calendar.DST_OFFSET) != 0);
  }

  /**
   * Generates the hashCode for the SimpleDateFormat object.  It is
   * the rawOffset, possibly, if useDaylightSavings is true, xored
   * with startYear, startMonth, startDayOfWeekInMonth, ..., endTime.
   */
  public synchronized int hashCode()
  {
    return rawOffset
           ^ (useDaylight
              ? startMonth ^ startDay ^ startDayOfWeek ^ startTime ^ endMonth
              ^ endDay ^ endDayOfWeek ^ endTime : 0);
  }

  public synchronized boolean equals(Object o)
  {
    if (this == o)
      return true;
    if (! (o instanceof SimpleTimeZone))
      return false;
    SimpleTimeZone zone = (SimpleTimeZone) o;
    if (zone.hashCode() != hashCode() || ! getID().equals(zone.getID())
        || rawOffset != zone.rawOffset || useDaylight != zone.useDaylight)
      return false;
    if (! useDaylight)
      return true;
    return (startYear == zone.startYear && startMonth == zone.startMonth
           && startDay == zone.startDay
           && startDayOfWeek == zone.startDayOfWeek
           && startTime == zone.startTime
           && startTimeMode == zone.startTimeMode && endMonth == zone.endMonth
           && endDay == zone.endDay && endDayOfWeek == zone.endDayOfWeek
           && endTime == zone.endTime && endTimeMode == zone.endTimeMode);
  }

  /**
   * Test if the other time zone uses the same rule and only
   * possibly differs in ID.  This implementation for this particular
   * class will return true if the other object is a SimpleTimeZone,
   * the raw offsets and useDaylight are identical and if useDaylight
   * is true, also the start and end datas are identical.
   * @return true if this zone uses the same rule.
   */
  public boolean hasSameRules(TimeZone other)
  {
    if (this == other)
      return true;
    if (! (other instanceof SimpleTimeZone))
      return false;
    SimpleTimeZone zone = (SimpleTimeZone) other;
    if (zone.hashCode() != hashCode() || rawOffset != zone.rawOffset
        || useDaylight != zone.useDaylight)
      return false;
    if (! useDaylight)
      return true;
    return (startYear == zone.startYear && startMonth == zone.startMonth
           && startDay == zone.startDay
           && startDayOfWeek == zone.startDayOfWeek
           && startTime == zone.startTime
           && startTimeMode == zone.startTimeMode && endMonth == zone.endMonth
           && endDay == zone.endDay && endDayOfWeek == zone.endDayOfWeek
           && endTime == zone.endTime && endTimeMode == zone.endTimeMode);
  }

  /**
   * Returns a string representation of this SimpleTimeZone object.
   * @return a string representation of this SimpleTimeZone object.
   */
  public String toString()
  {
    // the test for useDaylight is an incompatibility to jdk1.2, but
    // I think this shouldn't hurt.
    return getClass().getName() + "[" + "id=" + getID() + ",offset="
           + rawOffset + ",dstSavings=" + dstSavings + ",useDaylight="
           + useDaylight
           + (useDaylight
              ? ",startYear=" + startYear + ",startMode=" + startMode
              + ",startMonth=" + startMonth + ",startDay=" + startDay
              + ",startDayOfWeek=" + startDayOfWeek + ",startTime="
              + startTime + ",startTimeMode=" + startTimeMode + ",endMode="
              + endMode + ",endMonth=" + endMonth + ",endDay=" + endDay
              + ",endDayOfWeek=" + endDayOfWeek + ",endTime=" + endTime
              + ",endTimeMode=" + endTimeMode : "") + "]";
  }

  /**
   * Reads a serialized simple time zone from stream.
   * @see #writeObject
   */
  private void readObject(java.io.ObjectInputStream input)
    throws java.io.IOException, ClassNotFoundException
  {
    input.defaultReadObject();
    if (serialVersionOnStream == 0)
      {
	// initialize the new fields to default values.
	dstSavings = 60 * 60 * 1000;
	endMode = DOW_IN_MONTH_MODE;
	startMode = DOW_IN_MONTH_MODE;
	startTimeMode = WALL_TIME;
	endTimeMode = WALL_TIME;
	serialVersionOnStream = 2;
      }
    else
      {
	int length = input.readInt();
	byte[] byteArray = new byte[length];
	input.read(byteArray, 0, length);
	if (length >= 4)
	  {
	    // Lets hope that Sun does extensions to the serialized
	    // form in a sane manner.
	    startDay = byteArray[0];
	    startDayOfWeek = byteArray[1];
	    endDay = byteArray[2];
	    endDayOfWeek = byteArray[3];
	  }
      }
  }

  /**
   * Serializes this object to a stream.  @serialdata The object is
   * first written in the old JDK 1.1 format, so that it can be read
   * by by the old classes.  This means, that the
   * <code>start/endDay(OfWeek)</code>-Fields are written in the
   * DOW_IN_MONTH_MODE rule, since this was the only supported rule
   * in 1.1.
   *
   * In the optional section, we write first the length of an byte
   * array as int and afterwards the byte array itself.  The byte
   * array contains in this release four elements, namely the real
   * startDay, startDayOfWeek endDay, endDayOfWeek in that Order.
   * These fields are needed, because for compatibility reasons only
   * approximative values are written to the required section, as
   * described above.
   */
  private void writeObject(java.io.ObjectOutputStream output)
    throws java.io.IOException
  {
    byte[] byteArray = new byte[]
                       {
                         (byte) startDay, (byte) startDayOfWeek, (byte) endDay,
                         (byte) endDayOfWeek
                       };

    /* calculate the approximation for JDK 1.1 */
    switch (startMode)
      {
      case DOM_MODE:
	startDayOfWeek = Calendar.SUNDAY; // random day of week

      // fall through
      case DOW_GE_DOM_MODE:
      case DOW_LE_DOM_MODE:
	startDay = (startDay + 6) / 7;
      }
    switch (endMode)
      {
      case DOM_MODE:
	endDayOfWeek = Calendar.SUNDAY;

      // fall through
      case DOW_GE_DOM_MODE:
      case DOW_LE_DOM_MODE:
	endDay = (endDay + 6) / 7;
      }

    // the required part:
    output.defaultWriteObject();
    // the optional part:
    output.writeInt(byteArray.length);
    output.write(byteArray, 0, byteArray.length);
  }
}
