/* java.util.GregorianCalendar
   Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004, 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;


/**
 * <p>
 * This class represents the Gregorian calendar, that is used in most
 * countries all over the world.  It does also handle the Julian calendar
 * for dates smaller than the date of the change to the Gregorian calendar.
 * The Gregorian calendar differs from the Julian calendar by a different
 * leap year rule (no leap year every 100 years, except if year is divisible
 * by 400).
 * </p>
 * <p>
 * This change date is different from country to country, and can be changed with
 * <code>setGregorianChange</code>.  The first countries to adopt the Gregorian
 * calendar did so on the 15th of October, 1582.  This date followed October
 * the 4th, 1582 in the Julian calendar system.  The non-existant days that were
 * omitted when the change took place are interpreted as Gregorian dates.
 * </p>
 * <p>
 * Prior to the changeover date, New Year's Day occurred on the 25th of March.
 * However, this class always takes New Year's Day as being the 1st of January.
 * Client code should manually adapt the year value, if required, for dates
 * between January the 1st and March the 24th in years prior to the changeover.
 * </p>
 * <p>
 * Any date infinitely forwards or backwards in time can be represented by
 * this class.  A <em>proleptic</em> calendar system is used, which allows
 * future dates to be created via the existing rules.  This allows meaningful
 * and consistent dates to be produced for all years.  However, dates are only
 * historically accurate following March the 1st, 4AD when the Julian calendar
 * system was adopted.  Prior to this, leap year rules were applied erraticly.
 * </p>
 * <p>
 * There are two eras available for the Gregorian calendar, namely BC and AD.
 * </p>
 * <p>
 * Weeks are defined as a period of seven days, beginning on the first day
 * of the week, as returned by <code>getFirstDayOfWeek()</code>, and ending
 * on the day prior to this.
 * </p>
 * <p>
 * The weeks of the year are numbered from 1 to a possible 53.  The first week
 * of the year is defined as the first week that contains at least the minimum
 * number of days of the first week in the new year (retrieved via
 * <code>getMinimalDaysInFirstWeek()</code>).  All weeks after this are numbered
 * from 2 onwards.
 * </p>
 * <p>
 * For example, take the year 2004.  It began on a Thursday.  The first week
 * of 2004 depends both on where a week begins and how long it must minimally
 * last.  Let's say that the week begins on a Monday and must have a minimum
 * of 5 days.  In this case, the first week begins on Monday, the 5th of January.
 * The first 4 days (Thursday to Sunday) are not eligible, as they are too few
 * to make up the minimum number of days of the first week which must be in
 * the new year.  If the minimum was lowered to 4 days, then the first week
 * would instead begin on Monday, the 29th of December, 2003.  This first week
 * has 4 of its days in the new year, and is now eligible.
 * </p>
 * <p>
 * The weeks of the month are numbered from 0 to a possible 6.  The first week
 * of the month (numbered 1) is a set of days, prior to the first day of the week,
 * which number at least the minimum number of days in a week.  Unlike the first
 * week of the year, the first week of the month only uses days from that particular
 * month.  As a consequence, it may have a variable number of days (from the minimum
 * number required up to a full week of 7) and it need not start on the first day of
 * the week.  It must, however, be following by the first day of the week, as this
 * marks the beginning of week 2.  Any days of the month which occur prior to the
 * first week (because the first day of the week occurs before the minimum number
 * of days is met) are seen as week 0.
 * </p>
 * <p>
 * Again, we will take the example of the year 2004 to demonstrate this.  September
 * 2004 begins on a Wednesday.  Taking our first day of the week as Monday, and the
 * minimum length of the first week as 6, we find that week 1 runs from Monday,
 * the 6th of September to Sunday the 12th.  Prior to the 6th, there are only
 * 5 days (Wednesday through to Sunday).  This is too small a number to meet the
 * minimum, so these are classed as being days in week 0.  Week 2 begins on the
 * 13th, and so on.  This changes if we reduce the minimum to 5.  In this case,
 * week 1 is a truncated week from Wednesday the 1st to Sunday the 5th, and week
 * 0 doesn't exist.  The first seven day week is week 2, starting on the 6th.
 * </p>
 * <p>
 * On using the <code>clear()</code> method, the Gregorian calendar returns
 * to its default value of the 1st of January, 1970 AD 00:00:00 (the epoch).
 * The day of the week is set to the correct day for that particular time.
 * The day is also the first of the month, and the date is in week 0.
 * </p>
 *
 * @see Calendar
 * @see TimeZone
 * @see Calendar#getFirstDayOfWeek()
 * @see Calendar#getMinimalDaysInFirstWeek()
 */
public class GregorianCalendar extends Calendar
{
  /**
   * Constant representing the era BC (Before Christ).
   */
  public static final int BC = 0;

  /**
   * Constant representing the era AD (Anno Domini).
   */
  public static final int AD = 1;

  /**
   * The point at which the Gregorian calendar rules were used.
   * This may be changed by using setGregorianChange;
   * The default is midnight (UTC) on October 5, 1582 (Julian),
   * or October 15, 1582 (Gregorian).
   *
   * @serial the changeover point from the Julian calendar
   *         system to the Gregorian.
   */
  private long gregorianCutover = (new Date((24 * 60 * 60 * 1000L) * (((1582 * (365 * 4
                                            + 1)) / 4
                                            + (java.util.Calendar.OCTOBER * (31
                                            + 30 + 31 + 30 + 31) - 9) / 5 + 5)
                                            - ((1970 * (365 * 4 + 1)) / 4 + 1
                                            - 13)))).getTime();

  /**
   * For compatability with Sun's JDK.
   */
  static final long serialVersionUID = -8125100834729963327L;

