home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / util / Calendar.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  48.7 KB  |  1,376 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)Calendar.java    1.42 98/09/23
  3.  *
  4.  * (C) Copyright Taligent, Inc. 1996-1998 - All Rights Reserved
  5.  * (C) Copyright IBM Corp. 1996-1998 - All Rights Reserved
  6.  *
  7.  * Portions copyright (c) 1996-1998 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.  * {@link Date}
  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 {@link DateFormat}
  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 <code>December 12, <b>1996</b></code> results in
  139.  * <code>January 12, <b>1996</b></code>.
  140.  *
  141.  * <p>
  142.  * <code>Calendar</code> also provides a date arithmetic function for
  143.  * adding the specified (signed) amount of time to a particular time field.
  144.  * For example, subtracting 5 days from the date <code>September 12, 1996</code>
  145.  * results in <code>September 7, 1996</code>.
  146.  *
  147.  * @see          Date
  148.  * @see          GregorianCalendar
  149.  * @see          TimeZone
  150.  * @see          java.text.DateFormat
  151.  * @version      1.42
  152.  * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu
  153.  */
  154. public abstract class Calendar implements Serializable, Cloneable {
  155.  
  156.     // Data flow in Calendar
  157.     // ---------------------
  158.  
  159.     // The current time is represented in two ways by Calendar: as UTC
  160.     // milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local
  161.     // fields such as MONTH, HOUR, AM_PM, etc.  It is possible to compute the
  162.     // millis from the fields, and vice versa.  The data needed to do this
  163.     // conversion is encapsulated by a TimeZone object owned by the Calendar.
  164.     // The data provided by the TimeZone object may also be overridden if the
  165.     // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
  166.     // keeps track of what information was most recently set by the caller, and
  167.     // uses that to compute any other information as needed.
  168.  
  169.     // If the user sets the fields using set(), the data flow is as follows.
  170.     // This is implemented by the Calendar subclass's computeTime() method.
  171.     // During this process, certain fields may be ignored.  The disambiguation
  172.     // algorithm for resolving which fields to pay attention to is described
  173.     // above.
  174.  
  175.     //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
  176.     //           |
  177.     //           | Using Calendar-specific algorithm
  178.     //           V
  179.     //   local standard millis
  180.     //           |
  181.     //           | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
  182.     //           V
  183.     //   UTC millis (in time data member)
  184.  
  185.     // If the user sets the UTC millis using setTime(), the data flow is as
  186.     // follows.  This is implemented by the Calendar subclass's computeFields()
  187.     // method.
  188.  
  189.     //   UTC millis (in time data member)
  190.     //           |
  191.     //           | Using TimeZone getOffset()
  192.     //           V
  193.     //   local standard millis
  194.     //           |
  195.     //           | Using Calendar-specific algorithm
  196.     //           V
  197.     //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
  198.  
  199.     // In general, a round trip from fields, through local and UTC millis, and
  200.     // back out to fields is made when necessary.  This is implemented by the
  201.     // complete() method.  Resolving a partial set of fields into a UTC millis
  202.     // value allows all remaining fields to be generated from that value.  If
  203.     // the Calendar is lenient, the fields are also renormalized to standard
  204.     // ranges when they are regenerated.
  205.  
  206.     /**
  207.      * Field number for <code>get</code> and <code>set</code> indicating the
  208.      * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific
  209.      * value.
  210.      * @see GregorianCalendar#AD
  211.      * @see GregorianCalendar#BC
  212.      */
  213.     public final static int ERA = 0;
  214.     /**
  215.      * Field number for <code>get</code> and <code>set</code> indicating the
  216.      * year. This is a calendar-specific value.
  217.      */
  218.     public final static int YEAR = 1;
  219.     /**
  220.      * Field number for <code>get</code> and <code>set</code> indicating the
  221.      * month. This is a calendar-specific value.
  222.      */
  223.     public final static int MONTH = 2;
  224.     /**
  225.      * Field number for <code>get</code> and <code>set</code> indicating the
  226.      * week number within the current year.
  227.      */
  228.     public final static int WEEK_OF_YEAR = 3;
  229.     /**
  230.      * Field number for <code>get</code> and <code>set</code> indicating the
  231.      * week number within the current month.
  232.      */
  233.     public final static int WEEK_OF_MONTH = 4;
  234.     /**
  235.      * Field number for <code>get</code> and <code>set</code> indicating the
  236.      * day of the month. This is a synonym for <code>DAY_OF_MONTH</code>.
  237.      * @see #DAY_OF_MONTH
  238.      */
  239.     public final static int DATE = 5;
  240.     /**
  241.      * Field number for <code>get</code> and <code>set</code> indicating the
  242.      * day of the month. This is a synonym for <code>DATE</code>.
  243.      * @see #DATE
  244.      */
  245.     public final static int DAY_OF_MONTH = 5;
  246.     /**
  247.      * Field number for <code>get</code> and <code>set</code> indicating the
  248.      * day number within the current year.
  249.      */
  250.     public final static int DAY_OF_YEAR = 6;
  251.     /**
  252.      * Field number for <code>get</code> and <code>set</code> indicating the
  253.      * day of the week.
  254.      */
  255.     public final static int DAY_OF_WEEK = 7;
  256.     /**
  257.      * Field number for <code>get</code> and <code>set</code> indicating the
  258.      * ordinal number of the day of the week within the current month. Together
  259.      * with the <code>DAY_OF_WEEK</code> field, this uniquely specifies a day
  260.      * within a month.  Example: the last Sunday in October is specified as
  261.      * <code>DAY_OF_WEEK = Sunday, DAY_OF_WEEK_IN_MONTH = -1</code>.
  262.      * @see #DAY_OF_WEEK
  263.      */
  264.     public final static int DAY_OF_WEEK_IN_MONTH = 8;
  265.     /**
  266.      * Field number for <code>get</code> and <code>set</code> indicating
  267.      * whether the <code>HOUR</code> is before or after noon.
  268.      * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>.
  269.      * @see #AM
  270.      * @see #PM
  271.      * @see #HOUR
  272.      */
  273.     public final static int AM_PM = 9;
  274.     /**
  275.      * Field number for <code>get</code> and <code>set</code> indicating the
  276.      * hour of the morning or afternoon. <code>HOUR</code> is used for the 12-hour
  277.      * clock.
  278.      * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10.
  279.      * @see #AM_PM
  280.      * @see #HOUR_OF_DAY
  281.      */
  282.     public final static int HOUR = 10;
  283.     /**
  284.      * Field number for <code>get</code> and <code>set</code> indicating the
  285.      * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock.
  286.      * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22.
  287.      * @see #HOUR
  288.      */
  289.     public final static int HOUR_OF_DAY = 11;
  290.     /**
  291.      * Field number for <code>get</code> and <code>set</code> indicating the
  292.      * minute within the hour.
  293.      * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4.
  294.      */
  295.     public final static int MINUTE = 12;
  296.     /**
  297.      * Field number for <code>get</code> and <code>set</code> indicating the
  298.      * second within the minute.
  299.      * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15.
  300.      */
  301.     public final static int SECOND = 13;
  302.     /**
  303.      * Field number for <code>get</code> and <code>set</code> indicating the
  304.      * millisecond within the second.
  305.      * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250.
  306.      */
  307.     public final static int MILLISECOND = 14;
  308.     /**
  309.      * Field number for <code>get</code> and <code>set</code> indicating the
  310.      * raw offset from GMT in milliseconds.
  311.      */
  312.     public final static int ZONE_OFFSET = 15;
  313.     /**
  314.      * Field number for <code>get</code> and <code>set</code> indicating the
  315.      * daylight savings offset in milliseconds.
  316.      */
  317.     public final static int DST_OFFSET = 16;
  318.     /**
  319.      * The number of distict fields recognized by <code>get</code> and <code>set</code>.
  320.      * Field numbers range from <code>0..FIELD_COUNT-1</code>.
  321.      */
  322.     public final static int FIELD_COUNT = 17;
  323.  
  324.     /**
  325.      * Value of the <code>DAY_OF_WEEK</code> field indicating
  326.      * Sunday.
  327.      */
  328.     public final static int SUNDAY = 1;
  329.     /**
  330.      * Value of the <code>DAY_OF_WEEK</code> field indicating
  331.      * Monday.
  332.      */
  333.     public final static int MONDAY = 2;
  334.     /**
  335.      * Value of the <code>DAY_OF_WEEK</code> field indicating
  336.      * Tuesday.
  337.      */
  338.     public final static int TUESDAY = 3;
  339.     /**
  340.      * Value of the <code>DAY_OF_WEEK</code> field indicating
  341.      * Wednesday.
  342.      */
  343.     public final static int WEDNESDAY = 4;
  344.     /**
  345.      * Value of the <code>DAY_OF_WEEK</code> field indicating
  346.      * Thursday.
  347.      */
  348.     public final static int THURSDAY = 5;
  349.     /**
  350.      * Value of the <code>DAY_OF_WEEK</code> field indicating
  351.      * Friday.
  352.      */
  353.     public final static int FRIDAY = 6;
  354.     /**
  355.      * Value of the <code>DAY_OF_WEEK</code> field indicating
  356.      * Saturday.
  357.      */
  358.     public final static int SATURDAY = 7;
  359.  
  360.     /**
  361.      * Value of the <code>MONTH</code> field indicating the
  362.      * first month of the year.
  363.      */
  364.     public final static int JANUARY = 0;
  365.     /**
  366.      * Value of the <code>MONTH</code> field indicating the
  367.      * second month of the year.
  368.      */
  369.     public final static int FEBRUARY = 1;
  370.     /**
  371.      * Value of the <code>MONTH</code> field indicating the
  372.      * third month of the year.
  373.      */
  374.     public final static int MARCH = 2;
  375.     /**
  376.      * Value of the <code>MONTH</code> field indicating the
  377.      * fourth month of the year.
  378.      */
  379.     public final static int APRIL = 3;
  380.     /**
  381.      * Value of the <code>MONTH</code> field indicating the
  382.      * fifth month of the year.
  383.      */
  384.     public final static int MAY = 4;
  385.     /**
  386.      * Value of the <code>MONTH</code> field indicating the
  387.      * sixth month of the year.
  388.      */
  389.     public final static int JUNE = 5;
  390.     /**
  391.      * Value of the <code>MONTH</code> field indicating the
  392.      * seventh month of the year.
  393.      */
  394.     public final static int JULY = 6;
  395.     /**
  396.      * Value of the <code>MONTH</code> field indicating the
  397.      * eighth month of the year.
  398.      */
  399.     public final static int AUGUST = 7;
  400.     /**
  401.      * Value of the <code>MONTH</code> field indicating the
  402.      * ninth month of the year.
  403.      */
  404.     public final static int SEPTEMBER = 8;
  405.     /**
  406.      * Value of the <code>MONTH</code> field indicating the
  407.      * tenth month of the year.
  408.      */
  409.     public final static int OCTOBER = 9;
  410.     /**
  411.      * Value of the <code>MONTH</code> field indicating the
  412.      * eleventh month of the year.
  413.      */
  414.     public final static int NOVEMBER = 10;
  415.     /**
  416.      * Value of the <code>MONTH</code> field indicating the
  417.      * twelfth month of the year.
  418.      */
  419.     public final static int DECEMBER = 11;
  420.     /**
  421.      * Value of the <code>MONTH</code> field indicating the
  422.      * thirteenth month of the year. Although <code>GregorianCalendar</code>
  423.      * does not use this value, lunar calendars do.
  424.      */
  425.     public final static int UNDECIMBER = 12;
  426.  
  427.     /**
  428.      * Value of the <code>AM_PM</code> field indicating the
  429.      * period of the day from midnight to just before noon.
  430.      */
  431.     public final static int AM = 0;
  432.     /**
  433.      * Value of the <code>AM_PM</code> field indicating the
  434.      * period of the day from noon to just before midnight.
  435.      */
  436.     public final static int PM = 1;
  437.  
  438.     // Internal notes:
  439.     // Calendar contains two kinds of time representations: current "time" in
  440.     // milliseconds, and a set of time "fields" representing the current time.
  441.     // The two representations are usually in sync, but can get out of sync
  442.     // as follows.
  443.     // 1. Initially, no fields are set, and the time is invalid.
  444.     // 2. If the time is set, all fields are computed and in sync.
  445.     // 3. If a single field is set, the time is invalid.
  446.     // Recomputation of the time and fields happens when the object needs
  447.     // to return a result to the user, or use a result for a computation.
  448.  
  449.     /**
  450.      * The field values for the currently set time for this calendar.
  451.      * This is an array of <code>FIELD_COUNT</code> integers, with index values
  452.      * <code>ERA</code> through <code>DST_OFFSET</code>.
  453.      * @serial
  454.      */
  455.     protected int           fields[]; // NOTE: Make transient when possible
  456.  
  457.     /**
  458.      * The flags which tell if a specified time field for the calendar is set.
  459.      * A new object has no fields set.  After the first call to a method
  460.      * which generates the fields, they all remain set after that.
  461.      * This is an array of <code>FIELD_COUNT</code> booleans, with index values
  462.      * <code>ERA</code> through <code>DST_OFFSET</code>.
  463.      * @serial
  464.      */
  465.     protected boolean       isSet[]; // NOTE: Remove when possible
  466.  
  467.     /**
  468.      * Pseudo-time-stamps which specify when each field was set. There
  469.      * are two special values, UNSET and INTERNALLY_SET. Values from
  470.      * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values.
  471.      */
  472.     transient int           stamp[];
  473.  
  474.     /**
  475.      * The currently set time for this calendar, expressed in milliseconds after
  476.      * January 1, 1970, 0:00:00 GMT.
  477.      * @see #isTimeSet
  478.      * @serial
  479.      */
  480.     protected long          time;
  481.  
  482.     /**
  483.      * True if then the value of <code>time</code> is valid.
  484.      * The time is made invalid by a change to an item of <code>field[]</code>.
  485.      * @see #time
  486.      * @serial
  487.      */
  488.     protected boolean       isTimeSet; // NOTE: Make transient when possible
  489.  
  490.     /**
  491.      * True if <code>fields[]</code> are in sync with the currently set time.
  492.      * If false, then the next attempt to get the value of a field will
  493.      * force a recomputation of all fields from the current value of
  494.      * <code>time</code>.
  495.      * @serial
  496.      */
  497.     protected boolean       areFieldsSet; // NOTE: Make transient when possible
  498.  
  499.     /**
  500.      * True if all fields have been set.
  501.      * @serial
  502.      */
  503.     transient boolean       areAllFieldsSet;
  504.  
  505.     /**
  506.      * True if this calendar allows out-of-range field values during computation
  507.      * of <code>time</code> from <code>fields[]</code>.
  508.      * @see #setLenient
  509.      * @serial
  510.      */
  511.     private boolean         lenient = true;
  512.  
  513.     /**
  514.      * The <code>TimeZone</code> used by this calendar. </code>Calendar</code>
  515.      * uses the time zone data to translate between locale and GMT time.
  516.      * @serial
  517.      */
  518.     private TimeZone        zone;
  519.  
  520.     /**
  521.      * The first day of the week, with possible values <code>SUNDAY</code>,
  522.      * <code>MONDAY</code>, etc.  This is a locale-dependent value.
  523.      * @serial
  524.      */
  525.     private int             firstDayOfWeek;
  526.  
  527.     /**
  528.      * The number of days required for the first week in a month or year,
  529.      * with possible values from 1 to 7.  This is a locale-dependent value.
  530.      * @serial
  531.      */
  532.     private int             minimalDaysInFirstWeek;
  533.  
  534.     /**
  535.      * Cache to hold the firstDayOfWeek and minimalDaysInFirstWeek
  536.      * of a Locale.
  537.      */
  538.     private static Hashtable cachedLocaleData = new Hashtable(3);
  539.  
  540.     // Special values of stamp[]
  541.     static final int        UNSET = 0;
  542.     static final int        INTERNALLY_SET = 1;
  543.     static final int        MINIMUM_USER_STAMP = 2;
  544.  
  545.     /**
  546.      * The next available value for <code>stamp[]</code>, an internal array.
  547.      * This actually should not be written out to the stream, and will probably
  548.      * be removed from the stream in the near future.  In the meantime,
  549.      * a value of <code>MINIMUM_USER_STAMP</code> should be used.
  550.      * @serial
  551.      */
  552.     private int             nextStamp = MINIMUM_USER_STAMP;
  553.  
  554.     // the internal serial version which says which version was written
  555.     // - 0 (default) for version up to JDK 1.1.5
  556.     // - 1 for version from JDK 1.1.6, which writes a correct 'time' value
  557.     //     as well as compatible values for other fields.  This is a
  558.     //     transitional format.
  559.     // - 2 (not implemented yet) a future version, in which fields[],
  560.     //     areFieldsSet, and isTimeSet become transient, and isSet[] is
  561.     //     removed. In JDK 1.1.6 we write a format compatible with version 2.
  562.     static final int        currentSerialVersion = 1;
  563.     
  564.     /**
  565.      * The version of the serialized data on the stream.  Possible values:
  566.      * <dl>
  567.      * <dt><b>0</b> or not present on stream</dt>
  568.      * <dd>
  569.      * JDK 1.1.5 or earlier.
  570.      * </dd>
  571.      * <dt><b>1</b></dt>
  572.      * <dd>
  573.      * JDK 1.1.6 or later.  Writes a correct 'time' value
  574.      * as well as compatible values for other fields.  This is a
  575.      * transitional format.
  576.      * </dd>
  577.      * </dl>
  578.      * When streaming out this class, the most recent format
  579.      * and the highest allowable <code>serialVersionOnStream</code>
  580.      * is written.
  581.      * @serial
  582.      * @since JDK1.1.6
  583.      */
  584.     private int             serialVersionOnStream = currentSerialVersion;
  585.  
  586.     // Proclaim serialization compatibility with JDK 1.1
  587.     static final long       serialVersionUID = -1807547505821590642L;
  588.  
  589.     /**
  590.      * Constructs a Calendar with the default time zone
  591.      * and locale.
  592.      * @see     TimeZone#getDefault
  593.      */
  594.     protected Calendar()
  595.     {
  596.         this(TimeZone.getDefault(), Locale.getDefault());
  597.     }
  598.  
  599.     /**
  600.      * Constructs a calendar with the specified time zone and locale.
  601.      * @param zone the time zone to use
  602.      * @param aLocale the locale for the week data
  603.      */
  604.     protected Calendar(TimeZone zone, Locale aLocale)
  605.     {
  606.         fields = new int[FIELD_COUNT];
  607.         isSet = new boolean[FIELD_COUNT];
  608.         stamp = new int[FIELD_COUNT];
  609.  
  610.         this.zone = zone;
  611.         setWeekCountData(aLocale);
  612.     }
  613.  
  614.     /**
  615.      * Gets a calendar using the default time zone and locale.
  616.      * @return a Calendar.
  617.      */
  618.     public static synchronized Calendar getInstance()
  619.     {
  620.         return new GregorianCalendar();
  621.     }
  622.  
  623.     /**
  624.      * Gets a calendar using the specified time zone and default locale.
  625.      * @param zone the time zone to use
  626.      * @return a Calendar.
  627.      */
  628.     public static synchronized Calendar getInstance(TimeZone zone)
  629.     {
  630.         return new GregorianCalendar(zone, Locale.getDefault());
  631.     }
  632.  
  633.     /**
  634.      * Gets a calendar using the default time zone and specified locale.
  635.      * @param aLocale the locale for the week data
  636.      * @return a Calendar.
  637.      */
  638.     public static synchronized Calendar getInstance(Locale aLocale)
  639.     {
  640.         return new GregorianCalendar(TimeZone.getDefault(), aLocale);
  641.     }
  642.  
  643.     /**
  644.      * Gets a calendar with the specified time zone and locale.
  645.      * @param zone the time zone to use
  646.      * @param aLocale the locale for the week data
  647.      * @return a Calendar.
  648.      */
  649.     public static synchronized Calendar getInstance(TimeZone zone,
  650.                                                     Locale aLocale)
  651.     {
  652.         return new GregorianCalendar(zone, aLocale);
  653.     }
  654.  
  655.     /**
  656.      * Gets the list of locales for which Calendars are installed.
  657.      * @return the list of locales for which Calendars are installed.
  658.      */
  659.     public static synchronized Locale[] getAvailableLocales()
  660.     {
  661.         return DateFormat.getAvailableLocales();
  662.     }
  663.  
  664.     /**
  665.      * Converts the current field values in <code>fields[]</code>
  666.      * to the millisecond time value
  667.      * <code>time</code>.
  668.      */
  669.     protected abstract void computeTime();
  670.  
  671.     /**
  672.      * Converts 
  673.      * the current millisecond time value
  674.      * <code>time</code>
  675.      * to field values in <code>fields[]</code>.
  676.      * This allows you to sync up the time field values with
  677.      * a new time that is set for the calendar.  The time is <em>not</em>
  678.      * recomputed first; to recompute the time, then the fields, call the
  679.      * <code>complete</code> method.
  680.      * @see #complete
  681.      */
  682.     protected abstract void computeFields();
  683.  
  684.     /**
  685.      * Gets this Calendar's current time.
  686.      * @return the current time.
  687.      */
  688.     public final Date getTime() {
  689.         return new Date( getTimeInMillis() );
  690.     }
  691.  
  692.     /**
  693.      * Sets this Calendar's current time with the given Date.
  694.      * <p>
  695.      * Note: Calling <code>setTime()</code> with
  696.      * <code>Date(Long.MAX_VALUE)</code> or <code>Date(Long.MIN_VALUE)</code>
  697.      * may yield incorrect field values from <code>get()</code>.
  698.      * @param date the given Date.  */
  699.     public final void setTime(Date date) {
  700.         setTimeInMillis( date.getTime() );
  701.     }
  702.  
  703.     /**
  704.      * Gets this Calendar's current time as a long.
  705.      * @return the current time as UTC milliseconds from the epoch.
  706.      */
  707.     protected long getTimeInMillis() {
  708.         if (!isTimeSet) updateTime();
  709.         return time;
  710.     }
  711.  
  712.     /**
  713.      * Sets this Calendar's current time from the given long value.
  714.      * @param date the new time in UTC milliseconds from the epoch.
  715.      */
  716.     protected void setTimeInMillis( long millis ) {
  717.         isTimeSet = true;
  718.         time = millis;
  719.         areFieldsSet = false;
  720.         if (!areFieldsSet) {
  721.             computeFields();
  722.             areFieldsSet = true;
  723.             areAllFieldsSet = true;
  724.         }
  725.     }
  726.  
  727.     /**
  728.      * Gets the value for a given time field.
  729.      * @param field the given time field.
  730.      * @return the value for the given time field.
  731.      */
  732.     public final int get(int field)
  733.     {
  734.         complete();
  735.         return fields[field];
  736.     }
  737.  
  738.     /**
  739.      * Gets the value for a given time field. This is an internal
  740.      * fast time field value getter for the subclasses.
  741.      * @param field the given time field.
  742.      * @return the value for the given time field.
  743.      */
  744.     protected final int internalGet(int field)
  745.     {
  746.         return fields[field];
  747.     }
  748.  
  749.     /**
  750.      * Sets the value for the given time field.  This is an internal
  751.      * fast setter for subclasses.  It does not affect the areFieldsSet, isTimeSet,
  752.      * or areAllFieldsSet flags.
  753.      */
  754.     final void internalSet(int field, int value)
  755.     {
  756.         fields[field] = value;
  757.     }
  758.  
  759.     /**
  760.      * Sets the time field with the given value.
  761.      * @param field the given time field.
  762.      * @param value the value to be set for the given time field.
  763.      */
  764.     public final void set(int field, int value)
  765.     {
  766.         isTimeSet = false;
  767.         fields[field] = value;
  768.         stamp[field] = nextStamp++;
  769.         areFieldsSet = false;
  770.         isSet[field] = true; // Remove later
  771.     }
  772.  
  773.     /**
  774.      * Sets the values for the fields year, month, and date.
  775.      * Previous values of other fields are retained.  If this is not desired,
  776.      * call <code>clear</code> first.
  777.      * @param year the value used to set the YEAR time field.
  778.      * @param month the value used to set the MONTH time field.
  779.      * Month value is 0-based. e.g., 0 for January.
  780.      * @param date the value used to set the DATE time field.
  781.      */
  782.     public final void set(int year, int month, int date)
  783.     {
  784.         set(YEAR, year);
  785.         set(MONTH, month);
  786.         set(DATE, date);
  787.     }
  788.  
  789.     /**
  790.      * Sets the values for the fields year, month, date, hour, and minute.
  791.      * Previous values of other fields are retained.  If this is not desired,
  792.      * call <code>clear</code> first.
  793.      * @param year the value used to set the YEAR time field.
  794.      * @param month the value used to set the MONTH time field.
  795.      * Month value is 0-based. e.g., 0 for January.
  796.      * @param date the value used to set the DATE time field.
  797.      * @param hour the value used to set the HOUR_OF_DAY time field.
  798.      * @param minute the value used to set the MINUTE time field.
  799.      */
  800.     public final void set(int year, int month, int date, int hour, int minute)
  801.     {
  802.         set(YEAR, year);
  803.         set(MONTH, month);
  804.         set(DATE, date);
  805.         set(HOUR_OF_DAY, hour);
  806.         set(MINUTE, minute);
  807.     }
  808.  
  809.     /**
  810.      * Sets the values for the fields year, month, date, hour, minute, and second.
  811.      * Previous values of other fields are retained.  If this is not desired,
  812.      * call <code>clear</code> first.
  813.      * @param year the value used to set the YEAR time field.
  814.      * @param month the value used to set the MONTH time field.
  815.      * Month value is 0-based. e.g., 0 for January.
  816.      * @param date the value used to set the DATE time field.
  817.      * @param hour the value used to set the HOUR_OF_DAY time field.
  818.      * @param minute the value used to set the MINUTE time field.
  819.      * @param second the value used to set the SECOND time field.
  820.      */
  821.     public final void set(int year, int month, int date, int hour, int minute,
  822.                           int second)
  823.     {
  824.         set(YEAR, year);
  825.         set(MONTH, month);
  826.         set(DATE, date);
  827.         set(HOUR_OF_DAY, hour);
  828.         set(MINUTE, minute);
  829.         set(SECOND, second);
  830.     }
  831.  
  832.     /**
  833.      * Clears the values of all the time fields.
  834.      */
  835.     public final void clear()
  836.     {
  837.         fields = new int[FIELD_COUNT];
  838.         stamp = new int[FIELD_COUNT];
  839.         areFieldsSet = false;
  840.         areAllFieldsSet = false;
  841.         isSet = new boolean[FIELD_COUNT]; // Remove later
  842.         isTimeSet = false;
  843.     }
  844.  
  845.     /**
  846.      * Clears the value in the given time field.
  847.      * @param field the time field to be cleared.
  848.      */
  849.     public final void clear(int field)
  850.     {
  851.         fields[field] = 0;
  852.         stamp[field] = UNSET;
  853.         areFieldsSet = false;
  854.         areAllFieldsSet = false;
  855.         isSet[field] = false; // Remove later
  856.         isTimeSet = false;
  857.     }
  858.  
  859.     /**
  860.      * Determines if the given time field has a value set.
  861.      * @return true if the given time field has a value set; false otherwise.
  862.      */
  863.     public final boolean isSet(int field)
  864.     {
  865.         return stamp[field] != UNSET;
  866.         // return isSet[field];
  867.     }
  868.  
  869.     /**
  870.      * Fills in any unset fields in the time field list.
  871.      */
  872.     protected void complete()
  873.     {
  874.         if (!isTimeSet) updateTime();
  875.         if (!areFieldsSet) {
  876.             computeFields(); // fills in unset fields
  877.             areFieldsSet = true;
  878.             areAllFieldsSet = true;
  879.         }
  880.     }
  881.  
  882.     /**
  883.      * Compares this calendar to the specified object.
  884.      * The result is <code>true</code> if and only if the argument is
  885.      * not <code>null</code> and is a <code>Calendar</code> object that
  886.      * represents the same calendar as this object.
  887.      * @param obj the object to compare with.
  888.      * @return <code>true</code> if the objects are the same;
  889.      * <code>false</code> otherwise.
  890.      */
  891.     public boolean equals(Object obj) {
  892.         if (this == obj)
  893.             return true;
  894.         if (!(obj instanceof Calendar))
  895.             return false;
  896.  
  897.         Calendar that = (Calendar)obj;
  898.  
  899.         return getTimeInMillis() == that.getTimeInMillis() &&
  900.             lenient == that.lenient &&
  901.             firstDayOfWeek == that.firstDayOfWeek &&
  902.             minimalDaysInFirstWeek == that.minimalDaysInFirstWeek &&
  903.             zone.equals(that.zone);
  904.     }
  905.  
  906.     /**
  907.      * Returns a hash code for this calendar.
  908.      * @return a hash code value for this object. 
  909.      */
  910.     public int hashCode() {
  911.         /* Don't include the time because (a) we don't want the hash value to
  912.          * move around just because a calendar is set to different times, and
  913.          * (b) we don't want to trigger a time computation just to get a hash.
  914.          * Note that it is not necessary for unequal objects to always have
  915.          * unequal hashes, but equal objects must have equal hashes.  */
  916.         return (lenient ? 1 : 0)
  917.             | (firstDayOfWeek << 1)
  918.             | (minimalDaysInFirstWeek << 4)
  919.             | (zone.hashCode() << 7);
  920.     }
  921.  
  922.     /**
  923.      * Compares the time field records.
  924.      * Equivalent to comparing result of conversion to UTC.
  925.      * @param when the Calendar to be compared with this Calendar.
  926.      * @return true if the current time of this Calendar is before
  927.      * the time of Calendar when; false otherwise.
  928.      */
  929.     public boolean before(Object when) {
  930.         return when instanceof Calendar &&
  931.             getTimeInMillis() < ((Calendar) when).getTimeInMillis();
  932.     }
  933.  
  934.     /**
  935.      * Compares the time field records.
  936.      * Equivalent to comparing result of conversion to UTC.
  937.      * @param when the Calendar to be compared with this Calendar.
  938.      * @return true if the current time of this Calendar is after
  939.      * the time of Calendar when; false otherwise.
  940.      */
  941.     public boolean after(Object when) {
  942.         return when instanceof Calendar &&
  943.             getTimeInMillis() > ((Calendar) when).getTimeInMillis();
  944.     }
  945.  
  946.     /**
  947.      * Date Arithmetic function.
  948.      * Adds the specified (signed) amount of time to the given time field,
  949.      * based on the calendar's rules. For example, to subtract 5 days from
  950.      * the current time of the calendar, you can achieve it by calling:
  951.      * <p>add(Calendar.DATE, -5).
  952.      * @param field the time field.
  953.      * @param amount the amount of date or time to be added to the field.
  954.      */
  955.     abstract public void add(int field, int amount);
  956.  
  957.     /**
  958.      * Time Field Rolling function.
  959.      * Rolls (up/down) a single unit of time on the given time field. For
  960.      * example, to roll the current date up by one day, you can achieve it
  961.      * by calling:
  962.      * <p>roll(Calendar.DATE, true).
  963.      * When rolling on the year or Calendar.YEAR field, it will roll the year
  964.      * value in the range between 1 and the value returned by calling
  965.      * getMaximum(Calendar.YEAR).
  966.      * When rolling on the month or Calendar.MONTH field, other fields like
  967.      * date might conflict and, need to be changed. For instance,
  968.      * rolling the month on the date 01/31/96 will result in 02/29/96.
  969.      * When rolling on the hour-in-day or Calendar.HOUR_OF_DAY field, it will
  970.      * roll the hour value in the range between 0 and 23, which is zero-based.
  971.      * @param field the time field.
  972.      * @param up indicates if the value of the specified time field is to be
  973.      * rolled up or rolled down. Use true if rolling up, false otherwise.
  974.      */
  975.     abstract public void roll(int field, boolean up);
  976.  
  977.     /**
  978.      * Time Field Rolling function.
  979.      * Rolls up or down the specified number of units on the given time field.
  980.      * (A negative roll amount means to roll down.)
  981.      * [NOTE:  This default implementation on Calendar just repeatedly calls the
  982.      * version of roll() that takes a boolean and rolls by one unit.  This may not
  983.      * always do the right thing.  For example, if the DAY_OF_MONTH field is 31,
  984.      * rolling through February will leave it set to 28.  The GregorianCalendar
  985.      * version of this function takes care of this problem.  Other subclasses
  986.      * should also provide overrides of this function that do the right thing.
  987.      */
  988.     public void roll(int field, int amount)
  989.     {
  990.         while (amount > 0) {
  991.             roll(field, true);
  992.             amount--;
  993.         }
  994.         while (amount < 0) {
  995.             roll(field, false);
  996.             amount++;
  997.         }
  998.     }
  999.  
  1000.     /**
  1001.      * Sets the time zone with the given time zone value.
  1002.      * @param value the given time zone.
  1003.      */
  1004.     public void setTimeZone(TimeZone value)
  1005.     {
  1006.         zone = value;
  1007.     }
  1008.  
  1009.     /**
  1010.      * Gets the time zone.
  1011.      * @return the time zone object associated with this calendar.
  1012.      */
  1013.     public TimeZone getTimeZone()
  1014.     {
  1015.         return zone;
  1016.     }
  1017.  
  1018.     /**
  1019.      * Specify whether or not date/time interpretation is to be lenient.  With
  1020.      * lenient interpretation, a date such as "February 942, 1996" will be
  1021.      * treated as being equivalent to the 941st day after February 1, 1996.
  1022.      * With strict interpretation, such dates will cause an exception to be
  1023.      * thrown.
  1024.      *
  1025.      * @see java.text.DateFormat#setLenient
  1026.      */
  1027.     public void setLenient(boolean lenient)
  1028.     {
  1029.         this.lenient = lenient;
  1030.     }
  1031.  
  1032.     /**
  1033.      * Tell whether date/time interpretation is to be lenient.
  1034.      */
  1035.     public boolean isLenient()
  1036.     {
  1037.         return lenient;
  1038.     }
  1039.  
  1040.     /**
  1041.      * Sets what the first day of the week is; e.g., Sunday in US,
  1042.      * Monday in France.
  1043.      * @param value the given first day of the week.
  1044.      */
  1045.     public void setFirstDayOfWeek(int value)
  1046.     {
  1047.         firstDayOfWeek = value;
  1048.     }
  1049.  
  1050.     /**
  1051.      * Gets what the first day of the week is; e.g., Sunday in US,
  1052.      * Monday in France.
  1053.      * @return the first day of the week.
  1054.      */
  1055.     public int getFirstDayOfWeek()
  1056.     {
  1057.         return firstDayOfWeek;
  1058.     }
  1059.  
  1060.     /**
  1061.      * Sets what the minimal days required in the first week of the year are;
  1062.      * For example, if the first week is defined as one that contains the first
  1063.      * day of the first month of a year, call the method with value 1. If it
  1064.      * must be a full week, use value 7.
  1065.      * @param value the given minimal days required in the first week
  1066.      * of the year.
  1067.      */
  1068.     public void setMinimalDaysInFirstWeek(int value)
  1069.     {
  1070.         minimalDaysInFirstWeek = value;
  1071.     }
  1072.  
  1073.     /**
  1074.      * Gets what the minimal days required in the first week of the year are;
  1075.      * e.g., if the first week is defined as one that contains the first day
  1076.      * of the first month of a year, getMinimalDaysInFirstWeek returns 1. If
  1077.      * the minimal days required must be a full week, getMinimalDaysInFirstWeek
  1078.      * returns 7.
  1079.      * @return the minimal days required in the first week of the year.
  1080.      */
  1081.     public int getMinimalDaysInFirstWeek()
  1082.     {
  1083.         return minimalDaysInFirstWeek;
  1084.     }
  1085.  
  1086.     /**
  1087.      * Gets the minimum value for the given time field.
  1088.      * e.g., for Gregorian DAY_OF_MONTH, 1.
  1089.      * @param field the given time field.
  1090.      * @return the minimum value for the given time field.
  1091.      */
  1092.     abstract public int getMinimum(int field);
  1093.  
  1094.     /**
  1095.      * Gets the maximum value for the given time field.
  1096.      * e.g. for Gregorian DAY_OF_MONTH, 31.
  1097.      * @param field the given time field.
  1098.      * @return the maximum value for the given time field.
  1099.      */
  1100.     abstract public int getMaximum(int field);
  1101.  
  1102.     /**
  1103.      * Gets the highest minimum value for the given field if varies.
  1104.      * Otherwise same as getMinimum(). For Gregorian, no difference.
  1105.      * @param field the given time field.
  1106.      * @return the highest minimum value for the given time field.
  1107.      */
  1108.     abstract public int getGreatestMinimum(int field);
  1109.  
  1110.     /**
  1111.      * Gets the lowest maximum value for the given field if varies.
  1112.      * Otherwise same as getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28.
  1113.      * @param field the given time field.
  1114.      * @return the lowest maximum value for the given time field.
  1115.      */
  1116.     abstract public int getLeastMaximum(int field);
  1117.  
  1118.     /**
  1119.      * Return the minimum value that this field could have, given the current date.
  1120.      * For the Gregorian calendar, this is the same as getMinimum() and getGreatestMinimum().
  1121.      *
  1122.      * The version of this function on Calendar uses an iterative algorithm to determine the
  1123.      * actual minimum value for the field.  There is almost always a more efficient way to
  1124.      * accomplish this (in most cases, you can simply return getMinimum()).  GregorianCalendar
  1125.      * overrides this function with a more efficient implementation.
  1126.      *
  1127.      * @param field the field to determine the minimum of
  1128.      * @return the minimum of the given field for the current date of this Calendar
  1129.      */
  1130.     public int getActualMinimum(int field) {
  1131.         int fieldValue = getGreatestMinimum(field);
  1132.         int endValue = getMinimum(field);
  1133.  
  1134.         // if we know that the minimum value is always the same, just return it
  1135.         if (fieldValue == endValue) {
  1136.             return fieldValue;
  1137.         }
  1138.  
  1139.         // clone the calendar so we don't mess with the real one, and set it to
  1140.         // accept anything for the field values
  1141.         Calendar work = (Calendar)this.clone();
  1142.         work.setLenient(true);
  1143.  
  1144.         // now try each value from getLeastMaximum() to getMaximum() one by one until
  1145.         // we get a value that normalizes to another value.  The last value that
  1146.         // normalizes to itself is the actual minimum for the current date
  1147.         int result = fieldValue;
  1148.  
  1149.         do {
  1150.             work.set(field, fieldValue);
  1151.             if (work.get(field) != fieldValue) {
  1152.                 break;
  1153.             } else {
  1154.                 result = fieldValue;
  1155.                 fieldValue--;
  1156.             }
  1157.         } while (fieldValue >= endValue);
  1158.  
  1159.         return result;
  1160.     }
  1161.  
  1162.     /**
  1163.      * Return the maximum value that this field could have, given the current date.
  1164.      * For example, with the date "Feb 3, 1997" and the DAY_OF_MONTH field, the actual
  1165.      * maximum would be 28; for "Feb 3, 1996" it s 29.  Similarly for a Hebrew calendar,
  1166.      * for some years the actual maximum for MONTH is 12, and for others 13.
  1167.      *
  1168.      * The version of this function on Calendar uses an iterative algorithm to determine the
  1169.      * actual maximum value for the field.  There is almost always a more efficient way to
  1170.      * accomplish this (in most cases, you can simply return getMaximum()).  GregorianCalendar
  1171.      * overrides this function with a more efficient implementation.
  1172.      *
  1173.      * @param field the field to determine the maximum of
  1174.      * @return the maximum of the given field for the current date of this Calendar
  1175.      */
  1176.     public int getActualMaximum(int field) {
  1177.         int fieldValue = getLeastMaximum(field);
  1178.         int endValue = getMaximum(field);
  1179.  
  1180.         // if we know that the maximum value is always the same, just return it
  1181.         if (fieldValue == endValue) {
  1182.             return fieldValue;
  1183.         }
  1184.  
  1185.         // clone the calendar so we don't mess with the real one, and set it to
  1186.         // accept anything for the field values
  1187.         Calendar work = (Calendar)this.clone();
  1188.         work.setLenient(true);
  1189.  
  1190.         // if we're counting weeks, set the day of the week to Sunday.  We know the
  1191.         // last week of a month or year will contain the first day of the week.
  1192.         if (field == WEEK_OF_YEAR || field == WEEK_OF_MONTH)
  1193.             work.set(DAY_OF_WEEK, firstDayOfWeek);
  1194.  
  1195.         // now try each value from getLeastMaximum() to getMaximum() one by one until
  1196.         // we get a value that normalizes to another value.  The last value that
  1197.         // normalizes to itself is the actual maximum for the current date
  1198.         int result = fieldValue;
  1199.  
  1200.         do {
  1201.             work.set(field, fieldValue);
  1202.             if (work.get(field) != fieldValue) {
  1203.                 break;
  1204.             } else {
  1205.                 result = fieldValue;
  1206.                 fieldValue++;
  1207.             }
  1208.         } while (fieldValue <= endValue);
  1209.  
  1210.         return result;
  1211.     }
  1212.  
  1213.     /**
  1214.      * Overrides Cloneable
  1215.      */
  1216.     public Object clone()
  1217.     {
  1218.         try {
  1219.             Calendar other = (Calendar) super.clone();
  1220.  
  1221.             other.fields = new int[FIELD_COUNT];
  1222.             other.isSet = new boolean[FIELD_COUNT];
  1223.             other.stamp = new int[FIELD_COUNT];
  1224.             System.arraycopy(this.fields, 0, other.fields, 0, FIELD_COUNT);
  1225.             System.arraycopy(this.isSet, 0, other.isSet, 0, FIELD_COUNT);
  1226.             System.arraycopy(this.stamp, 0, other.stamp, 0, FIELD_COUNT);
  1227.  
  1228.             other.zone = (TimeZone) zone.clone();
  1229.             return other;
  1230.         }
  1231.         catch (CloneNotSupportedException e) {
  1232.             // this shouldn't happen, since we are Cloneable
  1233.             throw new InternalError();
  1234.         }
  1235.     }
  1236.  
  1237.     private static final String[] FIELD_NAME = {
  1238.         ",ERA=", ",YEAR=", ",MONTH=", ",WEEK_OF_YEAR=", ",WEEK_OF_MONTH=", ",DAY_OF_MONTH=",
  1239.         ",DAY_OF_YEAR=", ",DAY_OF_WEEK=", ",DAY_OF_WEEK_IN_MONTH=", ",AM_PM=", ",HOUR=",
  1240.         ",HOUR_OF_DAY=", ",MINUTE=", ",SECOND=", ",MILLISECOND=", ",ZONE_OFFSET=",
  1241.         ",DST_OFFSET="
  1242.     };
  1243.  
  1244.     /**
  1245.      * Return a string representation of this calendar. This method 
  1246.      * is intended to be used only for debugging purposes, and the 
  1247.      * format of the returned string may vary between implementations. 
  1248.      * The returned string may be empty but may not be <code>null</code>.
  1249.      * 
  1250.      * @return  a string representation of this calendar.
  1251.      */
  1252.     public String toString() {
  1253.         StringBuffer buffer = new StringBuffer();
  1254.         buffer.append(getClass().getName());
  1255.         buffer.append("[time=");
  1256.         buffer.append(isTimeSet ? String.valueOf(time) : "?");
  1257.         buffer.append(",areFieldsSet=");
  1258.         buffer.append(areFieldsSet);
  1259.         buffer.append(",areAllFieldsSet=");
  1260.         buffer.append(areAllFieldsSet);
  1261.         buffer.append(",lenient=");
  1262.         buffer.append(lenient);
  1263.         buffer.append(",zone=");
  1264.         buffer.append(zone);
  1265.         buffer.append(",firstDayOfWeek=");
  1266.         buffer.append(firstDayOfWeek);
  1267.         buffer.append(",minimalDaysInFirstWeek=");
  1268.         buffer.append(minimalDaysInFirstWeek);
  1269.         for (int i=0; i<FIELD_COUNT; ++i) {
  1270.             buffer.append(FIELD_NAME[i]);
  1271.             buffer.append(isSet(i) ? String.valueOf(fields[i]) : "?");
  1272.         }
  1273.         buffer.append(']');
  1274.         return buffer.toString();
  1275.     }
  1276.  
  1277.     // =======================privates===============================
  1278.  
  1279.     /**
  1280.      * Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent.
  1281.      * They are used to figure out the week count for a specific date for
  1282.      * a given locale. These must be set when a Calendar is constructed.
  1283.      * @param desiredLocale the given locale.
  1284.      */
  1285.     private void setWeekCountData(Locale desiredLocale)
  1286.     {
  1287.     /* try to get the Locale data from the cache */
  1288.     int[] data = (int[]) cachedLocaleData.get(desiredLocale);
  1289.     if (data == null) {  /* cache miss */
  1290.         ResourceBundle resource
  1291.         = ResourceBundle.getBundle("java.text.resources.LocaleElements",
  1292.                        desiredLocale);
  1293.         String[] dateTimePatterns =
  1294.         resource.getStringArray("DateTimeElements");
  1295.         data = new int[2];
  1296.         data[0] = Integer.parseInt(dateTimePatterns[0]);
  1297.         data[1] = Integer.parseInt(dateTimePatterns[1]);
  1298.         /* cache update */
  1299.         cachedLocaleData.put(desiredLocale, data);
  1300.     }
  1301.     firstDayOfWeek = data[0];
  1302.     minimalDaysInFirstWeek = data[1];
  1303.     }
  1304.  
  1305.     /**
  1306.      * Recompute the time and update the status fields isTimeSet
  1307.      * and areFieldsSet.  Callers should check isTimeSet and only
  1308.      * call this method if isTimeSet is false.
  1309.      */
  1310.     private void updateTime() {
  1311.         computeTime();
  1312.         // If we are lenient, we need to recompute the fields to normalize
  1313.         // the values.  Also, if we haven't set all the fields yet (i.e.,
  1314.         // in a newly-created object), we need to fill in the fields. [LIU]
  1315.         if (isLenient() || !areAllFieldsSet) areFieldsSet = false;
  1316.         isTimeSet = true;
  1317.     }
  1318.  
  1319.     /**
  1320.      * Save the state of this object to a stream (i.e., serialize it).
  1321.      *
  1322.      * Ideally, <code>Calendar</code> would only write out its state data and
  1323.      * the current time, and not write any field data out, such as
  1324.      * <code>fields[]</code>, <code>isTimeSet</code>, <code>areFieldsSet</code>,
  1325.      * and <code>isSet[]</code>.  <code>nextStamp</code> also should not be part
  1326.      * of the persistent state. Unfortunately, this didn't happen before JDK 1.1
  1327.      * shipped. To be compatible with JDK 1.1, we will always have to write out
  1328.      * the field values and state flags.  However, <code>nextStamp</code> can be
  1329.      * removed from the serialization stream; this will probably happen in the
  1330.      * near future.
  1331.      */
  1332.     private void writeObject(ObjectOutputStream stream)
  1333.          throws IOException
  1334.     {
  1335.         // Try to compute the time correctly, for the future (stream
  1336.         // version 2) in which we don't write out fields[] or isSet[].
  1337.         if (!isTimeSet) {
  1338.             try {
  1339.                 updateTime();
  1340.             }
  1341.             catch (IllegalArgumentException e) {}
  1342.         }
  1343.  
  1344.         // Write out the 1.1 FCS object.
  1345.         stream.defaultWriteObject();
  1346.     }
  1347.  
  1348.     /**
  1349.      * Reconstitute this object from a stream (i.e., deserialize it).
  1350.      */
  1351.     private void readObject(ObjectInputStream stream)
  1352.          throws IOException, ClassNotFoundException
  1353.     {
  1354.         stream.defaultReadObject();
  1355.  
  1356.         stamp = new int[FIELD_COUNT];
  1357.  
  1358.         // Starting with version 2 (not implemented yet), we expect that
  1359.         // fields[], isSet[], isTimeSet, and areFieldsSet may not be
  1360.         // streamed out anymore.  We expect 'time' to be correct.
  1361.         if (serialVersionOnStream >= 2)
  1362.         {
  1363.             isTimeSet = true;
  1364.             if (fields == null) fields = new int[FIELD_COUNT];
  1365.             if (isSet == null) isSet = new boolean[FIELD_COUNT];
  1366.         }
  1367.         else if (serialVersionOnStream == 0)
  1368.         {
  1369.             for (int i=0; i<FIELD_COUNT; ++i)
  1370.                 stamp[i] = isSet[i] ? INTERNALLY_SET : UNSET;
  1371.         }
  1372.  
  1373.         serialVersionOnStream = currentSerialVersion;
  1374.     }
  1375. }
  1376.