[kaffe] CVS kaffe (robilad): Resynced with GNU Classpath: calendar fixes

Kaffe CVS cvs-commits at kaffe.org
Sat Jun 11 12:30:53 PDT 2005


PatchSet 6623 
Date: 2005/06/11 19:22:59
Author: robilad
Branch: HEAD
Tag: (none) 
Log:
Resynced with GNU Classpath: calendar fixes

Members: 
	ChangeLog:1.4149->1.4150 
	libraries/javalib/java/util/Calendar.java:INITIAL->1.36 

Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.4149 kaffe/ChangeLog:1.4150
--- kaffe/ChangeLog:1.4149	Sat Jun 11 19:11:33 2005
+++ kaffe/ChangeLog	Sat Jun 11 19:22:59 2005
@@ -2,6 +2,15 @@
 
 	Resynced with GNU Classpath.
 
+	2005-06-01  Sven de Marothy  <sven at physto.se>
+
+	* java/util/GregorianCalendar.java
+	(setTimeInMillis): Recompute time fields.
+
+2005-06-11  Dalibor Topic  <robilad at kaffe.org>
+
+	Resynced with GNU Classpath.
+
 	2005-06-01  Roman Kennke  <roman at kennke.org>
 
 	* javax/swing/plaf/basic/BasicFileChooserUI.java
===================================================================
Checking out kaffe/libraries/javalib/java/util/Calendar.java
RCS:  /home/cvs/kaffe/kaffe/libraries/javalib/java/util/Calendar.java,v
VERS: 1.36
***************
--- /dev/null	Sun Aug  4 19:57:58 2002
+++ kaffe/libraries/javalib/java/util/Calendar.java	Sat Jun 11 19:30:51 2005
@@ -0,0 +1,1278 @@
+/* Calendar.java --
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004, 2005  Free Software Foundation, Inc.
+
+This file is part of GNU Classpath.
+
+GNU Classpath is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+GNU Classpath is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GNU Classpath; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 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 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;
+
+/**
+ * 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.
+ *
+ * @see Date
+ * @see GregorianCalendar
+ * @see TimeZone
+ * @see java.text.DateFormat
+ */
+public abstract class Calendar implements Serializable, Cloneable
+{
+  /**
+   * 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;
+
+  /**
+   * 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());
+  }
+
+  /**
+   * 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" };
+
+    ResourceBundle rb = getBundle(locale);
+    String min = (String) rb.getObject("minNumberOfDaysInFirstWeek");
+    String first = (String) rb.getObject("firstDayOfWeek");
+    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.
+   */
+  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.
+   */
+  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.
+   */
+  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 HashMap cache = new HashMap();
+
+  /** 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.
+   * @param locale a locale.
+   */
+  public static synchronized Calendar getInstance(TimeZone zone, Locale locale)
+  {
+    Class calendarClass = (Class) 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.
+   */
+  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
+                       };
+    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
+   * @return true if the specified field has a value.
+   */
+  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)
+  {
+    return (o instanceof Calendar)
+           && getTimeInMillis() == ((Calendar) o).getTimeInMillis();
+  }
+
+  /**
+   * 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();
+    return (int) ((time & 0xffffffffL) ^ (time >> 32));
+  }
+
+  /**
+   * 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

*** Patch too long, truncated ***



More information about the kaffe mailing list