  /**
   * Days in the epoch. Relative Jan 1, year '0' which is not a leap year.
   * (although there is no year zero, this does not matter.)
   * This is consistent with the formula:
   * = (year-1)*365L + ((year-1) >> 2)
   *
   * Plus the gregorian correction:
   *  Math.floor((year-1) / 400.) - Math.floor((year-1) / 100.);
   * For a correct julian date, the correction is -2 instead.
   *
   * The gregorian cutover in 1582 was 10 days, so by calculating the
   * correction from year zero, we have 15 non-leap days (even centuries)
   * minus 3 leap days (year 400,800,1200) = 12. Subtracting two corrects
   * this to the correct number 10.
   */
  private static final int EPOCH_DAYS = 719162;

  /**
   * Constructs a new GregorianCalender representing the current
   * time, using the default time zone and the default locale.
   */
  public GregorianCalendar()
  {
    this(TimeZone.getDefault(), Locale.getDefault());
  }

  /**
   * Constructs a new GregorianCalender representing the current
   * time, using the specified time zone and the default locale.
   *
   * @param zone a time zone.
   */
  public GregorianCalendar(TimeZone zone)
  {
    this(zone, Locale.getDefault());
  }

  /**
   * Constructs a new GregorianCalender representing the current
   * time, using the default time zone and the specified locale.
   *
   * @param locale a locale.
   */
  public GregorianCalendar(Locale locale)
  {
    this(TimeZone.getDefault(), locale);
  }

  /**
   * Constructs a new GregorianCalender representing the current
   * time with the given time zone and the given locale.
   *
   * @param zone a time zone.
   * @param locale a locale.
   */
  public GregorianCalendar(TimeZone zone, Locale locale)
  {
    this(zone, locale, false);
    setTimeInMillis(System.currentTimeMillis());
  }

  /**
   * Common constructor that all constructors should call.
   * @param zone a time zone.
   * @param locale a locale.
   * @param unused unused parameter to make the signature differ from
   * the public constructor (TimeZone, Locale).
   */
  private GregorianCalendar(TimeZone zone, Locale locale, boolean unused)
  {
    super(zone, locale);
  }

  /**
   * Constructs a new GregorianCalendar representing midnight on the
   * given date with the default time zone and locale.
   *
   * @param year corresponds to the YEAR time field.
   * @param month corresponds to the MONTH time field.
   * @param day corresponds to the DAY time field.
   */
  public GregorianCalendar(int year, int month, int day)
  {
    this(TimeZone.getDefault(), Locale.getDefault(), false);
    set(year, month, day);
  }

  /**
   * Constructs a new GregorianCalendar representing midnight on the
   * given date with the default time zone and locale.
   *
   * @param year corresponds to the YEAR time field.
   * @param month corresponds to the MONTH time field.
   * @param day corresponds to the DAY time field.
   * @param hour corresponds to the HOUR_OF_DAY time field.
   * @param minute corresponds to the MINUTE time field.
   */
  public GregorianCalendar(int year, int month, int day, int hour, int minute)
  {
    this(TimeZone.getDefault(), Locale.getDefault(), false);
    set(year, month, day, hour, minute);
  }

  /**
   * Constructs a new GregorianCalendar representing midnight on the
   * given date with the default time zone and locale.
   *
   * @param year corresponds to the YEAR time field.
   * @param month corresponds to the MONTH time field.
   * @param day corresponds to the DAY time field.
   * @param hour corresponds to the HOUR_OF_DAY time field.
   * @param minute corresponds to the MINUTE time field.
   * @param second corresponds to the SECOND time field.
   */
  public GregorianCalendar(int year, int month, int day, int hour, int minute,
                           int second)
  {
    this(TimeZone.getDefault(), Locale.getDefault(), false);
    set(year, month, day, hour, minute, second);
  }

  /**
   * Sets the date of the switch from Julian dates to Gregorian dates.
   * You can use <code>new Date(Long.MAX_VALUE)</code> to use a pure
   * Julian calendar, or <code>Long.MIN_VALUE</code> for a pure Gregorian
   * calendar.
   *
   * @param date the date of the change.
   */
  public void setGregorianChange(Date date)
  {
    gregorianCutover = date.getTime();
  }

  /**
   * Gets the date of the switch from Julian dates to Gregorian dates.
   *
   * @return the date of the change.
   */
  public final Date getGregorianChange()
  {
    return new Date(gregorianCutover);
  }

  /**
   * <p>
   * Determines if the given year is a leap year.  The result is
   * undefined if the Gregorian change took place in 1800, so that
   * the end of February is skipped, and that year is specified.
   * (well...).
   * </p>
   * <p>
   * To specify a year in the BC era, use a negative value calculated
   * as 1 - y, where y is the required year in BC.  So, 1 BC is 0,
   * 2 BC is -1, 3 BC is -2, etc.
   * </p>
   *
   * @param year a year (use a negative value for BC).
   * @return true, if the given year is a leap year, false otherwise.
   */
  public boolean isLeapYear(int year)
  {
    // Only years divisible by 4 can be leap years
    if ((year & 3) != 0)
      return false;

    // Is the leap-day a Julian date? Then it's a leap year
    if (! isGregorian(year, 31 + 29 - 1))
      return true;

    // Apply gregorian rules otherwise
    return ((year % 100) != 0 || (year % 400) == 0);
  }

  /**
   * Retrieves the day of the week corresponding to the specified
   * day of the specified year.
   *
   * @param year the year in which the dayOfYear occurs.
   * @param dayOfYear the day of the year (an integer between 0 and
   *        and 366)
   */
  private int getWeekDay(int year, int dayOfYear)
  {
    boolean greg = isGregorian(year, dayOfYear);
    int day = (int) getLinearDay(year, dayOfYear, greg);

    // The epoch was a thursday.
    int weekday = (day + THURSDAY) % 7;
    if (weekday <= 0)
      weekday += 7;
    return weekday;
  }

  /**
   * Returns the day of the week for the first day of a given month (0..11)
   */
  private int getFirstDayOfMonth(int year, int month)
  {
    int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };

