/* java.util.SimpleTimeZone
   Copyright (C) 1998, 1999, 2000, 2003, 2004, 2005, 2007
   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 in startTimeMode
   * chosen time mode.
   * @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 in endTimeMode
   * chosen time mode.
   * @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, id, startMonth, startDayOfWeekInMonth, startDayOfWeek,
	 startTime, endMonth, endDayOfWeekInMonth, endDayOfWeek, endTime);

    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.dstSavings = dstSavings;
    this.startTimeMode = startTimeMode;
    this.endTimeMode = endTimeMode;
  }

  /**
   * 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);
    this.startTime = time;
    this.startTimeMode = WALL_TIME;
  }

  /**
   * 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)
  {
    if (after)
      setStartRule(month, day, -dayOfWeek, time);
    else
      setStartRule(month, -day, -dayOfWeek, time);
  }

  /**
   * 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);
    this.endTime = time;
    this.endTimeMode = WALL_TIME;
    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)
  {
    if (after)
      setEndRule(month, day, -dayOfWeek, time);
    else
      setEndRule(month, -day, -dayOfWeek, 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 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)
      {
	int orig_year = year;
	int time = startTime + (startTimeMode == UTC_TIME ? rawOffset : 0);
	// 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, time);
	millis += dstSavings;
	if (millis >= 24 * 60 * 60 * 1000)
	  {
	    millis -= 24 * 60 * 60 * 1000;
	    dayOfWeek = (dayOfWeek % 7) + 1;
	    if (++day > daysInMonth)
	      {
		day = 1;
		if (month++ == Calendar.DECEMBER)
		  {
		    month = Calendar.JANUARY;
		    year++;
		  }
	      }
	  }
	time = endTime + (endTimeMode == UTC_TIME ? rawOffset : 0);
	if (endTimeMode != WALL_TIME)
	  time += dstSavings;
	boolean beforeEnd = isBefore(year, month, day, dayOfWeek, millis,
				     endMode, endMonth, endDay, endDayOfWeek,
				     time);

	if (year != orig_year)
	  afterStart = false;
	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 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);
  }
}
