home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / VCAFE.3.0A / Main.bin / Calendar.java < prev    next >
Text File  |  1998-09-22  |  41KB  |  1,118 lines

  1. /*
  2.  * @(#)Calendar.java    1.32 98/02/02
  3.  *
  4.  * (C) Copyright Taligent, Inc. 1996-1997 - All Rights Reserved
  5.  * (C) Copyright IBM Corp. 1996-1997 - All Rights Reserved
  6.  *
  7.  * Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
  8.  *
  9.  *   The original version of this source code and documentation is copyrighted
  10.  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
  11.  * materials are provided under terms of a License Agreement between Taligent
  12.  * and Sun. This technology is protected by multiple US and International
  13.  * patents. This notice and attribution to Taligent may not be removed.
  14.  *   Taligent is a registered trademark of Taligent, Inc.
  15.  *
  16.  * Permission to use, copy, modify, and distribute this software
  17.  * and its documentation for NON-COMMERCIAL purposes and without
  18.  * fee is hereby granted provided that this copyright notice
  19.  * appears in all copies. Please refer to the file "copyright.html"
  20.  * for further important copyright and licensing information.
  21.  *
  22.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  23.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  24.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  25.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  26.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  27.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  28.  *
  29.  */
  30.  
  31. package java.util;
  32. import java.io.IOException;
  33. import java.io.ObjectInputStream;
  34. import java.io.ObjectOutputStream;
  35. import java.io.Serializable;
  36. import java.text.DateFormat;
  37.  
  38. /**
  39.  * <code>Calendar</code> is an abstract base class for converting between
  40.  * a <code>Date</code> object and a set of integer fields such as
  41.  * <code>YEAR</code>, <code>MONTH</code>, <code>DAY</code>, <code>HOUR</code>,
  42.  * and so on. (A <code>Date</code> object represents a specific instant in
  43.  * time with millisecond precision. See
  44.  * <a href="java.util.Date.html"><code>java.util.Date</code></a>
  45.  * for information about the <code>Date</code> class.)
  46.  *
  47.  * <p>
  48.  * Subclasses of <code>Calendar</code> interpret a <code>Date</code>
  49.  * according to the rules of a specific calendar system. The JDK
  50.  * provides one concrete subclass of <code>Calendar</code>:
  51.  * <code>GregorianCalendar</code>. Future subclasses could represent
  52.  * the various types of lunar calendars in use in many parts of the world.
  53.  *
  54.  * <p>
  55.  * Like other locale-sensitive classes, <code>Calendar</code> provides a
  56.  * class method, <code>getInstance</code>, for getting a generally useful
  57.  * object of this type. <code>Calendar</code>'s <code>getInstance</code> method
  58.  * returns a <code>GregorianCalendar</code> object whose
  59.  * time fields have been initialized with the current date and time:
  60.  * <blockquote>
  61.  * <pre>
  62.  * Calendar rightNow = Calendar.getInstance();
  63.  * </pre>
  64.  * </blockquote>
  65.  *
  66.  * <p>
  67.  * A <code>Calendar</code> object can produce all the time field values
  68.  * needed to implement the date-time formatting for a particular language
  69.  * and calendar style (for example, Japanese-Gregorian, Japanese-Traditional).
  70.  *
  71.  * <p>
  72.  * When computing a <code>Date</code> from time fields, two special circumstances
  73.  * may arise: there may be insufficient information to compute the
  74.  * <code>Date</code> (such as only year and month but no day in the month),
  75.  * or there may be inconsistent information (such as "Tuesday, July 15, 1996"
  76.  * -- July 15, 1996 is actually a Monday).
  77.  *
  78.  * <p>
  79.  * <strong>Insufficient information.</strong> The calendar will use default
  80.  * information to specify the missing fields. This may vary by calendar; for
  81.  * the Gregorian calendar, the default for a field is the same as that of the
  82.  * start of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc.
  83.  *
  84.  * <p>
  85.  * <strong>Inconsistent information.</strong> If fields conflict, the calendar
  86.  * will give preference to fields set more recently. For example, when
  87.  * determining the day, the calendar will look for one of the following
  88.  * combinations of fields.  The most recent combination, as determined by the
  89.  * most recently set single field, will be used.
  90.  *
  91.  * <blockquote>
  92.  * <pre>
  93.  * MONTH + DAY_OF_MONTH
  94.  * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
  95.  * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
  96.  * DAY_OF_YEAR
  97.  * DAY_OF_WEEK + WEEK_OF_YEAR
  98.  * </pre>
  99.  * </blockquote>
  100.  *
  101.  * For the time of day:
  102.  *
  103.  * <blockquote>
  104.  * <pre>
  105.  * HOUR_OF_DAY
  106.  * AM_PM + HOUR
  107.  * </pre>
  108.  * </blockquote>
  109.  *
  110.  * <p>
  111.  * <strong>Note:</strong> for some non-Gregorian calendars, different
  112.  * fields may be necessary for complete disambiguation. For example, a full
  113.  * specification of the historial Arabic astronomical calendar requires year,
  114.  * month, day-of-month <em>and</em> day-of-week in some cases.
  115.  *
  116.  * <p>
  117.  * <strong>Note:</strong> There are certain possible ambiguities in
  118.  * interpretation of certain singular times, which are resolved in the
  119.  * following ways:
  120.  * <ol>
  121.  *     <li> 24:00:00 "belongs" to the following day. That is,
  122.  *          23:59 on Dec 31, 1969 < 24:00 on Jan 1, 1970 < 24:01:00 on Jan 1, 1970
  123.  *
  124.  *     <li> Although historically not precise, midnight also belongs to "am",
  125.  *          and noon belongs to "pm", so on the same day,
  126.  *          12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm
  127.  * </ol>
  128.  *
  129.  * <p>
  130.  * The date or time format strings are not part of the definition of a
  131.  * calendar, as those must be modifiable or overridable by the user at
  132.  * runtime. Use <a href="java.text.DateFormat.html">java.text.DateFormat</a>
  133.  * to format dates.
  134.  *
  135.  * <p>
  136.  * <code>Calendar</code> provides an API for field "rolling", where fields
  137.  * can be incremented or decremented, but wrap around. For example, rolling the
  138.  * month up in the date "September 12, 1996" results in "October 12, 1996".
  139.  *
  140.  * <p>
  141.  * <code>Calendar</code> also provides a date arithmetic function for
  142.  * adding the specified (signed) amount of time to a particular time field.
  143.  * For example, subtracting 5 days from the date "September 12, 1996" results
  144.  * in "September 7, 1996".
  145.  *
  146.  * @see          Date
  147.  * @see          GregorianCalendar
  148.  * @see          TimeZone
  149.  * @see          java.text.DateFormat
  150.  * @version      1.17 06 Jan 1997
  151.  * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu
  152.  */
  153. public abstract class Calendar implements Serializable, Cloneable {
  154.  
  155.     // Data flow in Calendar
  156.     // ---------------------
  157.  
  158.     // The current time is represented in two ways by Calendar: as UTC
  159.     // milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local
  160.     // fields such as MONTH, HOUR, AM_PM, etc.  It is possible to compute the
  161.     // millis from the fields, and vice versa.  The data needed to do this
  162.     // conversion is encapsulated by a TimeZone object owned by the Calendar.
  163.     // The data provided by the TimeZone object may also be overridden if the
  164.     // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
  165.     // keeps track of what information was most recently set by the caller, and
  166.     // uses that to compute any other information as needed.
  167.  
  168.     // If the user sets the fields using set(), the data flow is as follows.
  169.     // This is implemented by the Calendar subclass's computeTime() method.
  170.     // During this process, certain fields may be ignored.  The disambiguation
  171.     // algorithm for resolving which fields to pay attention to is described
  172.     // above.
  173.  
  174.     //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
  175.     //           |
  176.     //           | Using Calendar-specific algorithm
  177.     //           V
  178.     //   local standard millis
  179.     //           |
  180.     //           | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
  181.     //           V
  182.     //   UTC millis (in time data member)
  183.  
  184.     // If the user sets the UTC millis using setTime(), the data flow is as
  185.     // follows.  This is implemented by the Calendar subclass's computeFields()
  186.     // method.
  187.  
  188.     //   UTC millis (in time data member)
  189.     //           |
  190.     //           | Using TimeZone getOffset()
  191.     //           V
  192.     //   local standard millis
  193.     //           |
  194.     //           | Using Calendar-specific algorithm
  195.     //           V
  196.     //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
  197.  
  198.     // In general, a round trip from fields, through local and UTC millis, and
  199.     // back out to fields is made when necessary.  This is implemented by the
  200.     // complete() method.  Resolving a partial set of fields into a UTC millis
  201.     // value allows all remaining fields to be generated from that value.  If
  202.     // the Calendar is lenient, the fields are also renormalized to standard
  203.     // ranges when they are regenerated.
  204.  
  205.     /**
  206.      * Useful constant for date and time. Used in time fields.
  207.      * ERA is calendar specific.
  208.      */
  209.     public final static int ERA = 0;
  210.     /**
  211.      * Useful constant for date and time. Used in time fields.
  212.      */
  213.     public final static int YEAR = 1;
  214.     /**
  215.      * Useful constant for date and time. Used in time fields.
  216.      */
  217.     public final static int MONTH = 2;
  218.     /**
  219.      * Useful constant for date and time. Used in time fields.
  220.      */
  221.     public final static int WEEK_OF_YEAR = 3;
  222.     /**
  223.      * Useful constant for date and time. Used in time fields.
  224.      */
  225.     public final static int WEEK_OF_MONTH = 4;
  226.     /**
  227.      * Useful constant for date and time. Used in time fields.
  228.      * This is a synonym for DAY_OF_MONTH.
  229.      */
  230.     public final static int DATE = 5;
  231.     /**
  232.      * Useful constant for date and time. Used in time fields.
  233.      * This is a synonym for DATE.
  234.      */
  235.     public final static int DAY_OF_MONTH = 5;
  236.     /**
  237.      * Useful constant for date and time. Used in time fields.
  238.      */
  239.     public final static int DAY_OF_YEAR = 6;
  240.     /**
  241.      * Useful constant for date and time. Used in time fields.
  242.      */
  243.     public final static int DAY_OF_WEEK = 7;
  244.     /**
  245.      * Useful constant for date and time. Used in time fields.
  246.      */
  247.     public final static int DAY_OF_WEEK_IN_MONTH = 8;
  248.     /**
  249.      * Useful constant for date and time. Used in time fields.
  250.      */
  251.     public final static int AM_PM = 9;
  252.     /**
  253.      * Useful constant for date and time. Used in time fields.
  254.      * HOUR is used for the 12-hour clock.
  255.      */
  256.     public final static int HOUR = 10;
  257.     /**
  258.      * Useful constant for date and time. Used in time fields.
  259.      * HOUR_OF_DAY is used for the 24-hour clock.
  260.      */
  261.     public final static int HOUR_OF_DAY = 11;
  262.     /**
  263.      * Useful constant for date and time. Used in time fields.
  264.      */
  265.     public final static int MINUTE = 12;
  266.     /**
  267.      * Useful constant for date and time. Used in time fields.
  268.      */
  269.     public final static int SECOND = 13;
  270.     /**
  271.      * Useful constant for date and time. Used in time fields.
  272.      */
  273.     public final static int MILLISECOND = 14;
  274.     /**
  275.      * Useful constant for date and time. Used in time fields.
  276.      */
  277.     public final static int ZONE_OFFSET = 15;
  278.     /**
  279.      * Useful constant for date and time. Used in time fields.
  280.      */
  281.     public final static int DST_OFFSET = 16;
  282.     /**
  283.      * Useful constant for date and time.
  284.      * FIELD_COUNT is used for the time field array creation.
  285.      */
  286.     public final static int FIELD_COUNT = 17;
  287.  
  288.     /**
  289.      * Useful constant for days of week. Used in GregorianCalendar.
  290.      */
  291.     public final static int SUNDAY = 1;
  292.     /**
  293.      * Useful constant for days of week. Used in GregorianCalendar.
  294.      */
  295.     public final static int MONDAY = 2;
  296.     /**
  297.      * Useful constant for days of week. Used in GregorianCalendar.
  298.      */
  299.     public final static int TUESDAY = 3;
  300.     /**
  301.      * Useful constant for days of week. Used in GregorianCalendar.
  302.      */
  303.     public final static int WEDNESDAY = 4;
  304.     /**
  305.      * Useful constant for days of week. Used in GregorianCalendar.
  306.      */
  307.     public final static int THURSDAY = 5;
  308.     /**
  309.      * Useful constant for days of week. Used in GregorianCalendar.
  310.      */
  311.     public final static int FRIDAY = 6;
  312.     /**
  313.      * Useful constant for days of week. Used in GregorianCalendar.
  314.      */
  315.     public final static int SATURDAY = 7;
  316.     /**
  317.      * Useful constant for month. Used in GregorianCalendar.
  318.      * Note: Calendar month is now 0-based.
  319.      */
  320.     public final static int JANUARY = 0;
  321.     /**
  322.      * Useful constant for month. Used in GregorianCalendar.
  323.      */
  324.     public final static int FEBRUARY = 1;
  325.     /**
  326.      * Useful constant for month. Used in GregorianCalendar.
  327.      */
  328.     public final static int MARCH = 2;
  329.     /**
  330.      * Useful constant for month. Used in GregorianCalendar.
  331.      */
  332.     public final static int APRIL = 3;
  333.     /**
  334.      * Useful constant for month. Used in GregorianCalendar.
  335.      */
  336.     public final static int MAY = 4;
  337.     /**
  338.      * Useful constant for month. Used in GregorianCalendar.
  339.      */
  340.     public final static int JUNE = 5;
  341.     /**
  342.      * Useful constant for month. Used in GregorianCalendar.
  343.      */
  344.     public final static int JULY = 6;
  345.     /**
  346.      * Useful constant for month. Used in GregorianCalendar.
  347.      */
  348.     public final static int AUGUST = 7;
  349.     /**
  350.      * Useful constant for month. Used in GregorianCalendar.
  351.      */
  352.     public final static int SEPTEMBER = 8;
  353.     /**
  354.      * Useful constant for month. Used in GregorianCalendar.
  355.      */
  356.     public final static int OCTOBER = 9;
  357.     /**
  358.      * Useful constant for month. Used in GregorianCalendar.
  359.      */
  360.     public final static int NOVEMBER = 10;
  361.     /**
  362.      * Useful constant for month. Used in GregorianCalendar.
  363.      */
  364.     public final static int DECEMBER = 11;
  365.     /**
  366.      * Useful constant for month. Used in GregorianCalendar.
  367.      * UNDECIMBER is an artifical name. This 13th month is for lunar
  368.      * calendars.
  369.      */
  370.     public final static int UNDECIMBER = 12;
  371.     /**
  372.      * Useful constant for hour in 12-hour clock. Used in GregorianCalendar.
  373.      */
  374.     public final static int AM = 0;
  375.     /**
  376.      * Useful constant for hour in 12-hour clock. Used in GregorianCalendar.
  377.      */
  378.     public final static int PM = 1;
  379.  
  380.     // Internal notes:
  381.     // Calendar contains two kinds of time representations: current "time" in
  382.     // milliseconds, and a set of time "fields" representing the current time.
  383.     // The two representations are usually in sync, but can get out of sync
  384.     // as follows.
  385.     // 1. Initially, no fields are set, and the time is invalid.
  386.     // 2. If the time is set, all fields are computed and in sync.
  387.     // 3. If a single field is set, the time is invalid.
  388.     // Recomputation of the time and fields happens when the object needs
  389.     // to return a result to the user, or use a result for a computation.
  390.  
  391.     /**
  392.      * The time fields containing values into which the millis is computed.
  393.      */
  394.     protected int           fields[]; // NOTE: Make transient when possible
  395.  
  396.     /**
  397.      * The flags which tell if a specified time field for the calendar is set.
  398.      * A new object has no fields set.  After the first call to a method
  399.      * which generates the fields, they all remain set after that.
  400.      */
  401.     protected boolean       isSet[]; // NOTE: Remove when possible
  402.  
  403.     /**
  404.      * Pseudo-time-stamps which specify when each field was set. There
  405.      * are two special values, UNSET and INTERNALLY_SET. Values from
  406.      * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values.
  407.      */
  408.     transient int           stamp[];
  409.  
  410.     /**
  411.      * The current time set for the calendar.
  412.      */
  413.     protected long          time;
  414.  
  415.     /**
  416.      * The flag which indicates if the current time is set for the calendar.
  417.      * The time is made invalid by the user setting an individual field.
  418.      */
  419.     protected boolean       isTimeSet; // NOTE: Make transient when possible
  420.  
  421.     /**
  422.      * True if the fields are in sync with the currently set time of this Calendar.
  423.      * If false, then the next attempt to get the value of a field will
  424.      * force a recomputation of all fields from the current value of the time
  425.      * field.
  426.      *
  427.      * This should really be named areFieldsInSync, but the old name is retained
  428.      * for backward compatibility.
  429.      */
  430.     protected boolean       areFieldsSet; // NOTE: Make transient when possible
  431.  
  432.     /**
  433.      * True if all fields have been set.
  434.      *
  435.      * NOTE: MAKE PROTECTED AT NEXT API CHANGE, or ADD ACCESSOR METHODS.
  436.      */
  437.     transient boolean       areAllFieldsSet;
  438.  
  439.     /**
  440.      * @see #setLenient
  441.      */
  442.     private boolean         lenient = true;
  443.  
  444.     /**
  445.      * Time zone affects the time calculation done by Calendar. Calendar uses
  446.      * the time zone data to produce the local time. Both firstDayOfWeek
  447.      * and minimalDaysInFirstWeek are locale-dependent. For example,
  448.      * in US locale, firstDayOfWeek is SUNDAY; minimalDaysInFirstWeek is 1.
  449.      * They are used to figure out the week count for a specific date for
  450.      * a given locale. These must be set when a Calendar is constructed.
  451.      */
  452.     private TimeZone        zone;
  453.     private int             firstDayOfWeek;
  454.     private int             minimalDaysInFirstWeek;
  455.  
  456.     /**
  457.      * Cache to hold the firstDayOfWeek and minimalDaysInFirstWeek
  458.      * of a Locale.
  459.      */
  460.     private static Hashtable cachedLocaleData = new Hashtable(3);
  461.  
  462.     // Special values of stamp[]
  463.     static final int        UNSET = 0;
  464.     static final int        INTERNALLY_SET = 1;
  465.     static final int        MINIMUM_USER_STAMP = 2;
  466.  
  467.     // The next available value for stampp[]
  468.     private int             nextStamp = MINIMUM_USER_STAMP;
  469.  
  470.     // the internal serial version which says which version was written
  471.     // - 0 (default) for version up to JDK 1.1.5
  472.     // - 1 for version from JDK 1.1.6, which writes a correct 'time' value
  473.     //     as well as compatible values for other fields.  This is a
  474.     //     transitional format.
  475.     // - 2 (not implemented yet) a future version, in which fields[],
  476.     //     areFieldsSet, and isTimeSet become transient, and isSet[] is
  477.     //     removed. In JDK 1.1.6 we write a format compatible with version 2.
  478.     static final int        currentSerialVersion = 1;
  479.     private int             serialVersionOnStream = currentSerialVersion;
  480.  
  481.     // Proclaim serialization compatibility with JDK 1.1
  482.     static final long       serialVersionUID = -1807547505821590642L;
  483.  
  484.     /**
  485.      * Constructs a Calendar with the default time zone as returned
  486.      * by TimeZone.getDefault(), and the default locale.
  487.      * @see     TimeZone#getDefault
  488.      */
  489.     protected Calendar()
  490.     {
  491.         this(TimeZone.getDefault(), Locale.getDefault());
  492.     }
  493.  
  494.     /**
  495.      * Constructs a Calendar with the given time zone and locale.
  496.      * @param zone the given time zone.
  497.      */
  498.     protected Calendar(TimeZone zone, Locale aLocale)
  499.     {
  500.         fields = new int[FIELD_COUNT];
  501.         isSet = new boolean[FIELD_COUNT];
  502.         stamp = new int[FIELD_COUNT];
  503.  
  504.         this.zone = zone;
  505.         setWeekCountData(aLocale);
  506.     }
  507.  
  508.     /**
  509.      * Gets a Calendar using the default timezone and locale.
  510.      * @return a Calendar.
  511.      */
  512.     public static synchronized Calendar getInstance()
  513.     {
  514.         return new GregorianCalendar();
  515.     }
  516.  
  517.     /**
  518.      * Gets a Calendar using the given timezone and default locale.
  519.      * @param zone the given timezone.
  520.      * @return a Calendar.
  521.      */
  522.     public static synchronized Calendar getInstance(TimeZone zone)
  523.     {
  524.         return new GregorianCalendar(zone, Locale.getDefault());
  525.     }
  526.  
  527.     /**
  528.      * Gets a Calendar using the default timezone and given locale.
  529.      * @param aLocale the given locale.
  530.      * @return a Calendar.
  531.      */
  532.     public static synchronized Calendar getInstance(Locale aLocale)
  533.     {
  534.         return new GregorianCalendar(TimeZone.getDefault(), aLocale);
  535.     }
  536.  
  537.     /**
  538.      * Gets a Calendar using the given timezone and given locale.
  539.      * @param zone the given timezone.
  540.      * @param aLocale the given locale.
  541.      * @return a Calendar.
  542.      */
  543.     public static synchronized Calendar getInstance(TimeZone zone,
  544.                                                     Locale aLocale)
  545.     {
  546.         return new GregorianCalendar(zone, aLocale);
  547.     }
  548.  
  549.     /**
  550.      * Gets the set of locales for which Calendars are installed.
  551.      * @return the set of locales for which Calendars are installed.
  552.      */
  553.     public static synchronized Locale[] getAvailableLocales()
  554.     {
  555.         return DateFormat.getAvailableLocales();
  556.     }
  557.  
  558.     /**
  559.      * Converts Calendar's time field values to UTC as milliseconds.
  560.      */
  561.     protected abstract void computeTime();
  562.  
  563.     /**
  564.      * Converts UTC as milliseconds to time field values.
  565.      * This allows you to sync up the time field values with
  566.      * a new time that is set for the calendar.  The time is <em>not</em>
  567.      * recomputed first; to recompute the time, then the fields, call the
  568.      * <code>complete</code> method.
  569.      * @see #complete
  570.      */
  571.     protected abstract void computeFields();
  572.  
  573.     /**
  574.      * Gets this Calendar's current time.
  575.      * @return the current time.
  576.      */
  577.     public final Date getTime() {
  578.         return new Date( getTimeInMillis() );
  579.     }
  580.  
  581.     /**
  582.      * Sets this Calendar's current time with the given Date.
  583.      * @param date the given Date.
  584.      */
  585.     public final void setTime(Date date) {
  586.         setTimeInMillis( date.getTime() );
  587.     }
  588.  
  589.     /**
  590.      * Gets this Calendar's current time as a long.
  591.      * @return the current time as UTC milliseconds from the epoch.
  592.      */
  593.     protected long getTimeInMillis() {
  594.         if (!isTimeSet) updateTime();
  595.         return time;
  596.     }
  597.  
  598.     /**
  599.      * Sets this Calendar's current time from the given long value.
  600.      * @param date the new time in UTC milliseconds from the epoch.
  601.      */
  602.     protected void setTimeInMillis( long millis ) {
  603.         isTimeSet = true;
  604.         time = millis;
  605.         areFieldsSet = false;
  606.         if (!areFieldsSet) {
  607.             computeFields();
  608.             areFieldsSet = true;
  609.             areAllFieldsSet = true;
  610.         }
  611.     }
  612.  
  613.     /**
  614.      * Gets the value for a given time field.
  615.      * @param field the given time field.
  616.      * @return the value for the given time field.
  617.      */
  618.     public final int get(int field)
  619.     {
  620.         complete();
  621.         return fields[field];
  622.     }
  623.  
  624.     /**
  625.      * Gets the value for a given time field. This is an internal
  626.      * fast time field value getter for the subclasses.
  627.      * @param field the given time field.
  628.      * @return the value for the given time field.
  629.      */
  630.     protected final int internalGet(int field)
  631.     {
  632.         return fields[field];
  633.     }
  634.  
  635.     /**
  636.      * Sets the value for the given time field.  This is an internal
  637.      * fast setter for subclasses.  It does not affect the areFieldsSet, isTimeSet,
  638.      * or areAllFieldsSet flags.
  639.      */
  640.     final void internalSet(int field, int value)
  641.     {
  642.         fields[field] = value;
  643.     }
  644.  
  645.     /**
  646.      * Sets the time field with the given value.
  647.      * @param field the given time field.
  648.      * @param value the value to be set for the given time field.
  649.      */
  650.     public final void set(int field, int value)
  651.     {
  652.         isTimeSet = false;
  653.         fields[field] = value;
  654.         stamp[field] = nextStamp++;
  655.         areFieldsSet = false;
  656.         isSet[field] = true; // Remove later
  657.     }
  658.  
  659.     /**
  660.      * Sets the values for the fields year, month, and date.
  661.      * Previous values of other fields are retained.  If this is not desired,
  662.      * call <code>clear</code> first.
  663.      * @param year the value used to set the YEAR time field.
  664.      * @param month the value used to set the MONTH time field.
  665.      * Month value is 0-based. e.g., 0 for January.
  666.      * @param date the value used to set the DATE time field.
  667.      */
  668.     public final void set(int year, int month, int date)
  669.     {
  670.         set(YEAR, year);
  671.         set(MONTH, month);
  672.         set(DATE, date);
  673.     }
  674.  
  675.     /**
  676.      * Sets the values for the fields year, month, date, hour, and minute.
  677.      * Previous values of other fields are retained.  If this is not desired,
  678.      * call <code>clear</code> first.
  679.      * @param year the value used to set the YEAR time field.
  680.      * @param month the value used to set the MONTH time field.
  681.      * Month value is 0-based. e.g., 0 for January.
  682.      * @param date the value used to set the DATE time field.
  683.      * @param hour the value used to set the HOUR_OF_DAY time field.
  684.      * @param minute the value used to set the MINUTE time field.
  685.      */
  686.     public final void set(int year, int month, int date, int hour, int minute)
  687.     {
  688.         set(YEAR, year);
  689.         set(MONTH, month);
  690.         set(DATE, date);
  691.         set(HOUR_OF_DAY, hour);
  692.         set(MINUTE, minute);
  693.     }
  694.  
  695.     /**
  696.      * Sets the values for the fields year, month, date, hour, minute, and second.
  697.      * Previous values of other fields are retained.  If this is not desired,
  698.      * call <code>clear</code> first.
  699.      * @param year the value used to set the YEAR time field.
  700.      * @param month the value used to set the MONTH time field.
  701.      * Month value is 0-based. e.g., 0 for January.
  702.      * @param date the value used to set the DATE time field.
  703.      * @param hour the value used to set the HOUR_OF_DAY time field.
  704.      * @param minute the value used to set the MINUTE time field.
  705.      * @param second the value used to set the SECOND time field.
  706.      */
  707.     public final void set(int year, int month, int date, int hour, int minute,
  708.                           int second)
  709.     {
  710.         set(YEAR, year);
  711.         set(MONTH, month);
  712.         set(DATE, date);
  713.         set(HOUR_OF_DAY, hour);
  714.         set(MINUTE, minute);
  715.         set(SECOND, second);
  716.     }
  717.  
  718.     /**
  719.      * Clears the values of all the time fields.
  720.      */
  721.     public final void clear()
  722.     {
  723.         fields = new int[FIELD_COUNT];
  724.         stamp = new int[FIELD_COUNT];
  725.         areFieldsSet = false;
  726.         areAllFieldsSet = false;
  727.         isSet = new boolean[FIELD_COUNT]; // Remove later
  728.     }
  729.  
  730.     /**
  731.      * Clears the value in the given time field.
  732.      * @param field the time field to be cleared.
  733.      */
  734.     public final void clear(int field)
  735.     {
  736.         fields[field] = 0;
  737.         stamp[field] = UNSET;
  738.         areFieldsSet = false;
  739.         areAllFieldsSet = false;
  740.         isSet[field] = false; // Remove later
  741.     }
  742.  
  743.     /**
  744.      * Determines if the given time field has a value set.
  745.      * @return true if the given time field has a value set; false otherwise.
  746.      */
  747.     public final boolean isSet(int field)
  748.     {
  749.         return stamp[field] != UNSET;
  750.         // return isSet[field];
  751.     }
  752.  
  753.     /**
  754.      * Fills in any unset fields in the time field list.
  755.      */
  756.     protected void complete()
  757.     {
  758.         if (!isTimeSet) updateTime();
  759.         if (!areFieldsSet) {
  760.             computeFields(); // fills in unset fields
  761.             areFieldsSet = true;
  762.             areAllFieldsSet = true;
  763.         }
  764.     }
  765.  
  766.     /**
  767.      * Compares this calendar to the specified object.
  768.      * The result is <code>true</code> if and only if the argument is
  769.      * not <code>null</code> and is a <code>Calendar</code> object that
  770.      * represents the same calendar as this object.
  771.      * @param obj the object to compare with.
  772.      * @return <code>true</code> if the objects are the same;
  773.      * <code>false</code> otherwise.
  774.      */
  775.     public abstract boolean equals(Object obj); // This becomes concrete in 1.2
  776.  
  777.     /**
  778.      * Compares the time field records.
  779.      * Equivalent to comparing result of conversion to UTC.
  780.      * @param when the Calendar to be compared with this Calendar.
  781.      * @return true if the current time of this Calendar is before
  782.      * the time of Calendar when; false otherwise.
  783.      */
  784.     public abstract boolean before(Object when); // This becomes concrete in 1.2
  785.  
  786.     /**
  787.      * Compares the time field records.
  788.      * Equivalent to comparing result of conversion to UTC.
  789.      * @param when the Calendar to be compared with this Calendar.
  790.      * @return true if the current time of this Calendar is after
  791.      * the time of Calendar when; false otherwise.
  792.      */
  793.     public abstract boolean after(Object when); // This becomes concrete in 1.2
  794.  
  795.     /**
  796.      * Date Arithmetic function.
  797.      * Adds the specified (signed) amount of time to the given time field,
  798.      * based on the calendar's rules. For example, to subtract 5 days from
  799.      * the current time of the calendar, you can achieve it by calling:
  800.      * <p>add(Calendar.DATE, -5).
  801.      * @param field the time field.
  802.      * @param amount the amount of date or time to be added to the field.
  803.      */
  804.     abstract public void add(int field, int amount);
  805.  
  806.     /**
  807.      * Time Field Rolling function.
  808.      * Rolls (up/down) a single unit of time on the given time field. For
  809.      * example, to roll the current date up by one day, you can achieve it
  810.      * by calling:
  811.      * <p>roll(Calendar.DATE, true).
  812.      * When rolling on the year or Calendar.YEAR field, it will roll the year
  813.      * value in the range between 1 and the value returned by calling
  814.      * getMaximum(Calendar.YEAR).
  815.      * When rolling on the month or Calendar.MONTH field, other fields like
  816.      * date might conflict and, need to be changed. For instance,
  817.      * rolling the month on the date 01/31/96 will result in 03/02/96.
  818.      * When rolling on the hour-in-day or Calendar.HOUR_OF_DAY field, it will
  819.      * roll the hour value in the range between 0 and 23, which is zero-based.
  820.      * @param field the time field.
  821.      * @param up indicates if the value of the specified time field is to be
  822.      * rolled up or rolled down. Use true if rolling up, false otherwise.
  823.      */
  824.     abstract public void roll(int field, boolean up);
  825.  
  826.     /**
  827.      * Sets the time zone with the given time zone value.
  828.      * @param value the given time zone.
  829.      */
  830.     public void setTimeZone(TimeZone value)
  831.     {
  832.         zone = value;
  833.     }
  834.  
  835.     /**
  836.      * Gets the time zone.
  837.      * @return the time zone object associated with this calendar.
  838.      */
  839.     public TimeZone getTimeZone()
  840.     {
  841.         return zone;
  842.     }
  843.  
  844.     /**
  845.      * Specify whether or not date/time interpretation is to be lenient.  With
  846.      * lenient interpretation, a date such as "February 942, 1996" will be
  847.      * treated as being equivalent to the 941st day after February 1, 1996.
  848.      * With strict interpretation, such dates will cause an exception to be
  849.      * thrown.
  850.      *
  851.      * @see java.text.DateFormat#setLenient
  852.      */
  853.     public void setLenient(boolean lenient)
  854.     {
  855.         this.lenient = lenient;
  856.     }
  857.  
  858.     /**
  859.      * Tell whether date/time interpretation is to be lenient.
  860.      */
  861.     public boolean isLenient()
  862.     {
  863.         return lenient;
  864.     }
  865.  
  866.     /**
  867.      * Sets what the first day of the week is; e.g., Sunday in US,
  868.      * Monday in France.
  869.      * @param value the given first day of the week.
  870.      */
  871.     public void setFirstDayOfWeek(int value)
  872.     {
  873.         firstDayOfWeek = value;
  874.     }
  875.  
  876.     /**
  877.      * Gets what the first day of the week is; e.g., Sunday in US,
  878.      * Monday in France.
  879.      * @return the first day of the week.
  880.      */
  881.     public int getFirstDayOfWeek()
  882.     {
  883.         return firstDayOfWeek;
  884.     }
  885.  
  886.     /**
  887.      * Sets what the minimal days required in the first week of the year are;
  888.      * For example, if the first week is defined as one that contains the first
  889.      * day of the first month of a year, call the method with value 1. If it
  890.      * must be a full week, use value 7.
  891.      * @param value the given minimal days required in the first week
  892.      * of the year.
  893.      */
  894.     public void setMinimalDaysInFirstWeek(int value)
  895.     {
  896.         minimalDaysInFirstWeek = value;
  897.     }
  898.  
  899.     /**
  900.      * Gets what the minimal days required in the first week of the year are;
  901.      * e.g., if the first week is defined as one that contains the first day
  902.      * of the first month of a year, getMinimalDaysInFirstWeek returns 1. If
  903.      * the minimal days required must be a full week, getMinimalDaysInFirstWeek
  904.      * returns 7.
  905.      * @return the minimal days required in the first week of the year.
  906.      */
  907.     public int getMinimalDaysInFirstWeek()
  908.     {
  909.         return minimalDaysInFirstWeek;
  910.     }
  911.  
  912.     /**
  913.      * Gets the minimum value for the given time field.
  914.      * e.g., for Gregorian DAY_OF_MONTH, 1.
  915.      * @param field the given time field.
  916.      * @return the minimum value for the given time field.
  917.      */
  918.     abstract public int getMinimum(int field);
  919.  
  920.     /**
  921.      * Gets the maximum value for the given time field.
  922.      * e.g. for Gregorian DAY_OF_MONTH, 31.
  923.      * @param field the given time field.
  924.      * @return the maximum value for the given time field.
  925.      */
  926.     abstract public int getMaximum(int field);
  927.  
  928.     /**
  929.      * Gets the highest minimum value for the given field if varies.
  930.      * Otherwise same as getMinimum(). For Gregorian, no difference.
  931.      * @param field the given time field.
  932.      * @return the highest minimum value for the given time field.
  933.      */
  934.     abstract public int getGreatestMinimum(int field);
  935.  
  936.     /**
  937.      * Gets the lowest maximum value for the given field if varies.
  938.      * Otherwise same as getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28.
  939.      * @param field the given time field.
  940.      * @return the lowest maximum value for the given time field.
  941.      */
  942.     abstract public int getLeastMaximum(int field);
  943.  
  944.     /**
  945.      * Overrides Cloneable
  946.      */
  947.     public Object clone()
  948.     {
  949.         try {
  950.             Calendar other = (Calendar) super.clone();
  951.  
  952.             other.fields = new int[FIELD_COUNT];
  953.             other.isSet = new boolean[FIELD_COUNT];
  954.             other.stamp = new int[FIELD_COUNT];
  955.             System.arraycopy(this.fields, 0, other.fields, 0, FIELD_COUNT);
  956.             System.arraycopy(this.isSet, 0, other.isSet, 0, FIELD_COUNT);
  957.             System.arraycopy(this.stamp, 0, other.stamp, 0, FIELD_COUNT);
  958.  
  959.             other.zone = (TimeZone) zone.clone();
  960.             return other;
  961.         }
  962.         catch (CloneNotSupportedException e) {
  963.             // this shouldn't happen, since we are Cloneable
  964.             throw new InternalError();
  965.         }
  966.     }
  967.  
  968.     private static final String[] FIELD_NAME = {
  969.         ",ERA=", ",YEAR=", ",MONTH=", ",WEEK_OF_YEAR=", ",WEEK_OF_MONTH=", ",DAY_OF_MONTH=",
  970.         ",DAY_OF_YEAR=", ",DAY_OF_WEEK=", ",DAY_OF_WEEK_IN_MONTH=", ",AM_PM=", ",HOUR=",
  971.         ",HOUR_OF_DAY=", ",MINUTE=", ",SECOND=", ",MILLISECOND=", ",ZONE_OFFSET=",
  972.         ",DST_OFFSET="
  973.     };
  974.  
  975.     /**
  976.      * Return a string representation of this calendar.
  977.      * @return  a string representation of this calendar.
  978.      */
  979.     public String toString() {
  980.         StringBuffer buffer = new StringBuffer();
  981.         buffer.append(getClass().getName());
  982.         buffer.append("[time=");
  983.         buffer.append(isTimeSet ? String.valueOf(time) : "?");
  984.         buffer.append(",areFieldsSet=");
  985.         buffer.append(areFieldsSet);
  986.         buffer.append(",areAllFieldsSet=");
  987.         buffer.append(areAllFieldsSet);
  988.         buffer.append(",lenient=");
  989.         buffer.append(lenient);
  990.         buffer.append(",zone=");
  991.         buffer.append(zone);
  992.         buffer.append(",firstDayOfWeek=");
  993.         buffer.append(firstDayOfWeek);
  994.         buffer.append(",minimalDaysInFirstWeek=");
  995.         buffer.append(minimalDaysInFirstWeek);
  996.         for (int i=0; i<FIELD_COUNT; ++i) {
  997.             buffer.append(FIELD_NAME[i]);
  998.             buffer.append(isSet(i) ? String.valueOf(fields[i]) : "?");
  999.         }
  1000.         buffer.append(']');
  1001.         return buffer.toString();
  1002.     }
  1003.  
  1004.     // =======================privates===============================
  1005.  
  1006.     /**
  1007.      * Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent.
  1008.      * They are used to figure out the week count for a specific date for
  1009.      * a given locale. These must be set when a Calendar is constructed.
  1010.      * @param desiredLocale the given locale.
  1011.      */
  1012.     private void setWeekCountData(Locale desiredLocale)
  1013.     {
  1014.     /* try to get the Locale data from the cache */
  1015.     int[] data = (int[]) cachedLocaleData.get(desiredLocale);
  1016.     if (data == null) {  /* cache miss */
  1017.         ResourceBundle resource
  1018.         = ResourceBundle.getBundle("java.text.resources.LocaleElements",
  1019.                        desiredLocale);
  1020.         String[] dateTimePatterns = 
  1021.         resource.getStringArray("DateTimeElements");
  1022.         data = new int[2];
  1023.         data[0] = Integer.parseInt(dateTimePatterns[0]);
  1024.         data[1] = Integer.parseInt(dateTimePatterns[1]);
  1025.         /* cache update */
  1026.         cachedLocaleData.put(desiredLocale, data);
  1027.     }
  1028.     firstDayOfWeek = data[0];
  1029.     minimalDaysInFirstWeek = data[1];
  1030.     }
  1031.  
  1032.     /**
  1033.      * Recompute the time and update the status fields isTimeSet
  1034.      * and areFieldsSet.  Callers should check isTimeSet and only
  1035.      * call this method if isTimeSet is false.
  1036.      */
  1037.     private void updateTime() {
  1038.         computeTime();
  1039.         // If we are lenient, we need to recompute the fields to normalize
  1040.         // the values.  Also, if we haven't set all the fields yet (i.e.,
  1041.         // in a newly-created object), we need to fill in the fields. [LIU]
  1042.         if (isLenient() || !areAllFieldsSet) areFieldsSet = false;
  1043.         isTimeSet = true;
  1044.     }
  1045.  
  1046.     /**
  1047.      * Write object out to a serialization stream.
  1048.      */
  1049.     private void writeObject(ObjectOutputStream stream)
  1050.          throws IOException
  1051.     {
  1052.         /*
  1053.          * Calendar has many private fields that are not marked transient, such
  1054.          * as fields[], isTimeSet, and areFieldsSet.  In addition, it has a
  1055.          * field which is obsolete, isSet[]. These fields should not be part of
  1056.          * the persistent state. Unfortunately, this bug didn't get fixed before
  1057.          * JDK 1.1 shipped. This means that any fix has to be done in a way that
  1058.          * doesn't break serialization compatibility with 1.1. Fields in later
  1059.          * versions can only be removed from the serialized format (i.e., made
  1060.          * transient) if it can be shown that the Calendar implementation in 1.1
  1061.          * (and possibly modified versions in later releases) can function
  1062.          * correctly if all the removed fields are initialized to their default
  1063.          * values (0, null, false).
  1064.          *
  1065.          * If that's not possible, it might be possible that we'll declare for
  1066.          * some release that it's no longer two-way serialization compatible,
  1067.          * i.e., data can move from older to newer versions, but not back, or
  1068.          * back only to a specified release. To make that possible, we implement
  1069.          * a special form of serialization for now, such that (a) it works
  1070.          * correctly if fields that we intend to remove are initialized to their
  1071.          * default values and (b) the fields that we intend to keep are written
  1072.          * to streams with complete and up-to-date information so that the other
  1073.          * fields are not necessary. In other words, we write all fields, but on
  1074.          * reading ignore those that we intend to remove.
  1075.          */
  1076.  
  1077.         // Try to compute the time correctly, for the future (stream
  1078.         // version 2) in which we don't write out fields[] or isSet[].
  1079.         if (!isTimeSet) {
  1080.             try {
  1081.                 updateTime();
  1082.             }
  1083.             catch (IllegalArgumentException e) {}
  1084.         }
  1085.  
  1086.         // Write out the 1.1 FCS object.
  1087.         stream.defaultWriteObject();
  1088.     }
  1089.  
  1090.     /**
  1091.      * Read this object out to a serialization stream.
  1092.      */
  1093.     private void readObject(ObjectInputStream stream)
  1094.          throws IOException, ClassNotFoundException
  1095.     {
  1096.         stream.defaultReadObject();
  1097.  
  1098.         stamp = new int[FIELD_COUNT];
  1099.  
  1100.         // Starting with version 2 (not implemented yet), we expect that
  1101.         // fields[], isSet[], isTimeSet, and areFieldsSet may not be
  1102.         // streamed out anymore.  We expect 'time' to be correct.
  1103.         if (serialVersionOnStream >= 2)
  1104.         {
  1105.             isTimeSet = true;
  1106.             if (fields == null) fields = new int[FIELD_COUNT];
  1107.             if (isSet == null) isSet = new boolean[FIELD_COUNT];
  1108.         }
  1109.         else if (serialVersionOnStream == 0)
  1110.         {
  1111.             for (int i=0; i<FIELD_COUNT; ++i)
  1112.                 stamp[i] = isSet[i] ? INTERNALLY_SET : UNSET;
  1113.         }
  1114.  
  1115.         serialVersionOnStream = currentSerialVersion;
  1116.     }
  1117. }
  1118.