/* Calendar.java --
   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005, 2006,
   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;

import gnu.java.lang.CPStringBuilder;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

import java.text.DateFormatSymbols;

/**
 * This class is an abstract base class for Calendars, which can be
 * used to convert between <code>Date</code> objects and a set of
 * integer fields which represent <code>YEAR</code>,
 * <code>MONTH</code>, <code>DAY</code>, etc.  The <code>Date</code>
 * object represents a time in milliseconds since the Epoch. <br>
 *
 * This class is locale sensitive.  To get the Object matching the
 * current locale you can use <code>getInstance</code>.  You can even provide
 * a locale or a timezone.  <code>getInstance</code> returns currently
 * a <code>GregorianCalendar</code> for the current date. <br>
 *
 * If you want to convert a date from the Year, Month, Day, DayOfWeek,
 * etc.  Representation to a <code>Date</code>-Object, you can create
 * a new Calendar with <code>getInstance()</code>,
 * <code>clear()</code> all fields, <code>set(int,int)</code> the
 * fields you need and convert it with <code>getTime()</code>. <br>
 *
 * If you want to convert a <code>Date</code>-object to the Calendar
 * representation, create a new Calendar, assign the
 * <code>Date</code>-Object with <code>setTime()</code>, and read the
 * fields with <code>get(int)</code>. <br>
 *
 * When computing the date from time fields, it may happen, that there
 * are either two few fields set, or some fields are inconsistent.  This
 * cases will handled in a calendar specific way.  Missing fields are
 * replaced by the fields of the epoch: 1970 January 1 00:00. <br>
 *
 * To understand, how the day of year is computed out of the fields
 * look at the following table.  It is traversed from top to bottom,
 * and for the first line all fields are set, that line is used to
 * compute the day. <br>
 *
 *
<pre>month + day_of_month
month + week_of_month + day_of_week
month + day_of_week_of_month + day_of_week
day_of_year
day_of_week + week_of_year</pre>
 *
 * The hour_of_day-field takes precedence over the ampm and
 * hour_of_ampm fields. <br>
 *
 * <STRONG>Note:</STRONG> This can differ for non-Gregorian calendar. <br>
 *
 * To convert a calendar to a human readable form and vice versa,  use
 * the <code>java.text.DateFormat</code> class. <br>
 *
 * Other useful things you can do with an calendar, is
 * <code>roll</code>ing fields (that means increase/decrease a
 * specific field by one, propagating overflows), or
 * <code>add</code>ing/substracting a fixed amount to a field.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Jochen Hoenicke (Jochen.Hoenicke@Informatik.Uni-Oldenburg.de)
 * @author Warren Levy (warrenl@cygnus.com)
 * @author Jeff Sturm (jsturm@one-point.com)
 * @author Tom Tromey (tromey@redhat.com)
 * @author Bryce McKinlay (mckinlay@redhat.com)
 * @author Ingo Proetel (proetel@aicas.com)
 * @author Jerry Quinn (jlquinn@optonline.net)
 * @author Jeroen Frijters (jeroen@frijters.net)
 * @author Noa Resare (noa@resare.com)
 * @author Sven de Marothy (sven@physto.se)
 * @author David Gilbert (david.gilbert@object-refinery.com)
 * @author Olivier Jolly (olivier.jolly@pcedev.com)
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
 * @see Date
 * @see GregorianCalendar
 * @see TimeZone
 * @see java.text.DateFormat
 */