    if (month > 11)
      {
	year += (month / 12);
	month = month % 12;
      }

    if (month < 0)
      {
	year += (int) month / 12;
	month = month % 12;
	if (month < 0)
	  {
	    month += 12;
	    year--;
	  }
      }

    int dayOfYear = dayCount[month] + 1;
    if (month > 1)
      if (isLeapYear(year))
	dayOfYear++;

    boolean greg = isGregorian(year, dayOfYear);
    int day = (int) getLinearDay(year, dayOfYear, greg);

    // The epoch was a thursday.
    int weekday = (day + THURSDAY) % 7;
    if (weekday <= 0)
      weekday += 7;
    return weekday;
  }

  /**
   * Takes a year, and a (zero based) day of year and determines
   * if it is gregorian or not.
   */
  private boolean isGregorian(int year, int dayOfYear)
  {
    int relativeDay = (year - 1) * 365 + ((year - 1) >> 2) + dayOfYear
                      - EPOCH_DAYS; // gregorian days from 1 to epoch.
    int gregFactor = (int) Math.floor((double) (year - 1) / 400.)
                     - (int) Math.floor((double) (year - 1) / 100.);

    return ((relativeDay + gregFactor) * 60L * 60L * 24L * 1000L >= gregorianCutover);
  }

  /**
   * Check set fields for validity, without leniency.
   *
   * @throws IllegalArgumentException if a field is invalid
   */
  private void nonLeniencyCheck() throws IllegalArgumentException
  {
    int[] month_days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int year = fields[YEAR];
    int month = fields[MONTH];
    int leap = isLeapYear(year) ? 1 : 0;

    if (isSet[ERA] && fields[ERA] != AD && fields[ERA] != BC)
      throw new IllegalArgumentException("Illegal ERA.");
    if (isSet[YEAR] && fields[YEAR] < 1)
      throw new IllegalArgumentException("Illegal YEAR.");
    if (isSet[MONTH] && (month < 0 || month > 11))
      throw new IllegalArgumentException("Illegal MONTH.");
    if (isSet[WEEK_OF_YEAR])
      {
	int daysInYear = 365 + leap;
	daysInYear += (getFirstDayOfMonth(year, 0) - 1); // pad first week
	int last = getFirstDayOfMonth(year, 11) + 4;
	if (last > 7)
	  last -= 7;
	daysInYear += 7 - last;
	int weeks = daysInYear / 7;
	if (fields[WEEK_OF_YEAR] < 1 || fields[WEEK_OF_YEAR] > weeks)
	  throw new IllegalArgumentException("Illegal WEEK_OF_YEAR.");
      }

    if (isSet[WEEK_OF_MONTH])
      {
	int weeks = (month == 1 && leap == 0) ? 5 : 6;
	if (fields[WEEK_OF_MONTH] < 1 || fields[WEEK_OF_MONTH] > weeks)
	  throw new IllegalArgumentException("Illegal WEEK_OF_MONTH.");
      }

    if (isSet[DAY_OF_MONTH])
      if (fields[DAY_OF_MONTH] < 1
          || fields[DAY_OF_MONTH] > month_days[month]
          + ((month == 1) ? leap : 0))
	throw new IllegalArgumentException("Illegal DAY_OF_MONTH.");

    if (isSet[DAY_OF_YEAR]
        && (fields[DAY_OF_YEAR] < 1 || fields[DAY_OF_YEAR] > 365 + leap))
      throw new IllegalArgumentException("Illegal DAY_OF_YEAR.");

    if (isSet[DAY_OF_WEEK]
        && (fields[DAY_OF_WEEK] < 1 || fields[DAY_OF_WEEK] > 7))
      throw new IllegalArgumentException("Illegal DAY_OF_WEEK.");

    if (isSet[DAY_OF_WEEK_IN_MONTH])
      {
	int weeks = (month == 1 && leap == 0) ? 4 : 5;
	if (fields[DAY_OF_WEEK_IN_MONTH] < -weeks
	    || fields[DAY_OF_WEEK_IN_MONTH] > weeks)
	  throw new IllegalArgumentException("Illegal DAY_OF_WEEK_IN_MONTH.");
      }

    if (isSet[AM_PM] && fields[AM_PM] != AM && fields[AM_PM] != PM)
      throw new IllegalArgumentException("Illegal AM_PM.");
    if (isSet[HOUR] && (fields[HOUR] < 0 || fields[HOUR] > 11))
      throw new IllegalArgumentException("Illegal HOUR.");
    if (isSet[HOUR_OF_DAY]
        && (fields[HOUR_OF_DAY] < 0 || fields[HOUR_OF_DAY] > 23))
      throw new IllegalArgumentException("Illegal HOUR_OF_DAY.");
    if (isSet[MINUTE] && (fields[MINUTE] < 0 || fields[MINUTE] > 59))
      throw new IllegalArgumentException("Illegal MINUTE.");
    if (isSet[SECOND] && (fields[SECOND] < 0 || fields[SECOND] > 59))
      throw new IllegalArgumentException("Illegal SECOND.");
    if (isSet[MILLISECOND]
        && (fields[MILLISECOND] < 0 || fields[MILLISECOND] > 999))
      throw new IllegalArgumentException("Illegal MILLISECOND.");
    if (isSet[ZONE_OFFSET]
        && (fields[ZONE_OFFSET] < -12 * 60 * 60 * 1000L
        || fields[ZONE_OFFSET] > 12 * 60 * 60 * 1000L))
      throw new IllegalArgumentException("Illegal ZONE_OFFSET.");
    if (isSet[DST_OFFSET]
        && (fields[DST_OFFSET] < -12 * 60 * 60 * 1000L
        || fields[DST_OFFSET] > 12 * 60 * 60 * 1000L))
      throw new IllegalArgumentException("Illegal DST_OFFSET.");
  }

  /**
   * Converts the time field values (<code>fields</code>) to
   * milliseconds since the epoch UTC (<code>time</code>).
   *
   * @throws IllegalArgumentException if any calendar fields
   *         are invalid.
   */
  protected synchronized void computeTime()
  {
    int millisInDay = 0;
    int era = fields[ERA];
    int year = fields[YEAR];
    int month = fields[MONTH];
    int day = fields[DAY_OF_MONTH];

    int minute = fields[MINUTE];
    int second = fields[SECOND];
    int millis = fields[MILLISECOND];
    int[] month_days = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
    int[] dayCount = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
    int hour = 0;

    if (! isLenient())
      nonLeniencyCheck();

    if (! isSet[MONTH] && (! isSet[DAY_OF_WEEK] || isSet[WEEK_OF_YEAR]))
      {
	// 5: YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
	if (isSet[WEEK_OF_YEAR])
	  {
	    int first = getFirstDayOfMonth(year, 0);
	    int offs = 1;
	    int daysInFirstWeek = getFirstDayOfWeek() - first;
	    if (daysInFirstWeek <= 0)
	      daysInFirstWeek += 7;

	    if (daysInFirstWeek < getMinimalDaysInFirstWeek())
	      offs += daysInFirstWeek;
	    else
	      offs -= 7 - daysInFirstWeek;
	    month = 0;
	    day = offs + 7 * (fields[WEEK_OF_YEAR] - 1);
	    offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek();

	    if (offs < 0)
	      offs += 7;
	    day += offs;
	  }
	else
	  {
	    // 4:  YEAR + DAY_OF_YEAR
	    month = 0;
	    day = fields[DAY_OF_YEAR];
	  }
      }
    else
      {
	if (isSet[DAY_OF_WEEK])
	  {
	    int first = getFirstDayOfMonth(year, month);

	    // 3: YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
	    if (isSet[DAY_OF_WEEK_IN_MONTH])
	      {
		if (fields[DAY_OF_WEEK_IN_MONTH] < 0)
		  {
		    month++;
		    first = getFirstDayOfMonth(year, month);
		    day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH]);
		  }
		else
		  day = 1 + 7 * (fields[DAY_OF_WEEK_IN_MONTH] - 1);

		int offs = fields[DAY_OF_WEEK] - first;
		if (offs < 0)
		  offs += 7;
		day += offs;
	      }
	    else
	      { // 2: YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
		int offs = 1;
		int daysInFirstWeek = getFirstDayOfWeek() - first;
		if (daysInFirstWeek <= 0)
		  daysInFirstWeek += 7;

		if (daysInFirstWeek < getMinimalDaysInFirstWeek())
		  offs += daysInFirstWeek;
		else
		  offs -= 7 - daysInFirstWeek;

		day = offs + 7 * (fields[WEEK_OF_MONTH] - 1);
		offs = fields[DAY_OF_WEEK] - getFirstDayOfWeek();
		if (offs < 0)
		  offs += 7;
		day += offs;
	      }
	  }

	// 1:  YEAR + MONTH + DAY_OF_MONTH
      }
    if (era == BC && year > 0)
      year = 1 - year;

    // rest of code assumes day/month/year set
    // should negative BC years be AD?
    // get the hour (but no check for validity)
    if (isSet[HOUR])
      {
	hour = fields[HOUR];
	if (fields[AM_PM] == PM)
	  hour += 12;
      }
    else
      hour = fields[HOUR_OF_DAY];

    // Read the era,year,month,day fields and convert as appropriate.
    // Calculate number of milliseconds into the day
    // This takes care of both h, m, s, ms over/underflows.
    long allMillis = (((hour * 60L) + minute) * 60L + second) * 1000L + millis;
    day += allMillis / (24 * 60 * 60 * 1000L);
    millisInDay = (int) (allMillis % (24 * 60 * 60 * 1000L));

    if (month < 0)
      {
	year += (int) month / 12;
	month = month % 12;
	if (month < 0)
	  {
	    month += 12;
	    year--;
	  }
      }
    if (month > 11)
      {
	year += (month / 12);
	month = month % 12;
      }

    month_days[1] = isLeapYear(year) ? 29 : 28;

    while (day <= 0)
      {
	if (month == 0)
	  {
	    year--;
	    month_days[1] = isLeapYear(year) ? 29 : 28;
	  }
	month = (month + 11) % 12;
	day += month_days[month];
      }
    while (day > month_days[month])
      {
	day -= (month_days[month]);
	month = (month + 1) % 12;
	if (month == 0)
	  {
	    year++;
	    month_days[1] = isLeapYear(year) ? 29 : 28;
	  }
      }

    // ok, by here we have valid day,month,year,era and millisinday
    int dayOfYear = dayCount[month] + day - 1; // (day starts on 1)
    if (isLeapYear(year) && month > 1)
      dayOfYear++;

    int relativeDay = (year - 1) * 365 + ((year - 1) >> 2) + dayOfYear
                      - EPOCH_DAYS; // gregorian days from 1 to epoch.
    int gregFactor = (int) Math.floor((double) (year - 1) / 400.)
                     - (int) Math.floor((double) (year - 1) / 100.);

    if ((relativeDay + gregFactor) * 60L * 60L * 24L * 1000L >= gregorianCutover)
      relativeDay += gregFactor;
    else
      relativeDay -= 2;

    time = relativeDay * (24 * 60 * 60 * 1000L) + millisInDay;

    // the epoch was a Thursday.
    int weekday = (int) (relativeDay + THURSDAY) % 7;
    if (weekday <= 0)
      weekday += 7;
    fields[DAY_OF_WEEK] = weekday;

    // Time zone corrections.
    TimeZone zone = getTimeZone();
    int rawOffset = isSet[ZONE_OFFSET] ? fields[ZONE_OFFSET]
                                       : zone.getRawOffset();

    int dstOffset = isSet[DST_OFFSET] ? fields[DST_OFFSET]
                                      : (zone.getOffset((year < 0) ? BC : AD,
                                                        (year < 0) ? 1 - year
                                                                   : year,
                                                        month, day, weekday,
                                                        millisInDay)
                                      - zone.getRawOffset());

    time -= rawOffset + dstOffset;

    isTimeSet = true;
  }

  /**
   * Get the linear day in days since the epoch, using the
   * Julian or Gregorian calendar as specified.  If you specify a
   * nonpositive year it is interpreted as BC as following: 0 is 1
   * BC, -1 is 2 BC and so on.
   *
   * @param year the year of the date.
   * @param dayOfYear the day of year of the date; 1 based.
   * @param gregorian <code>true</code>, if we should use the Gregorian rules.
   * @return the days since the epoch, may be negative.
   */
  private long getLinearDay(int year, int dayOfYear, boolean gregorian)
  {
    // The 13 is the number of days, that were omitted in the Gregorian
    // Calender until the epoch.
    // We shift right by 2 instead of dividing by 4, to get correct
    // results for negative years (and this is even more efficient).
    long julianDay = (year - 1) * 365L + ((year - 1) >> 2) + (dayOfYear - 1)
                     - EPOCH_DAYS; // gregorian days from 1 to epoch.

    if (gregorian)
      {
	// subtract the days that are missing in gregorian calendar
	// with respect to julian calendar.
	//
	// Okay, here we rely on the fact that the gregorian
	// calendar was introduced in the AD era.  This doesn't work
	// with negative years.
	//
	// The additional leap year factor accounts for the fact that
	// a leap day is not seen on Jan 1 of the leap year.
	int gregOffset = (int) Math.floor((double) (year - 1) / 400.)
	                 - (int) Math.floor((double) (year - 1) / 100.);

	return julianDay + gregOffset;
      }
    else
      julianDay -= 2;
    return julianDay;
  }

  /**
   * Converts the given linear day into era, year, month,
   * day_of_year, day_of_month, day_of_week, and writes the result
   * into the fields array.
   *
   * @param day the linear day.
   * @param gregorian true, if we should use Gregorian rules.
   */
  private void calculateDay(int[] fields, long day, boolean gregorian)
  {
    // the epoch was a Thursday.
    int weekday = (int) (day + THURSDAY) % 7;
    if (weekday <= 0)
      weekday += 7;
    fields[DAY_OF_WEEK] = weekday;

    // get a first approximation of the year.  This may be one 
    // year too big.
    int year = 1970
               + (int) (gregorian
                        ? ((day - 100L) * 400L) / (365L * 400L + 100L - 4L
                        + 1L) : ((day - 100L) * 4L) / (365L * 4L + 1L));
    if (day >= 0)
      year++;

    long firstDayOfYear = getLinearDay(year, 1, gregorian);

    // Now look in which year day really lies.
    if (day < firstDayOfYear)
      {
	year--;
	firstDayOfYear = getLinearDay(year, 1, gregorian);
      }

    day -= firstDayOfYear - 1; // day of year,  one based.

    fields[DAY_OF_YEAR] = (int) day;
    if (year <= 0)
      {
	fields[ERA] = BC;
	fields[YEAR] = 1 - year;
      }
    else
      {
	fields[ERA] = AD;
	fields[YEAR] = year;
      }

    int leapday = isLeapYear(year) ? 1 : 0;
    if (day <= 31 + 28 + leapday)
      {
	fields[MONTH] = (int) day / 32; // 31->JANUARY, 32->FEBRUARY
	fields[DAY_OF_MONTH] = (int) day - 31 * fields[MONTH];
      }
    else
      {
	// A few more magic formulas
	int scaledDay = ((int) day - leapday) * 5 + 8;
	fields[MONTH] = scaledDay / (31 + 30 + 31 + 30 + 31);
	fields[DAY_OF_MONTH] = (scaledDay % (31 + 30 + 31 + 30 + 31)) / 5 + 1;
      }
  }

  /**
   * Converts the milliseconds since the epoch UTC
   * (<code>time</code>) to time fields
   * (<code>fields</code>).
   */
  protected synchronized void computeFields()
  {
    boolean gregorian = (time >= gregorianCutover);

    TimeZone zone = getTimeZone();
    fields[ZONE_OFFSET] = zone.getRawOffset();
    long localTime = time + fields[ZONE_OFFSET];

    long day = localTime / (24 * 60 * 60 * 1000L);
    int millisInDay = (int) (localTime % (24 * 60 * 60 * 1000L));

    if (millisInDay < 0)
      {
	millisInDay += (24 * 60 * 60 * 1000);
	day--;
      }

    calculateDay(fields, day, gregorian);
    fields[DST_OFFSET] = zone.getOffset(fields[ERA], fields[YEAR],
                                        fields[MONTH], fields[DAY_OF_MONTH],
                                        fields[DAY_OF_WEEK], millisInDay)
                         - fields[ZONE_OFFSET];

    millisInDay += fields[DST_OFFSET];
    if (millisInDay >= 24 * 60 * 60 * 1000)
      {
	millisInDay -= 24 * 60 * 60 * 1000;
	calculateDay(fields, ++day, gregorian);
      }

    fields[DAY_OF_WEEK_IN_MONTH] = (fields[DAY_OF_MONTH] + 6) / 7;

    // which day of the week are we (0..6), relative to getFirstDayOfWeek
    int relativeWeekday = (7 + fields[DAY_OF_WEEK] - getFirstDayOfWeek()) % 7;

    // which day of the week is the first of this month?
    // nb 35 is the smallest multiple of 7 that ensures that
    // the left hand side of the modulo operator is positive.
    int relativeWeekdayOfFirst = (relativeWeekday - fields[DAY_OF_MONTH]
				  + 1 + 35) % 7;

    // which week of the month is the first of this month in?
    int minDays = getMinimalDaysInFirstWeek();
    int weekOfFirst = ((7 - relativeWeekdayOfFirst) >= minDays) ? 1 : 0;

    // which week of the month is this day in?
    fields[WEEK_OF_MONTH] = (fields[DAY_OF_MONTH]
			     + relativeWeekdayOfFirst - 1) / 7 + weekOfFirst;

    int weekOfYear = (fields[DAY_OF_YEAR] - relativeWeekday + 6) / 7;

    // Do the Correction: getMinimalDaysInFirstWeek() is always in the 
    // first week.
    int firstWeekday = (7 + getWeekDay(fields[YEAR], minDays)
                       - getFirstDayOfWeek()) % 7;
    if (minDays - firstWeekday < 1)
      weekOfYear++;
    fields[WEEK_OF_YEAR] = weekOfYear;

    int hourOfDay = millisInDay / (60 * 60 * 1000);
    fields[AM_PM] = (hourOfDay < 12) ? AM : PM;
    int hour = hourOfDay % 12;
    fields[HOUR] = hour;
    fields[HOUR_OF_DAY] = hourOfDay;
    millisInDay %= (60 * 60 * 1000);
    fields[MINUTE] = millisInDay / (60 * 1000);
    millisInDay %= (60 * 1000);
    fields[SECOND] = millisInDay / (1000);
    fields[MILLISECOND] = millisInDay % 1000;

    areFieldsSet = isSet[ERA] = isSet[YEAR] = isSet[MONTH] = isSet[WEEK_OF_YEAR] = isSet[WEEK_OF_MONTH] = isSet[DAY_OF_MONTH] = isSet[DAY_OF_YEAR] = isSet[DAY_OF_WEEK] = isSet[DAY_OF_WEEK_IN_MONTH] = isSet[AM_PM] = isSet[HOUR] = isSet[HOUR_OF_DAY] = isSet[MINUTE] = isSet[SECOND] = isSet[MILLISECOND] = isSet[ZONE_OFFSET] = isSet[DST_OFFSET] = true;
  }
  
  /**
   * Return a hash code for this object, following the general contract
   * specified by {@link Object#hashCode()}.
   * @return the hash code
   */
  public int hashCode()
  {
    int val = (int) ((gregorianCutover >>> 32) ^ (gregorianCutover & 0xffffffff));
    return super.hashCode() ^ val;
  }

  /**
   * Compares the given calendar with this.  An object, o, is
   * equivalent to this if it is also a <code>GregorianCalendar</code>
   * with the same time since the epoch under the same conditions
   * (same change date and same time zone).
   *
   * @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 necessarily have the same fields).
   * @throws IllegalArgumentException if one of the fields
   *         <code>ZONE_OFFSET</code> or <code>DST_OFFSET</code> is
   *         specified, if an unknown field is specified or if one
   *         of the calendar fields receives an illegal value when
   *         leniancy is not enabled.
   */
  public boolean equals(Object o)
  {
    if (! (o instanceof GregorianCalendar))
      return false;

    GregorianCalendar cal = (GregorianCalendar) o;
    return (cal.gregorianCutover == gregorianCutover
            && super.equals(o));
  }

  /**
   * 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 one of the time field constants.
   * @param amount the amount of time to add.
   * @exception IllegalArgumentException if <code>field</code> is
   *   <code>ZONE_OFFSET</code>, <code>DST_OFFSET</code>, or invalid; or
   *   if <code>amount</code> contains an out-of-range value and the calendar
   *   is not in lenient mode.
   */
  public void add(int field, int amount)
  {
    switch (field)
      {
      case YEAR:
	complete();
	fields[YEAR] += amount;
	isTimeSet = false;
	break;
      case MONTH:
	complete();
	int months = fields[MONTH] + amount;
	fields[YEAR] += months / 12;
	fields[MONTH] = months % 12;
	if (fields[MONTH] < 0)
	  {
	    fields[MONTH] += 12;
	    fields[YEAR]--;
	  }
	int maxDay = getActualMaximum(DAY_OF_MONTH);
	if (fields[DAY_OF_MONTH] > maxDay)
	  fields[DAY_OF_MONTH] = maxDay;
	set(YEAR, fields[YEAR]);
	set(MONTH, fields[MONTH]);
	break;
      case DAY_OF_MONTH:
      case DAY_OF_YEAR:
      case DAY_OF_WEEK:
	if (! isTimeSet)
	  computeTime();
	time += amount * (24 * 60 * 60 * 1000L);
	areFieldsSet = false;
	break;
      case WEEK_OF_YEAR:
      case WEEK_OF_MONTH:
      case DAY_OF_WEEK_IN_MONTH:
	if (! isTimeSet)
	  computeTime();
	time += amount * (7 * 24 * 60 * 60 * 1000L);
	areFieldsSet = false;
	break;
      case AM_PM:
	if (! isTimeSet)
	  computeTime();
	time += amount * (12 * 60 * 60 * 1000L);
	areFieldsSet = false;
	break;
      case HOUR:
      case HOUR_OF_DAY:
	if (! isTimeSet)
	  computeTime();
	time += amount * (60 * 60 * 1000L);
	areFieldsSet = false;
	break;
      case MINUTE:
	if (! isTimeSet)
	  computeTime();
	time += amount * (60 * 1000L);
	areFieldsSet = false;
	break;
      case SECOND:
	if (! isTimeSet)
	  computeTime();
	time += amount * (1000L);
	areFieldsSet = false;
	break;
      case MILLISECOND:
	if (! isTimeSet)
	  computeTime();
	time += amount;
	areFieldsSet = false;
	break;
      case ZONE_OFFSET:
      case DST_OFFSET:default:
	throw new IllegalArgumentException("Invalid or unknown field");
      }
  }

  /**
   * 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.
   *
   * <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.
   * This requires lenient settings.
   *
   * @param field the time field. One of the time field constants.
   * @param up the direction, true for up, false for down.
   * @throws IllegalArgumentException if one of the fields
   *         <code>ZONE_OFFSET</code> or <code>DST_OFFSET</code> is
   *         specified, if an unknown field is specified or if one
   *         of the calendar fields receives an illegal value when
   *         leniancy is not enabled.
   */
  public void roll(int field, boolean up)
  {
    roll(field, up ? 1 : -1);
  }

  /**
   * Checks that the fields are still within their legal bounds,
   * following use of the <code>roll()</code> method.
   *
   * @param field the field to check.
   * @param delta multipler for alterations to the <code>time</code>.
   * @see #roll(int, boolean)
   * @see #roll(int, int)
   */
  private void cleanUpAfterRoll(int field, int delta)
  {
    switch (field)
      {
      case ERA:
      case YEAR:
      case MONTH:
	// check that day of month is still in correct range
	if (fields[DAY_OF_MONTH] > getActualMaximum(DAY_OF_MONTH))
	  fields[DAY_OF_MONTH] = getActualMaximum(DAY_OF_MONTH);
	isTimeSet = false;
	isSet[WEEK_OF_MONTH] = false;
	isSet[DAY_OF_WEEK] = false;
	isSet[DAY_OF_WEEK_IN_MONTH] = false;
	isSet[DAY_OF_YEAR] = false;
	isSet[WEEK_OF_YEAR] = false;
	break;
      case DAY_OF_MONTH:
	isSet[WEEK_OF_MONTH] = false;
	isSet[DAY_OF_WEEK] = false;
	isSet[DAY_OF_WEEK_IN_MONTH] = false;
	isSet[DAY_OF_YEAR] = false;
	isSet[WEEK_OF_YEAR] = false;
	time += delta * (24 * 60 * 60 * 1000L);
	break;
      case WEEK_OF_MONTH:
	isSet[DAY_OF_MONTH] = false;
	isSet[DAY_OF_WEEK_IN_MONTH] = false;
	isSet[DAY_OF_YEAR] = false;
	isSet[WEEK_OF_YEAR] = false;
	time += delta * (7 * 24 * 60 * 60 * 1000L);
	break;
      case DAY_OF_WEEK_IN_MONTH:
	isSet[DAY_OF_MONTH] = false;
	isSet[WEEK_OF_MONTH] = false;
	isSet[DAY_OF_YEAR] = false;
	isSet[WEEK_OF_YEAR] = false;
	time += delta * (7 * 24 * 60 * 60 * 1000L);
	break;
      case DAY_OF_YEAR:
	isSet[MONTH] = false;
	isSet[DAY_OF_MONTH] = false;
	isSet[WEEK_OF_MONTH] = false;
	isSet[DAY_OF_WEEK_IN_MONTH] = false;
	isSet[DAY_OF_WEEK] = false;
	isSet[WEEK_OF_YEAR] = false;
	time += delta * (24 * 60 * 60 * 1000L);
	break;
      case WEEK_OF_YEAR:
	isSet[MONTH] = false;
	isSet[DAY_OF_MONTH] = false;
	isSet[WEEK_OF_MONTH] = false;
	isSet[DAY_OF_WEEK_IN_MONTH] = false;
	isSet[DAY_OF_YEAR] = false;
	time += delta * (7 * 24 * 60 * 60 * 1000L);
	break;
      case AM_PM:
	isSet[HOUR_OF_DAY] = false;
	time += delta * (12 * 60 * 60 * 1000L);
	break;
      case HOUR:
	isSet[HOUR_OF_DAY] = false;
	time += delta * (60 * 60 * 1000L);
	break;
      case HOUR_OF_DAY:
	isSet[HOUR] = false;
	isSet[AM_PM] = false;
	time += delta * (60 * 60 * 1000L);
	break;
      case MINUTE:
	time += delta * (60 * 1000L);
	break;
      case SECOND:
	time += delta * (1000L);
	break;
      case MILLISECOND:
	time += delta;
	break;
      }
  }

  /**
   * Rolls the specified time field by the given amount.  This means
   * add amount 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 and vice versa for negative amounts.
   *
   * <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 corrected to June, 30.
   *
   * @param field the time field. One of the time field constants.
   * @param amount the amount by which we should roll.
   * @throws IllegalArgumentException if one of the fields
   *         <code>ZONE_OFFSET</code> or <code>DST_OFFSET</code> is
   *         specified, if an unknown field is specified or if one
   *         of the calendar fields receives an illegal value when
   *         leniancy is not enabled.
   */
  public void roll(int field, int amount)
  {
    switch (field)
      {
      case DAY_OF_WEEK:
	// day of week is special: it rolls automatically
	add(field, amount);
	return;
      case ZONE_OFFSET:
      case DST_OFFSET:
	throw new IllegalArgumentException("Can't roll time zone");
      }
    complete();
    int min = getActualMinimum(field);
    int range = getActualMaximum(field) - min + 1;
    int oldval = fields[field];
    int newval = (oldval - min + range + amount) % range + min;
    if (newval < min)
      newval += range;
    fields[field] = newval;
    cleanUpAfterRoll(field, newval - oldval);
  }

  /**
   * The minimum values for the calendar fields.
   */
  private static final int[] minimums = 
                                        {
                                          BC, 1, 0, 0, 1, 1, 1, SUNDAY, 1, AM,
                                          1, 0, 0, 0, 0, -(12 * 60 * 60 * 1000),
                                          0
                                        };

  /**
   * The maximum values for the calendar fields.
   */
  private static final int[] maximums = 
                                        {
                                          AD, 5000000, 11, 53, 6, 31, 366,
                                          SATURDAY, 5, PM, 12, 23, 59, 59, 999,
                                          +(12 * 60 * 60 * 1000),
                                          (12 * 60 * 60 * 1000)
                                        };

  /**
   * Gets the smallest value that is allowed for the specified field.
   *
   * @param field one of the time field constants.
   * @return the smallest value for the specified field.
   */
  public int getMinimum(int field)
  {
    return minimums[field];
  }

  /**
   * Gets the biggest value that is allowed for the specified field.
   *
   * @param field one of the time field constants.
   * @return the biggest value.
   */
  public int getMaximum(int field)
  {
    return maximums[field];
  }

  /**
   * Gets the greatest minimum value that is allowed for the specified field.
   * This is the largest value returned by the <code>getActualMinimum(int)</code>
   * method.
   *
   * @param field the time field. One of the time field constants.
   * @return the greatest minimum value.
   * @see #getActualMinimum(int)
   */
  public int getGreatestMinimum(int field)
  {
    if (field == WEEK_OF_YEAR)
      return 1;
    return minimums[field];
  }

  /**
   * Gets the smallest maximum value that is allowed for the
   * specified field.  This is the smallest value returned
   * by the <code>getActualMaximum(int)</code>.  For example,
   * this is 28 for DAY_OF_MONTH (as all months have at least
   * 28 days).
   *
   * @param field the time field. One of the time field constants.
   * @return the least maximum value.
   * @see #getActualMaximum(int)
   * @since 1.2
   */
  public int getLeastMaximum(int field)
  {
    switch (field)
      {
      case WEEK_OF_YEAR:
	return 52;
      case DAY_OF_MONTH:
	return 28;
      case DAY_OF_YEAR:
	return 365;
      case DAY_OF_WEEK_IN_MONTH:
      case WEEK_OF_MONTH:
	return 4;
      default:
	return maximums[field];
      }
  }

  /**
   * Gets the actual minimum value that is allowed for the specified field.
   * This value is dependent on the values of the other fields.  Note that
   * this calls <code>complete()</code> if not enough fields are set.  This
   * can have ugly side effects.  The value given depends on the current
   * time used by this instance.
   *
   * @param field the time field. One of the time field constants.
   * @return the actual minimum value.
   * @since 1.2
   */
  public int getActualMinimum(int field)
  {
    if (field == WEEK_OF_YEAR)
      {
	int min = getMinimalDaysInFirstWeek();
	if (min == 0)
	  return 1;
	if (! areFieldsSet || ! isSet[ERA] || ! isSet[YEAR])
	  complete();

	int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR];
	int weekday = getWeekDay(year, min);
	if ((7 + weekday - getFirstDayOfWeek()) % 7 >= min - 1)
	  return 1;
	return 0;
      }
    return minimums[field];
  }

  /**
   * Gets the actual maximum value that is allowed for the specified field.
   * This value is dependent on the values of the other fields.  Note that
   * this calls <code>complete()</code> if not enough fields are set.  This
   * can have ugly side effects.  The value given depends on the current time
   * used by this instance; thus, leap years have a maximum day of month value of
   * 29, rather than 28.
   *
   * @param field the time field. One of the time field constants.
   * @return the actual maximum value.
   */
  public int getActualMaximum(int field)
  {
    switch (field)
      {
      case WEEK_OF_YEAR:
        {
	  if (! areFieldsSet || ! isSet[ERA] || ! isSet[YEAR])
	    complete();

	  // This is wrong for the year that contains the gregorian change.
	  // I.e it gives the weeks in the julian year or in the gregorian
	  // year in that case.
	  int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR];
	  int lastDay = isLeapYear(year) ? 366 : 365;
	  int weekday = getWeekDay(year, lastDay);
	  int week = (lastDay + 6 - (7 + weekday - getFirstDayOfWeek()) % 7) / 7;

	  int minimalDays = getMinimalDaysInFirstWeek();
	  int firstWeekday = getWeekDay(year, minimalDays);
	  /*
	   * Is there a set of days at the beginning of the year, before the
	   * first day of the week, equal to or greater than the minimum number
	   * of days required in the first week?
	   */
	  if (minimalDays - (7 + firstWeekday - getFirstDayOfWeek()) % 7 < 1)
	    return week + 1; /* Add week 1: firstWeekday through to firstDayOfWeek */
        }
      case DAY_OF_MONTH:
        {
	  if (! areFieldsSet || ! isSet[MONTH])
	    complete();
	  int month = fields[MONTH];

	  // If you change this, you should also change 
	  // SimpleTimeZone.getDaysInMonth();
	  if (month == FEBRUARY)
	    {
	      if (! isSet[YEAR] || ! isSet[ERA])
		complete();
	      int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR];
	      return isLeapYear(year) ? 29 : 28;
	    }
	  else if (month < AUGUST)
	    return 31 - (month & 1);
	  else
	    return 30 + (month & 1);
        }
      case DAY_OF_YEAR:
        {
	  if (! areFieldsSet || ! isSet[ERA] || ! isSet[YEAR])
	    complete();
	  int year = fields[ERA] == AD ? fields[YEAR] : 1 - fields[YEAR];
	  return isLeapYear(year) ? 366 : 365;
        }
      case DAY_OF_WEEK_IN_MONTH:
        {
	  // This is wrong for the month that contains the gregorian change.
	  int daysInMonth = getActualMaximum(DAY_OF_MONTH);

	  // That's black magic, I know
	  return (daysInMonth - (fields[DAY_OF_MONTH] - 1) % 7 + 6) / 7;
        }
      case WEEK_OF_MONTH:
        {
	  int daysInMonth = getActualMaximum(DAY_OF_MONTH);
	  int weekday = (daysInMonth - fields[DAY_OF_MONTH]
	                + fields[DAY_OF_WEEK] - SUNDAY) % 7 + SUNDAY;
	  return (daysInMonth + 6 - (7 + weekday - getFirstDayOfWeek()) % 7) / 7;
        }
      default:
	return maximums[field];
      }
  }
}