public abstract class Calendar
  implements Serializable, Cloneable, Comparable<Calendar>
{
  /**
   * Constant representing the era time field.
   */
  public static final int ERA = 0;

  /**
   * Constant representing the year time field.
   */
  public static final int YEAR = 1;

  /**
   * Constant representing the month time field.  This field
   * should contain one of the JANUARY,...,DECEMBER constants below.
   */
  public static final int MONTH = 2;

  /**
   * Constant representing the week of the year field.
   * @see #setFirstDayOfWeek(int)
   */
  public static final int WEEK_OF_YEAR = 3;

  /**
   * Constant representing the week of the month time field.
   * @see #setFirstDayOfWeek(int)
   */
  public static final int WEEK_OF_MONTH = 4;

  /**
   * Constant representing the day time field, synonym for DAY_OF_MONTH.
   */
  public static final int DATE = 5;

  /**
   * Constant representing the day time field.
   */
  public static final int DAY_OF_MONTH = 5;

  /**
   * Constant representing the day of year time field.  This is
   * 1 for the first day in month.
   */
  public static final int DAY_OF_YEAR = 6;

  /**
   * Constant representing the day of week time field.  This field
   * should contain one of the SUNDAY,...,SATURDAY constants below.
   */
  public static final int DAY_OF_WEEK = 7;

  /**
   * Constant representing the day-of-week-in-month field.  For
   * instance this field contains 2 for the second thursday in a
   * month.  If you give a negative number here, the day will count
   * from the end of the month.
   */
  public static final int DAY_OF_WEEK_IN_MONTH = 8;

  /**
   * Constant representing the part of the day for 12-hour clock.  This
   * should be one of AM or PM.
   */
  public static final int AM_PM = 9;

  /**
   * Constant representing the hour time field for 12-hour clock.
   */
  public static final int HOUR = 10;

  /**
   * Constant representing the hour of day time field for 24-hour clock.
   */
  public static final int HOUR_OF_DAY = 11;

  /**
   * Constant representing the minute of hour time field.
   */
  public static final int MINUTE = 12;

  /**
   * Constant representing the second time field.
   */
  public static final int SECOND = 13;

  /**
   * Constant representing the millisecond time field.
   */
  public static final int MILLISECOND = 14;

  /**
   * Constant representing the time zone offset time field for the
   * time given in the other fields.  It is measured in
   * milliseconds.  The default is the offset of the time zone.
   */
  public static final int ZONE_OFFSET = 15;

  /**
   * Constant representing the daylight saving time offset in
   * milliseconds.  The default is the value given by the time zone.
   */
  public static final int DST_OFFSET = 16;

  /**
   * Number of time fields.
   */
  public static final int FIELD_COUNT = 17;

  /**
   * Constant representing Sunday.
   */
  public static final int SUNDAY = 1;

  /**
   * Constant representing Monday.
   */
  public static final int MONDAY = 2;

  /**
   * Constant representing Tuesday.
   */
  public static final int TUESDAY = 3;

  /**
   * Constant representing Wednesday.
   */
  public static final int WEDNESDAY = 4;

  /**
   * Constant representing Thursday.
   */
  public static final int THURSDAY = 5;

  /**
   * Constant representing Friday.
   */
  public static final int FRIDAY = 6;

  /**
   * Constant representing Saturday.
   */
  public static final int SATURDAY = 7;

  /**
   * Constant representing January.
   */
  public static final int JANUARY = 0;

  /**
   * Constant representing February.
   */
  public static final int FEBRUARY = 1;

  /**
   * Constant representing March.
   */
  public static final int MARCH = 2;

  /**
   * Constant representing April.
   */
  public static final int APRIL = 3;

  /**
   * Constant representing May.
   */
  public static final int MAY = 4;

  /**
   * Constant representing June.
   */
  public static final int JUNE = 5;

  /**
   * Constant representing July.
   */
  public static final int JULY = 6;

  /**
   * Constant representing August.
   */
  public static final int AUGUST = 7;

  /**
   * Constant representing September.
   */
  public static final int SEPTEMBER = 8;

  /**
   * Constant representing October.
   */
  public static final int OCTOBER = 9;

  /**
   * Constant representing November.
   */
  public static final int NOVEMBER = 10;

  /**
   * Constant representing December.
   */
  public static final int DECEMBER = 11;

  /**
   * Constant representing Undecimber. This is an artificial name useful
   * for lunar calendars.
   */
  public static final int UNDECIMBER = 12;

  /**
   * Useful constant for 12-hour clock.
   */
  public static final int AM = 0;

  /**
   * Useful constant for 12-hour clock.
   */
  public static final int PM = 1;

  /**
   * A style specifier for {@link #getDisplayNames(int,int,Locale)}
   * stating that names should be returned in both long and short variants.
   *
   * @since 1.6
   * @see #SHORT
   * @see #LONG
   */
  public static final int ALL_STYLES = 0;

  /**
   * A style specifier for {@link #getDisplayName(int,int,Locale)}
   * and {@link #getDisplayNames(int,int,Locale)} stating that names
   * should be returned in their short variant if applicable.
   *
   * @since 1.6
   */
  public static final int SHORT = 1;

  /**
   * A style specifier for {@link #getDisplayName(int,int,Locale)}
   * and {@link #getDisplayNames(int,int,Locale)} stating that names
   * should be returned in their long variant if applicable.
   *
   * @since 1.6
   */
  public static final int LONG = 2;

  /**
   * The time fields.  The array is indexed by the constants YEAR to
   * DST_OFFSET.
   * @serial
   */
  protected int[] fields = new int[FIELD_COUNT];

  /**
   * The flags which tell if the fields above have a value.
   * @serial
   */
  protected boolean[] isSet = new boolean[FIELD_COUNT];

  /**
   * The time in milliseconds since the epoch.
   * @serial
   */
  protected long time;

  /**
   * Tells if the above field has a valid value.
   * @serial
   */
  protected boolean isTimeSet;

  /**
   * Tells if the fields have a valid value.  This superseeds the isSet
   * array.
   * @serial
   */
  protected boolean areFieldsSet;

  /**
   * The time zone of this calendar.  Used by sub classes to do UTC / local
   * time conversion.  Sub classes can access this field with getTimeZone().
   * @serial
   */
  private TimeZone zone;

  /**
   * This is the default calendar class, that is returned on
   * java.util.Calendar.getInstance().
   * XXX - this isn't localized anywhere, is it?
   * @see java.util.Calendar#getInstance()
   */
  private static final String calendarClassName = "java.util.GregorianCalendar";

  /**
   * Specifies if the date/time interpretation should be lenient.
   * If the flag is set, a date such as "February 30, 1996" will be
   * treated as the 29th day after the February 1.  If this flag
   * is false, such dates will cause an exception.
   * @serial
   */
  private boolean lenient;

  /**
   * Sets what the first day of week is.  This is used for
   * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
   * @serial
   */
  private int firstDayOfWeek;

  /**
   * Sets how many days are required in the first week of the year.
   * If the first day of the year should be the first week you should
   * set this value to 1.  If the first week must be a full week, set
   * it to 7.
   * @serial
   */
  private int minimalDaysInFirstWeek;

  /**
   * Is set to true if DST_OFFSET is explicitly set. In that case
   * it's value overrides the value computed from the current
   * time and the timezone.
   */
  private boolean explicitDSTOffset = false;

  /**
   * The version of the serialized data on the stream.
   * <dl><dt>0 or not present</dt>
   * <dd> JDK 1.1.5 or later.</dd>
   * <dt>1</dt>
   * <dd>JDK 1.1.6 or later.  This always writes a correct `time' value
   * on the stream, as well as the other fields, to be compatible with
   * earlier versions</dd></dl>
   * @since JDK1.1.6
   * @serial
   */
  private int serialVersionOnStream = 1;

  /**
   * XXX - I have not checked the compatibility.  The documentation of
   * the serialized-form is quite hairy...
   */
  static final long serialVersionUID = -1807547505821590642L;

  /**
   * The name of the resource bundle. Used only by getBundle()
   */
  private static final String bundleName = "gnu.java.locale.LocaleInformation";

  /**
   * get resource bundle:
   * The resources should be loaded via this method only. Iff an application
   * uses this method, the resourcebundle is required.
   */
  private static ResourceBundle getBundle(Locale locale)
  {
    return ResourceBundle.getBundle(bundleName, locale,
                                    ClassLoader.getSystemClassLoader());
  }

  /**
   * The set of properties for obtaining the minimum number of days in
   * the first week.
   */
  private static transient final Properties properties;

  /**
   * Reads in the properties.
   */
  static
  {
    properties = new Properties();
    try
      {
        properties.load(Calendar.class.getResourceAsStream("weeks.properties"));
      }
    catch (IOException exception)
      {
        System.out.println("Failed to load weeks resource: " + exception);
      }
  }

  /**
   * Constructs a new Calendar with the default time zone and the default
   * locale.
   */
  protected Calendar()
  {
    this(TimeZone.getDefault(), Locale.getDefault());
  }

  /**
   * Constructs a new Calendar with the given time zone and the given
   * locale.
   * @param zone a time zone.
   * @param locale a locale.
   */
  protected Calendar(TimeZone zone, Locale locale)
  {
    this.zone = zone;
    lenient = true;
    String[] days = { "", "sun", "mon", "tue", "wed", "thu", "fri", "sat" };

    String country = locale.getCountry();
    String min = properties.getProperty("minDays." + country);
    if (min == null)
      min = properties.getProperty("minDays.DEFAULT");
    String first = properties.getProperty("firstDay." + country);
    if (first == null)
      first = properties.getProperty("firstDay.DEFAULT");
    try
      {
        if (min != null)
          minimalDaysInFirstWeek = Integer.parseInt(min);
      }
    catch (NumberFormatException ex)
      {
        minimalDaysInFirstWeek = 1;
      }

    firstDayOfWeek = 1;
    if (first != null)
      for (int i = 0; i < 8; i++)
        if (days[i].equals(first))
          firstDayOfWeek = i;

    clear();
  }

  /**
   * Creates a calendar representing the actual time, using the default
   * time zone and locale.
   *
   * @return The new calendar.
   */
  public static synchronized Calendar getInstance()
  {
    return getInstance(TimeZone.getDefault(), Locale.getDefault());
  }

  /**
   * Creates a calendar representing the actual time, using the given
   * time zone and the default locale.
   *
   * @param zone a time zone (<code>null</code> not permitted).
   *
   * @return The new calendar.
   *
   * @throws NullPointerException if <code>zone</code> is <code>null</code>.
   */
  public static synchronized Calendar getInstance(TimeZone zone)
  {
    return getInstance(zone, Locale.getDefault());
  }

  /**
   * Creates a calendar representing the actual time, using the default
   * time zone and the given locale.
   *
   * @param locale a locale (<code>null</code> not permitted).
   *
   * @return The new calendar.
   *
   * @throws NullPointerException if <code>locale</code> is <code>null</code>.
   */
  public static synchronized Calendar getInstance(Locale locale)
  {
    return getInstance(TimeZone.getDefault(), locale);
  }

  /**
   * Cache of locale->calendar-class mappings. This avoids having to do a ResourceBundle
   * lookup for every getInstance call.
   */
  private static final HashMap<Locale,Class> cache = new HashMap<Locale,Class>();

  /** Preset argument types for calendar-class constructor lookup.  */
  private static Class[] ctorArgTypes = new Class[]
                                        {
                                          TimeZone.class, Locale.class
                                        };

  /**
   * Creates a calendar representing the actual time, using the given
   * time zone and locale.
   *
   * @param zone a time zone (<code>null</code> not permitted).
   * @param locale a locale (<code>null</code> not permitted).
   *
   * @return The new calendar.
   *
   * @throws NullPointerException if <code>zone</code> or <code>locale</code>
   *     is <code>null</code>.
   */
  public static synchronized Calendar getInstance(TimeZone zone, Locale locale)
  {
    Class calendarClass = cache.get(locale);
    Throwable exception = null;

    try
      {
        if (calendarClass == null)
          {
            calendarClass = Class.forName(calendarClassName);
            if (Calendar.class.isAssignableFrom(calendarClass))
              cache.put(locale, calendarClass);
          }

        // GregorianCalendar is by far the most common case. Optimize by
        // avoiding reflection.
        if (calendarClass == GregorianCalendar.class)
          return new GregorianCalendar(zone, locale);

        if (Calendar.class.isAssignableFrom(calendarClass))
          {
            Constructor ctor = calendarClass.getConstructor(ctorArgTypes);
            return (Calendar) ctor.newInstance(new Object[] { zone, locale });
          }
      }
    catch (ClassNotFoundException ex)
      {
        exception = ex;
      }
    catch (IllegalAccessException ex)
      {
        exception = ex;
      }
    catch (NoSuchMethodException ex)
      {
        exception = ex;
      }
    catch (InstantiationException ex)
      {
        exception = ex;
      }
    catch (InvocationTargetException ex)
      {
        exception = ex;
      }

    throw new RuntimeException("Error instantiating calendar for locale "
                               + locale, exception);
  }

  /**
   * Gets the set of locales for which a Calendar is available.
   * @exception MissingResourceException if locale data couldn't be found.
   * @return the set of locales.
   */
  public static synchronized Locale[] getAvailableLocales()
  {
    ResourceBundle rb = getBundle(new Locale("", ""));
    return (Locale[]) rb.getObject("availableLocales");
  }

  /**
   * Converts the time field values (<code>fields</code>) to
   * milliseconds since the epoch UTC (<code>time</code>).  Override
   * this method if you write your own Calendar.  */
  protected abstract void computeTime();

  /**
   * Converts the milliseconds since the epoch UTC
   * (<code>time</code>) to time fields
   * (<code>fields</code>). Override this method if you write your
   * own Calendar.
   */
  protected abstract void computeFields();

  /**
   * Converts the time represented by this object to a
   * <code>Date</code>-Object.
   * @return the Date.
   */
  public final Date getTime()
  {
    if (! isTimeSet)
      computeTime();
    return new Date(time);
  }

  /**
   * Sets this Calendar's time to the given Date.  All time fields
   * are invalidated by this method.
   *
   * @param date  the date (<code>null</code> not permitted).
   *
   * @throws NullPointerException if <code>date</code> is <code>null</code>.
   */
  public final void setTime(Date date)
  {
    setTimeInMillis(date.getTime());
  }

  /**
   * Returns the time represented by this Calendar.
   * @return the time in milliseconds since the epoch.
   * @specnote This was made public in 1.4.
   */
  public long getTimeInMillis()
  {
    if (! isTimeSet)
      computeTime();
    return time;
  }

  /**
   * Sets this Calendar's time to the given Time.  All time fields
   * are invalidated by this method.
   * @param time the time in milliseconds since the epoch
   * @specnote This was made public in 1.4.
   */
  public void setTimeInMillis(long time)
  {
    clear();
    this.time = time;
    isTimeSet = true;
    computeFields();
  }

  /**
   * Gets the value of the specified field.  They are recomputed
   * if they are invalid.
   * @param field the time field. One of the time field constants.
   * @return the value of the specified field
   * @throws ArrayIndexOutOfBoundsException if the field is outside
   *         the valid range.  The value of field must be >= 0 and
   *         <= <code>FIELD_COUNT</code>.
   * @specnote Not final since JDK 1.4
   */
  public int get(int field)
  {
    // If the requested field is invalid, force all fields to be recomputed.
    if (! isSet[field])
      areFieldsSet = false;
    complete();
    return fields[field];
  }

  /**
   * Gets the value of the specified field. This method doesn't
   * recompute the fields, if they are invalid.
   * @param field the time field. One of the time field constants.
   * @return the value of the specified field, undefined if
   * <code>areFieldsSet</code> or <code>isSet[field]</code> is false.
   * @throws ArrayIndexOutOfBoundsException if the field is outside
   *         the valid range.  The value of field must be >= 0 and
   *         <= <code>FIELD_COUNT</code>.
   */
  protected final int internalGet(int field)
  {
    return fields[field];
  }

  /**
   * Sets the time field with the given value.  This does invalidate
   * the time in milliseconds.
   * @param field the time field. One of the time field constants
   * @param value the value to be set.
   * @throws ArrayIndexOutOfBoundsException if field is outside
   *         the valid range.  The value of field must be >= 0 and
   *         <= <code>FIELD_COUNT</code>.
   * @specnote Not final since JDK 1.4
   */
  public void set(int field, int value)
  {
    if (isTimeSet)
      for (int i = 0; i < FIELD_COUNT; i++)
        isSet[i] = false;
    isTimeSet = false;
    fields[field] = value;
    isSet[field] = true;

    // The five valid date patterns, in order of priority
    // 1  YEAR + MONTH + DAY_OF_MONTH
    // 2  YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
    // 3  YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
    // 4  YEAR + DAY_OF_YEAR
    // 5  YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
    switch (field)
      {
      case MONTH: // pattern 1,2 or 3
        isSet[DAY_OF_YEAR] = false;
        isSet[WEEK_OF_YEAR] = false;
        break;
      case DAY_OF_MONTH: // pattern 1
        isSet[YEAR] = true;
        isSet[MONTH] = true;
        isSet[WEEK_OF_MONTH] = true;
        isSet[DAY_OF_WEEK] = false;
        isSet[DAY_OF_WEEK_IN_MONTH] = false;
        isSet[DAY_OF_YEAR] = false;
        isSet[WEEK_OF_YEAR] = false;
        break;
      case WEEK_OF_MONTH: // pattern 2
        if (! isSet[DAY_OF_WEEK])
          fields[DAY_OF_WEEK] = getFirstDayOfWeek();
        isSet[YEAR] = true;
        isSet[MONTH] = true;
        isSet[DAY_OF_WEEK] = true;
        isSet[DAY_OF_MONTH] = false;
        isSet[DAY_OF_WEEK_IN_MONTH] = false;
        isSet[DAY_OF_YEAR] = false;
        isSet[WEEK_OF_YEAR] = false;
        break;
      case DAY_OF_WEEK_IN_MONTH: // pattern 3
        if (! isSet[DAY_OF_WEEK])
          fields[DAY_OF_WEEK] = getFirstDayOfWeek();
        isSet[YEAR] = true;
        isSet[MONTH] = true;
        isSet[DAY_OF_WEEK] = true;
        isSet[DAY_OF_YEAR] = false;
        isSet[DAY_OF_MONTH] = false;
        isSet[WEEK_OF_MONTH] = false;
        isSet[WEEK_OF_YEAR] = false;
        break;
      case DAY_OF_YEAR: // pattern 4
        isSet[YEAR] = true;
        isSet[MONTH] = false;
        isSet[WEEK_OF_MONTH] = false;
        isSet[DAY_OF_MONTH] = false;
        isSet[DAY_OF_WEEK] = false;
        isSet[WEEK_OF_YEAR] = false;
        isSet[DAY_OF_WEEK_IN_MONTH] = false;
        break;
      case WEEK_OF_YEAR: // pattern 5
        if (! isSet[DAY_OF_WEEK])
          fields[DAY_OF_WEEK] = getFirstDayOfWeek();
        isSet[YEAR] = true;
        isSet[DAY_OF_WEEK] = true;
        isSet[MONTH] = false;
        isSet[DAY_OF_MONTH] = false;
        isSet[WEEK_OF_MONTH] = false;
        isSet[DAY_OF_YEAR] = false;
        isSet[DAY_OF_WEEK_IN_MONTH] = false;
        break;
      case AM_PM:
        isSet[HOUR] = true;
        isSet[HOUR_OF_DAY] = false;
        break;
      case HOUR_OF_DAY:
        isSet[AM_PM] = false;
        isSet[HOUR] = false;
        break;
      case HOUR:
        isSet[AM_PM] = true;
        isSet[HOUR_OF_DAY] = false;
        break;
      case DST_OFFSET:
        explicitDSTOffset = true;
      }

    // May have crossed over a DST boundary.
    if (! explicitDSTOffset && (field != DST_OFFSET && field != ZONE_OFFSET))
      isSet[DST_OFFSET] = false;
  }

  /**
   * Sets the fields for year, month, and date
   * @param year the year.
   * @param month the month, one of the constants JANUARY..UNDICEMBER.
   * @param date the day of the month
   */
  public final void set(int year, int month, int date)
  {
    isTimeSet = false;
    fields[YEAR] = year;
    fields[MONTH] = month;
    fields[DATE] = date;
    isSet[YEAR] = isSet[MONTH] = isSet[DATE] = true;
    isSet[WEEK_OF_YEAR] = false;
    isSet[DAY_OF_YEAR] = false;
    isSet[WEEK_OF_MONTH] = false;
    isSet[DAY_OF_WEEK] = false;
    isSet[DAY_OF_WEEK_IN_MONTH] = false;
    isSet[ERA] = false;

    if (! explicitDSTOffset)
      isSet[DST_OFFSET] = false; // May have crossed a DST boundary.
  }

  /**
   * Sets the fields for year, month, date, hour, and minute
   * @param year the year.
   * @param month the month, one of the constants JANUARY..UNDICEMBER.
   * @param date the day of the month
   * @param hour the hour of day.
   * @param minute the minute.
   */
  public final void set(int year, int month, int date, int hour, int minute)
  {
    set(year, month, date);
    fields[HOUR_OF_DAY] = hour;
    fields[MINUTE] = minute;
    isSet[HOUR_OF_DAY] = isSet[MINUTE] = true;
    isSet[AM_PM] = false;
    isSet[HOUR] = false;
  }

  /**
   * Sets the fields for year, month, date, hour, and minute
   * @param year the year.
   * @param month the month, one of the constants JANUARY..UNDICEMBER.
   * @param date the day of the month
   * @param hour the hour of day.
   * @param minute the minute.
   * @param second the second.
   */
  public final void set(int year, int month, int date, int hour, int minute,
                        int second)
  {
    set(year, month, date, hour, minute);
    fields[SECOND] = second;
    isSet[SECOND] = true;
  }

  /**
   * Clears the values of all the time fields.
   */
  public final void clear()
  {
    isTimeSet = false;
    areFieldsSet = false;
    int zoneOffs = zone.getRawOffset();
    int[] tempFields =
                       {
                         1, 1970, JANUARY, 1, 1, 1, 1, THURSDAY, 1, AM, 0, 0, 0,
                         0, 0, zoneOffs, 0
                       };
    fields = tempFields;
    for (int i = 0; i < FIELD_COUNT; i++)
      isSet[i] = false;
  }

  /**
   * Clears the values of the specified time field.
   * @param field the time field. One of the time field constants.
   * @throws ArrayIndexOutOfBoundsException if field is outside
   *         the valid range.  The value of field must be >= 0 and
   *         <= <code>FIELD_COUNT</code>.
   */
  public final void clear(int field)
  {
    int[] tempFields =
                       {
                         1, 1970, JANUARY, 1, 1, 1, 1, THURSDAY, 1, AM, 0, 0, 0,
                         0, 0, zone.getRawOffset(), 0
                       };
    complete();
    isTimeSet = false;
    areFieldsSet = false;
    isSet[field] = false;
    fields[field] = tempFields[field];
  }

  /**
   * Determines if the specified field has a valid value.
   * @return true if the specified field has a value.
   * @throws ArrayIndexOutOfBoundsException if the field is outside
   *         the valid range.  The value of field must be >= 0 and
   *         <= <code>FIELD_COUNT</code>.
   */
  public final boolean isSet(int field)
  {
    return isSet[field];
  }

  /**
   * Fills any unset fields in the time field list
   */
  protected void complete()
  {
    if (! isTimeSet)
      computeTime();
    if (! areFieldsSet)
      computeFields();
  }

  /**
   * Compares the given calendar with this.
   * @param o the object to that we should compare.
   * @return true, if the given object is a calendar, that represents
   * the same time (but doesn't necessary have the same fields).
   */
  public boolean equals(Object o)
  {
    if (! (o instanceof Calendar))
      return false;
    Calendar cal = (Calendar) o;
    if (getTimeInMillis() == ((Calendar) o).getTimeInMillis()
        && cal.getFirstDayOfWeek() == getFirstDayOfWeek()
        && cal.isLenient() == isLenient()
        && cal.getMinimalDaysInFirstWeek() == getMinimalDaysInFirstWeek())
      {
        TimeZone self = getTimeZone();
        TimeZone oth = cal.getTimeZone();
        return self == null ? oth == null : self.equals(oth);
      }
    return false;
  }

  /**
   * Returns a hash code for this calendar.
   * @return a hash code, which fullfits the general contract of
   * <code>hashCode()</code>
   */
  public int hashCode()
  {
    long time = getTimeInMillis();
    int val = (int) ((time & 0xffffffffL) ^ (time >> 32));
    val += (getFirstDayOfWeek() + (isLenient() ? 1230 : 1237)
            + getMinimalDaysInFirstWeek());
    TimeZone self = getTimeZone();
    if (self != null)
      val ^= self.hashCode();
    return val;
  }

  /**
   * Compares the given calendar with this.
   * @param o the object to that we should compare.
   * @return true, if the given object is a calendar, and this calendar
   * represents a smaller time than the calendar o.
   * @exception ClassCastException if o is not an calendar.
   * @since JDK1.2 you don't need to override this method
   */
  public boolean before(Object o)
  {
    return getTimeInMillis() < ((Calendar) o).getTimeInMillis();
  }

  /**
   * Compares the given calendar with this.
   * @param o the object to that we should compare.
   * @return true, if the given object is a calendar, and this calendar
   * represents a bigger time than the calendar o.
   * @exception ClassCastException if o is not an calendar.
   * @since JDK1.2 you don't need to override this method
   */
  public boolean after(Object o)
  {
    return getTimeInMillis() > ((Calendar) o).getTimeInMillis();
  }

  /**
   * Adds the specified amount of time to the given time field.  The
   * amount may be negative to subtract the time.  If the field overflows
   * it does what you expect: Jan, 25 + 10 Days is Feb, 4.
   * @param field the time field. One of the time field constants.
   * @param amount the amount of time.
   * @throws ArrayIndexOutOfBoundsException if the field is outside
   *         the valid range.  The value of field must be >= 0 and
   *         <= <code>FIELD_COUNT</code>.
   */
  public abstract void add(int field, int amount);

  /**
   * Rolls the specified time field up or down.  This means add one
   * to the specified field, but don't change the other fields.  If
   * the maximum for this field is reached, start over with the
   * minimum value.  <br>
   *
   * <strong>Note:</strong> There may be situation, where the other
   * fields must be changed, e.g rolling the month on May, 31.
   * The date June, 31 is automatically converted to July, 1.
   * @param field the time field. One of the time field constants.
   * @param up the direction, true for up, false for down.
   * @throws ArrayIndexOutOfBoundsException if the field is outside
   *         the valid range.  The value of field must be >= 0 and
   *         <= <code>FIELD_COUNT</code>.
   */
  public abstract void roll(int field, boolean up);

  /**
   * Rolls up or down the specified time field by the given amount.
   * A negative amount rolls down.  The default implementation is
   * call <code>roll(int, boolean)</code> for the specified amount.
   *
   * Subclasses should override this method to do more intuitiv things.
   *
   * @param field the time field. One of the time field constants.
   * @param amount the amount to roll by, positive for rolling up,
   * negative for rolling down.
   * @throws ArrayIndexOutOfBoundsException if the field is outside
   *         the valid range.  The value of field must be >= 0 and
   *         <= <code>FIELD_COUNT</code>.
   * @since JDK1.2
   */
  public void roll(int field, int amount)
  {
    while (amount > 0)
      {
        roll(field, true);
        amount--;
      }
    while (amount < 0)
      {
        roll(field, false);
        amount++;
      }
  }

  /**
   * Sets the time zone to the specified value.
   * @param zone the new time zone
   */
  public void setTimeZone(TimeZone zone)
  {
    this.zone = zone;
    computeTime();
    computeFields();
  }

  /**
   * Gets the time zone of this calendar
   * @return the current time zone.
   */
  public TimeZone getTimeZone()
  {
    return zone;
  }

  /**
   * Specifies if the date/time interpretation should be lenient.
   * If the flag is set, a date such as "February 30, 1996" will be
   * treated as the 29th day after the February 1.  If this flag
   * is false, such dates will cause an exception.
   * @param lenient true, if the date should be interpreted linient,
   * false if it should be interpreted strict.
   */
  public void setLenient(boolean lenient)
  {
    this.lenient = lenient;
  }

  /**
   * Tells if the date/time interpretation is lenient.
   * @return true, if the date should be interpreted linient,
   * false if it should be interpreted strict.
   */
  public boolean isLenient()
  {
    return lenient;
  }

  /**
   * Sets what the first day of week is.  This is used for
   * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
   * @param value the first day of week.  One of SUNDAY to SATURDAY.
   */
  public void setFirstDayOfWeek(int value)
  {
    firstDayOfWeek = value;
  }

  /**
   * Gets what the first day of week is.  This is used for
   * WEEK_OF_MONTH and WEEK_OF_YEAR fields.
   * @return the first day of week.  One of SUNDAY to SATURDAY.
   */
  public int getFirstDayOfWeek()
  {
    return firstDayOfWeek;
  }

  /**
   * Sets how many days are required in the first week of the year.
   * If the first day of the year should be the first week you should
   * set this value to 1.  If the first week must be a full week, set
   * it to 7.
   * @param value the minimal days required in the first week.
   */
  public void setMinimalDaysInFirstWeek(int value)
  {
    minimalDaysInFirstWeek = value;
  }

  /**
   * Gets how many days are required in the first week of the year.
   * @return the minimal days required in the first week.
   * @see #setMinimalDaysInFirstWeek
   */
  public int getMinimalDaysInFirstWeek()
  {
    return minimalDaysInFirstWeek;
  }

  /**
   * Gets the smallest value that is allowed for the specified field.
   * @param field the time field. One of the time field constants.
   * @return the smallest value.
   */
  public abstract int getMinimum(int field);

  /**
   * Gets the biggest value that is allowed for the specified field.
   * @param field the time field. One of the time field constants.
   * @return the biggest value.
   */
  public abstract int getMaximum(int field);

  /**
   * Gets the greatest minimum value that is allowed for the specified field.
   * @param field the time field. One of the time field constants.
   * @return the greatest minimum value.
   */
  public abstract int getGreatestMinimum(int field);

  /**
   * Gets the smallest maximum value that is allowed for the
   * specified field.  For example this is 28 for DAY_OF_MONTH.
   * @param field the time field. One of the time field constants.
   * @return the least maximum value.
   */
  public abstract int getLeastMaximum(int field);

  /**
   * Gets the actual minimum value that is allowed for the specified field.
   * This value is dependent on the values of the other fields.
   * @param field the time field. One of the time field constants.
   * @return the actual minimum value.
   * @throws ArrayIndexOutOfBoundsException if the field is outside
   *         the valid range.  The value of field must be >= 0 and
   *         <= <code>FIELD_COUNT</code>.
   * @since jdk1.2
   */
  public int getActualMinimum(int field)
  {
    Calendar tmp = (Calendar) clone(); // To avoid restoring state
    int min = tmp.getGreatestMinimum(field);
    int end = tmp.getMinimum(field);
    tmp.set(field, min);
    for (; min > end; min--)
      {
        tmp.add(field, -1); // Try to get smaller
        if (tmp.get(field) != min - 1)
          break; // Done if not successful
      }
    return min;
  }

  /**
   * Gets the actual maximum value that is allowed for the specified field.
   * This value is dependent on the values of the other fields.
   * @param field the time field. One of the time field constants.
   * @return the actual maximum value.
   * @throws ArrayIndexOutOfBoundsException if the field is outside
   *         the valid range.  The value of field must be >= 0 and
   *         <= <code>FIELD_COUNT</code>.
   * @since jdk1.2
   */
  public int getActualMaximum(int field)
  {
    Calendar tmp = (Calendar) clone(); // To avoid restoring state
    int max = tmp.getLeastMaximum(field);
    int end = tmp.getMaximum(field);
    tmp.set(field, max);
    for (; max < end; max++)
      {
        tmp.add(field, 1);
        if (tmp.get(field) != max + 1)
          break;
      }
    return max;
  }

  /**
   * Compares the time of two calendar instances.
   * @param cal the calendar to which the time should be compared.
   * @return 0 if the two calendars are set to the same time,
   * less than 0 if the time of this calendar is before that of
   * <code>cal</code>, or more than 0 if the time of this calendar is after
   * that of <code>cal</code>.
   *
   * @param cal the calendar to compare this instance with.
   * @throws NullPointerException if <code>cal</code> is null.
   * @throws IllegalArgumentException if either calendar has fields set to
   * invalid values.
   * @since 1.5
   */
  public int compareTo(Calendar cal)
  {
    long t1 = getTimeInMillis();
    long t2 = cal.getTimeInMillis();
    if(t1 == t2)
      return 0;
    if(t1 > t2)
      return 1;
    return -1;
  }

  /**
   * Return a clone of this object.
   */
  public Object clone()
  {
    try
      {
        Calendar cal = (Calendar) super.clone();
        cal.fields = (int[]) fields.clone();
        cal.isSet = (boolean[]) isSet.clone();
        return cal;
      }
    catch (CloneNotSupportedException ex)
      {
        return null;
      }
  }

  private static final String[] fieldNames =
                                             {
                                               ",ERA=", ",YEAR=", ",MONTH=",
                                               ",WEEK_OF_YEAR=",
                                               ",WEEK_OF_MONTH=",
                                               ",DAY_OF_MONTH=",
                                               ",DAY_OF_YEAR=", ",DAY_OF_WEEK=",
                                               ",DAY_OF_WEEK_IN_MONTH=",
                                               ",AM_PM=", ",HOUR=",
                                               ",HOUR_OF_DAY=", ",MINUTE=",
                                               ",SECOND=", ",MILLISECOND=",
                                               ",ZONE_OFFSET=", ",DST_OFFSET="
                                             };

  /**
   * Returns a string representation of this object.  It is mainly
   * for debugging purposes and its content is implementation
   * specific.
   */
  public String toString()
  {
    CPStringBuilder sb = new CPStringBuilder(getClass().getName());
    sb.append('[');
    sb.append("time=");
    if (isTimeSet)
      sb.append(time);
    else
      sb.append("?");
    sb.append(",zone=" + zone);
    sb.append(",areFieldsSet=" + areFieldsSet);
    for (int i = 0; i < FIELD_COUNT; i++)
      {
        sb.append(fieldNames[i]);
        if (isSet[i])
          sb.append(fields[i]);
        else
          sb.append("?");
      }
    sb.append(",lenient=").append(lenient);
    sb.append(",firstDayOfWeek=").append(firstDayOfWeek);
    sb.append(",minimalDaysInFirstWeek=").append(minimalDaysInFirstWeek);
    sb.append("]");
    return sb.toString();
  }

  /**
   * Saves the state of the object to the stream.  Ideally we would
   * only write the time field, but we need to be compatible with
   * earlier versions. <br>
   *
   * This doesn't write the JDK1.1 field nextStamp to the stream, as
   * I don't know what it is good for, and because the documentation
   * says, that it could be omitted.  */
  private void writeObject(ObjectOutputStream stream) throws IOException
  {
    if (! isTimeSet)
      computeTime();
    stream.defaultWriteObject();
  }

  /**
   * Reads the object back from stream (deserialization).
   */
  private void readObject(ObjectInputStream stream)
    throws IOException, ClassNotFoundException
  {
    stream.defaultReadObject();
    if (! isTimeSet)
      computeTime();

    if (serialVersionOnStream > 1)
      {
        // This is my interpretation of the serial number:
        // Sun wants to remove all fields from the stream someday
        // and will then increase the serialVersion number again.
        // We prepare to be compatible.
        fields = new int[FIELD_COUNT];
        isSet = new boolean[FIELD_COUNT];
        areFieldsSet = false;
      }
  }

  /**
   * Returns a localised textual representation of the current value
   * of the given field using the specified style.  If there is no
   * applicable textual representation (e.g. the field has a numeric
   * value), then <code>null</code> is returned.  If one does exist,
   * then the value is obtained from {@link #get(int)} and converted
   * appropriately.  For example, if the <code>MONTH</code> field is
   * requested, then <code>get(MONTH)</code> is called.  This is then
   * converted to a textual representation based on its value and
   * the style requested; if the <code>LONG</code> style is requested
   * and the returned value is <code>11</code> from a
   * {@link GregorianCalendar} implementation, then <code>"December"</code>
   * is returned.  By default, a textual representation is available
   * for all fields which have an applicable value obtainable from
   * {@link java.text.DateFormatSymbols}.
   *
   * @param field the calendar field whose textual representation should
   *              be obtained.
   * @param style the style to use; either {@link #LONG} or {@link #SHORT}.
   * @param locale the locale to use for translation.
   * @return the textual representation of the given field in the specified
   *         style, or <code>null</code> if none is applicable.
   * @throws IllegalArgumentException if <code>field</code> or <code>style</code>
   *                                  or invalid, or the calendar is non-lenient
   *                                  and has invalid values.
   * @throws NullPointerException if <code>locale</code> is <code>null</code>.
   * @since 1.6
   */
  public String getDisplayName(int field, int style, Locale locale)
  {
    if (field < 0 || field >= FIELD_COUNT)
      throw new IllegalArgumentException("The field value, " + field +
                                         ", is invalid.");
    if (style != SHORT && style != LONG)
      throw new IllegalArgumentException("The style must be either " +
                                         "short or long.");
    if (field == YEAR || field == WEEK_OF_YEAR ||
        field == WEEK_OF_MONTH || field == DAY_OF_MONTH ||
        field == DAY_OF_YEAR || field == DAY_OF_WEEK_IN_MONTH ||
        field == HOUR || field == HOUR_OF_DAY || field == MINUTE ||
        field == SECOND || field == MILLISECOND)
      return null;

    int value = get(field);
    DateFormatSymbols syms = DateFormatSymbols.getInstance(locale);
    if (field == ERA)
      return syms.getEras()[value];
    if (field == MONTH)
      if (style == LONG)
        return syms.getMonths()[value];
      else
        return syms.getShortMonths()[value];
    if (field == DAY_OF_WEEK)
      if (style == LONG)
        return syms.getWeekdays()[value];
      else
        return syms.getShortWeekdays()[value];
    if (field == AM_PM)
      return syms.getAmPmStrings()[value];
    if (field == ZONE_OFFSET)
      if (style == LONG)
        return syms.getZoneStrings()[value][1];
      else
        return syms.getZoneStrings()[value][2];
    if (field == DST_OFFSET)
      if (style == LONG)
        return syms.getZoneStrings()[value][3];
      else
        return syms.getZoneStrings()[value][4];

    throw new InternalError("Failed to resolve field " + field +
                            " with style " + style + " for locale " +
                            locale);
  }

  /**
   * Returns a map linking all specified textual representations
   * of the given field to their numerical values.  The textual
   * representations included are determined by the specified
   * style and locale.  For example, if the style <code>LONG</code>
   * is specified and the German locale, then the map will
   * contain "Montag" to {@link #MONDAY}, "Dienstag" to
   * {@link #TUESDAY}, "Mittwoch" to {@link #WEDNESDAY} and
   * so on.  The default implementation uses the values returned
   * by {@link DateFormatSymbols} so, for example, the style
   * {@link #ALL_STYLES} and the field {@link #MONTH} will return
   * a map filled with the values returned from
   * {@link DateFormatSymbols#getMonths()} and
   * {@link DateFormatSymbols#getShortMonths()}.  If there are
   * no textual representations for a given field (usually because
   * it is purely numeric, such as the year in the
   * {@link GregorianCalendar}), <code>null</code> is returned.
   *
   * @param field the calendar field whose textual representation should
   *              be obtained.
   * @param style the style to use; either {@link #LONG}, {@link #SHORT}
   *              or {@link ALL_STYLES}.
   * @param locale the locale to use for translation.
   * @return a map of the textual representations of the given field in the
   *         specified style to their numeric values, or <code>null</code>
   *         if none is applicable.
   * @throws IllegalArgumentException if <code>field</code> or <code>style</code>
   *                                  or invalid, or the calendar is non-lenient
   *                                  and has invalid values.
   * @throws NullPointerException if <code>locale</code> is <code>null</code>.
   * @since 1.6
   */
  public Map<String,Integer> getDisplayNames(int field, int style, Locale locale)
  {
    if (field < 0 || field >= FIELD_COUNT)
      throw new IllegalArgumentException("The field value, " + field +
                                         ", is invalid.");
    if (style != SHORT && style != LONG && style != ALL_STYLES)
      throw new IllegalArgumentException("The style must be either " +
                                         "short, long or all styles.");
    if (field == YEAR || field == WEEK_OF_YEAR ||
        field == WEEK_OF_MONTH || field == DAY_OF_MONTH ||
        field == DAY_OF_YEAR || field == DAY_OF_WEEK_IN_MONTH ||
        field == HOUR || field == HOUR_OF_DAY || field == MINUTE ||
        field == SECOND || field == MILLISECOND)
      return null;

    DateFormatSymbols syms = DateFormatSymbols.getInstance(locale);
    Map<String,Integer> map = new HashMap<String,Integer>();
    if (field == ERA)
      {
        String[] eras = syms.getEras();
        for (int a = 0; a < eras.length; ++a)
          map.put(eras[a], a);
        return map;
      }
    if (field == MONTH)
      {
        if (style == LONG || style == ALL_STYLES)
          {
            String[] months = syms.getMonths();
            for (int a = 0; a < months.length; ++a)
              map.put(months[a], a);
          }
        if (style == SHORT || style == ALL_STYLES)
          {
            String[] months = syms.getShortMonths();
            for (int a = 0; a < months.length; ++a)
              map.put(months[a], a);
          }
        return map;
      }
    if (field == DAY_OF_WEEK)
      {
        if (style == LONG || style == ALL_STYLES)
          {
            String[] weekdays = syms.getWeekdays();
            for (int a = SUNDAY; a < weekdays.length; ++a)
              map.put(weekdays[a], a);
          }
        if (style == SHORT || style == ALL_STYLES)
          {
            String[] weekdays = syms.getShortWeekdays();
            for (int a = SUNDAY; a < weekdays.length; ++a)
              map.put(weekdays[a], a);
          }
        return map;
      }
    if (field == AM_PM)
      {
        String[] ampms = syms.getAmPmStrings();
        for (int a = 0; a < ampms.length; ++a)
          map.put(ampms[a], a);
        return map;
      }
    if (field == ZONE_OFFSET)
      {
        String[][] zones = syms.getZoneStrings();
        for (int a = 0; a < zones.length; ++a)
          {
            if (style == LONG || style == ALL_STYLES)
              map.put(zones[a][1], a);
            if (style == SHORT || style == ALL_STYLES)
              map.put(zones[a][2], a);
          }
        return map;
      }
    if (field == DST_OFFSET)
      {
        String[][] zones = syms.getZoneStrings();
        for (int a = 0; a < zones.length; ++a)
          {
            if (style == LONG || style == ALL_STYLES)
              map.put(zones[a][3], a);
            if (style == SHORT || style == ALL_STYLES)
              map.put(zones[a][4], a);
          }
        return map;
      }

    throw new InternalError("Failed to resolve field " + field +
                            " with style " + style + " for locale " +
                            locale);
  }

}
