Save This Page
Home » openjdk-7 » java » util » [javadoc | source]
    1   /*
    2    * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   
   26   /*
   27    * (C) Copyright Taligent, Inc. 1996-1998 - All Rights Reserved
   28    * (C) Copyright IBM Corp. 1996-1998 - All Rights Reserved
   29    *
   30    *   The original version of this source code and documentation is copyrighted
   31    * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
   32    * materials are provided under terms of a License Agreement between Taligent
   33    * and Sun. This technology is protected by multiple US and International
   34    * patents. This notice and attribution to Taligent may not be removed.
   35    *   Taligent is a registered trademark of Taligent, Inc.
   36    *
   37    */
   38   
   39   package java.util;
   40   
   41   import java.io.IOException;
   42   import java.io.ObjectInputStream;
   43   import java.io.ObjectOutputStream;
   44   import java.io.OptionalDataException;
   45   import java.io.Serializable;
   46   import java.security.AccessControlContext;
   47   import java.security.AccessController;
   48   import java.security.PermissionCollection;
   49   import java.security.PrivilegedActionException;
   50   import java.security.PrivilegedExceptionAction;
   51   import java.security.ProtectionDomain;
   52   import java.text.DateFormat;
   53   import java.text.DateFormatSymbols;
   54   import java.util.concurrent.ConcurrentHashMap;
   55   import java.util.concurrent.ConcurrentMap;
   56   import sun.util.BuddhistCalendar;
   57   import sun.util.calendar.ZoneInfo;
   58   import sun.util.resources.LocaleData;
   59   
   60   /**
   61    * The <code>Calendar</code> class is an abstract class that provides methods
   62    * for converting between a specific instant in time and a set of {@link
   63    * #fields calendar fields} such as <code>YEAR</code>, <code>MONTH</code>,
   64    * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, and so on, and for
   65    * manipulating the calendar fields, such as getting the date of the next
   66    * week. An instant in time can be represented by a millisecond value that is
   67    * an offset from the <a name="Epoch"><em>Epoch</em></a>, January 1, 1970
   68    * 00:00:00.000 GMT (Gregorian).
   69    *
   70    * <p>The class also provides additional fields and methods for
   71    * implementing a concrete calendar system outside the package. Those
   72    * fields and methods are defined as <code>protected</code>.
   73    *
   74    * <p>
   75    * Like other locale-sensitive classes, <code>Calendar</code> provides a
   76    * class method, <code>getInstance</code>, for getting a generally useful
   77    * object of this type. <code>Calendar</code>'s <code>getInstance</code> method
   78    * returns a <code>Calendar</code> object whose
   79    * calendar fields have been initialized with the current date and time:
   80    * <blockquote>
   81    * <pre>
   82    *     Calendar rightNow = Calendar.getInstance();
   83    * </pre>
   84    * </blockquote>
   85    *
   86    * <p>A <code>Calendar</code> object can produce all the calendar field values
   87    * needed to implement the date-time formatting for a particular language and
   88    * calendar style (for example, Japanese-Gregorian, Japanese-Traditional).
   89    * <code>Calendar</code> defines the range of values returned by
   90    * certain calendar fields, as well as their meaning.  For example,
   91    * the first month of the calendar system has value <code>MONTH ==
   92    * JANUARY</code> for all calendars.  Other values are defined by the
   93    * concrete subclass, such as <code>ERA</code>.  See individual field
   94    * documentation and subclass documentation for details.
   95    *
   96    * <h4>Getting and Setting Calendar Field Values</h4>
   97    *
   98    * <p>The calendar field values can be set by calling the <code>set</code>
   99    * methods. Any field values set in a <code>Calendar</code> will not be
  100    * interpreted until it needs to calculate its time value (milliseconds from
  101    * the Epoch) or values of the calendar fields. Calling the
  102    * <code>get</code>, <code>getTimeInMillis</code>, <code>getTime</code>,
  103    * <code>add</code> and <code>roll</code> involves such calculation.
  104    *
  105    * <h4>Leniency</h4>
  106    *
  107    * <p><code>Calendar</code> has two modes for interpreting the calendar
  108    * fields, <em>lenient</em> and <em>non-lenient</em>.  When a
  109    * <code>Calendar</code> is in lenient mode, it accepts a wider range of
  110    * calendar field values than it produces.  When a <code>Calendar</code>
  111    * recomputes calendar field values for return by <code>get()</code>, all of
  112    * the calendar fields are normalized. For example, a lenient
  113    * <code>GregorianCalendar</code> interprets <code>MONTH == JANUARY</code>,
  114    * <code>DAY_OF_MONTH == 32</code> as February 1.
  115   
  116    * <p>When a <code>Calendar</code> is in non-lenient mode, it throws an
  117    * exception if there is any inconsistency in its calendar fields. For
  118    * example, a <code>GregorianCalendar</code> always produces
  119    * <code>DAY_OF_MONTH</code> values between 1 and the length of the month. A
  120    * non-lenient <code>GregorianCalendar</code> throws an exception upon
  121    * calculating its time or calendar field values if any out-of-range field
  122    * value has been set.
  123    *
  124    * <h4><a name="first_week">First Week</a></h4>
  125    *
  126    * <code>Calendar</code> defines a locale-specific seven day week using two
  127    * parameters: the first day of the week and the minimal days in first week
  128    * (from 1 to 7).  These numbers are taken from the locale resource data when a
  129    * <code>Calendar</code> is constructed.  They may also be specified explicitly
  130    * through the methods for setting their values.
  131    *
  132    * <p>When setting or getting the <code>WEEK_OF_MONTH</code> or
  133    * <code>WEEK_OF_YEAR</code> fields, <code>Calendar</code> must determine the
  134    * first week of the month or year as a reference point.  The first week of a
  135    * month or year is defined as the earliest seven day period beginning on
  136    * <code>getFirstDayOfWeek()</code> and containing at least
  137    * <code>getMinimalDaysInFirstWeek()</code> days of that month or year.  Weeks
  138    * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow
  139    * it.  Note that the normalized numbering returned by <code>get()</code> may be
  140    * different.  For example, a specific <code>Calendar</code> subclass may
  141    * designate the week before week 1 of a year as week <code><i>n</i></code> of
  142    * the previous year.
  143    *
  144    * <h4>Calendar Fields Resolution</h4>
  145    *
  146    * When computing a date and time from the calendar fields, there
  147    * may be insufficient information for the computation (such as only
  148    * year and month with no day of month), or there may be inconsistent
  149    * information (such as Tuesday, July 15, 1996 (Gregorian) -- July 15,
  150    * 1996 is actually a Monday). <code>Calendar</code> will resolve
  151    * calendar field values to determine the date and time in the
  152    * following way.
  153    *
  154    * <p>If there is any conflict in calendar field values,
  155    * <code>Calendar</code> gives priorities to calendar fields that have been set
  156    * more recently. The following are the default combinations of the
  157    * calendar fields. The most recent combination, as determined by the
  158    * most recently set single field, will be used.
  159    *
  160    * <p><a name="date_resolution">For the date fields</a>:
  161    * <blockquote>
  162    * <pre>
  163    * YEAR + MONTH + DAY_OF_MONTH
  164    * YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
  165    * YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
  166    * YEAR + DAY_OF_YEAR
  167    * YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
  168    * </pre></blockquote>
  169    *
  170    * <a name="time_resolution">For the time of day fields</a>:
  171    * <blockquote>
  172    * <pre>
  173    * HOUR_OF_DAY
  174    * AM_PM + HOUR
  175    * </pre></blockquote>
  176    *
  177    * <p>If there are any calendar fields whose values haven't been set in the selected
  178    * field combination, <code>Calendar</code> uses their default values. The default
  179    * value of each field may vary by concrete calendar systems. For example, in
  180    * <code>GregorianCalendar</code>, the default of a field is the same as that
  181    * of the start of the Epoch: i.e., <code>YEAR = 1970</code>, <code>MONTH =
  182    * JANUARY</code>, <code>DAY_OF_MONTH = 1</code>, etc.
  183    *
  184    * <p>
  185    * <strong>Note:</strong> There are certain possible ambiguities in
  186    * interpretation of certain singular times, which are resolved in the
  187    * following ways:
  188    * <ol>
  189    *     <li> 23:59 is the last minute of the day and 00:00 is the first
  190    *          minute of the next day. Thus, 23:59 on Dec 31, 1999 &lt; 00:00 on
  191    *          Jan 1, 2000 &lt; 00:01 on Jan 1, 2000.
  192    *
  193    *     <li> Although historically not precise, midnight also belongs to "am",
  194    *          and noon belongs to "pm", so on the same day,
  195    *          12:00 am (midnight) &lt; 12:01 am, and 12:00 pm (noon) &lt; 12:01 pm
  196    * </ol>
  197    *
  198    * <p>
  199    * The date or time format strings are not part of the definition of a
  200    * calendar, as those must be modifiable or overridable by the user at
  201    * runtime. Use {@link DateFormat}
  202    * to format dates.
  203    *
  204    * <h4>Field Manipulation</h4>
  205    *
  206    * The calendar fields can be changed using three methods:
  207    * <code>set()</code>, <code>add()</code>, and <code>roll()</code>.</p>
  208    *
  209    * <p><strong><code>set(f, value)</code></strong> changes calendar field
  210    * <code>f</code> to <code>value</code>.  In addition, it sets an
  211    * internal member variable to indicate that calendar field <code>f</code> has
  212    * been changed. Although calendar field <code>f</code> is changed immediately,
  213    * the calendar's time value in milliseconds is not recomputed until the next call to
  214    * <code>get()</code>, <code>getTime()</code>, <code>getTimeInMillis()</code>,
  215    * <code>add()</code>, or <code>roll()</code> is made. Thus, multiple calls to
  216    * <code>set()</code> do not trigger multiple, unnecessary
  217    * computations. As a result of changing a calendar field using
  218    * <code>set()</code>, other calendar fields may also change, depending on the
  219    * calendar field, the calendar field value, and the calendar system. In addition,
  220    * <code>get(f)</code> will not necessarily return <code>value</code> set by
  221    * the call to the <code>set</code> method
  222    * after the calendar fields have been recomputed. The specifics are determined by
  223    * the concrete calendar class.</p>
  224    *
  225    * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
  226    * originally set to August 31, 1999. Calling <code>set(Calendar.MONTH,
  227    * Calendar.SEPTEMBER)</code> sets the date to September 31,
  228    * 1999. This is a temporary internal representation that resolves to
  229    * October 1, 1999 if <code>getTime()</code>is then called. However, a
  230    * call to <code>set(Calendar.DAY_OF_MONTH, 30)</code> before the call to
  231    * <code>getTime()</code> sets the date to September 30, 1999, since
  232    * no recomputation occurs after <code>set()</code> itself.</p>
  233    *
  234    * <p><strong><code>add(f, delta)</code></strong> adds <code>delta</code>
  235    * to field <code>f</code>.  This is equivalent to calling <code>set(f,
  236    * get(f) + delta)</code> with two adjustments:</p>
  237    *
  238    * <blockquote>
  239    *   <p><strong>Add rule 1</strong>. The value of field <code>f</code>
  240    *   after the call minus the value of field <code>f</code> before the
  241    *   call is <code>delta</code>, modulo any overflow that has occurred in
  242    *   field <code>f</code>. Overflow occurs when a field value exceeds its
  243    *   range and, as a result, the next larger field is incremented or
  244    *   decremented and the field value is adjusted back into its range.</p>
  245    *
  246    *   <p><strong>Add rule 2</strong>. If a smaller field is expected to be
  247    *   invariant, but it is impossible for it to be equal to its
  248    *   prior value because of changes in its minimum or maximum after field
  249    *   <code>f</code> is changed or other constraints, such as time zone
  250    *   offset changes, then its value is adjusted to be as close
  251    *   as possible to its expected value. A smaller field represents a
  252    *   smaller unit of time. <code>HOUR</code> is a smaller field than
  253    *   <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields
  254    *   that are not expected to be invariant. The calendar system
  255    *   determines what fields are expected to be invariant.</p>
  256    * </blockquote>
  257    *
  258    * <p>In addition, unlike <code>set()</code>, <code>add()</code> forces
  259    * an immediate recomputation of the calendar's milliseconds and all
  260    * fields.</p>
  261    *
  262    * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
  263    * originally set to August 31, 1999. Calling <code>add(Calendar.MONTH,
  264    * 13)</code> sets the calendar to September 30, 2000. <strong>Add rule
  265    * 1</strong> sets the <code>MONTH</code> field to September, since
  266    * adding 13 months to August gives September of the next year. Since
  267    * <code>DAY_OF_MONTH</code> cannot be 31 in September in a
  268    * <code>GregorianCalendar</code>, <strong>add rule 2</strong> sets the
  269    * <code>DAY_OF_MONTH</code> to 30, the closest possible value. Although
  270    * it is a smaller field, <code>DAY_OF_WEEK</code> is not adjusted by
  271    * rule 2, since it is expected to change when the month changes in a
  272    * <code>GregorianCalendar</code>.</p>
  273    *
  274    * <p><strong><code>roll(f, delta)</code></strong> adds
  275    * <code>delta</code> to field <code>f</code> without changing larger
  276    * fields. This is equivalent to calling <code>add(f, delta)</code> with
  277    * the following adjustment:</p>
  278    *
  279    * <blockquote>
  280    *   <p><strong>Roll rule</strong>. Larger fields are unchanged after the
  281    *   call. A larger field represents a larger unit of
  282    *   time. <code>DAY_OF_MONTH</code> is a larger field than
  283    *   <code>HOUR</code>.</p>
  284    * </blockquote>
  285    *
  286    * <p><em>Example</em>: See {@link java.util.GregorianCalendar#roll(int, int)}.
  287    *
  288    * <p><strong>Usage model</strong>. To motivate the behavior of
  289    * <code>add()</code> and <code>roll()</code>, consider a user interface
  290    * component with increment and decrement buttons for the month, day, and
  291    * year, and an underlying <code>GregorianCalendar</code>. If the
  292    * interface reads January 31, 1999 and the user presses the month
  293    * increment button, what should it read? If the underlying
  294    * implementation uses <code>set()</code>, it might read March 3, 1999. A
  295    * better result would be February 28, 1999. Furthermore, if the user
  296    * presses the month increment button again, it should read March 31,
  297    * 1999, not March 28, 1999. By saving the original date and using either
  298    * <code>add()</code> or <code>roll()</code>, depending on whether larger
  299    * fields should be affected, the user interface can behave as most users
  300    * will intuitively expect.</p>
  301    *
  302    * @see          java.lang.System#currentTimeMillis()
  303    * @see          Date
  304    * @see          GregorianCalendar
  305    * @see          TimeZone
  306    * @see          java.text.DateFormat
  307    * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu
  308    * @since JDK1.1
  309    */
  310   public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {
  311   
  312       // Data flow in Calendar
  313       // ---------------------
  314   
  315       // The current time is represented in two ways by Calendar: as UTC
  316       // milliseconds from the epoch (1 January 1970 0:00 UTC), and as local
  317       // fields such as MONTH, HOUR, AM_PM, etc.  It is possible to compute the
  318       // millis from the fields, and vice versa.  The data needed to do this
  319       // conversion is encapsulated by a TimeZone object owned by the Calendar.
  320       // The data provided by the TimeZone object may also be overridden if the
  321       // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
  322       // keeps track of what information was most recently set by the caller, and
  323       // uses that to compute any other information as needed.
  324   
  325       // If the user sets the fields using set(), the data flow is as follows.
  326       // This is implemented by the Calendar subclass's computeTime() method.
  327       // During this process, certain fields may be ignored.  The disambiguation
  328       // algorithm for resolving which fields to pay attention to is described
  329       // in the class documentation.
  330   
  331       //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
  332       //           |
  333       //           | Using Calendar-specific algorithm
  334       //           V
  335       //   local standard millis
  336       //           |
  337       //           | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
  338       //           V
  339       //   UTC millis (in time data member)
  340   
  341       // If the user sets the UTC millis using setTime() or setTimeInMillis(),
  342       // the data flow is as follows.  This is implemented by the Calendar
  343       // subclass's computeFields() method.
  344   
  345       //   UTC millis (in time data member)
  346       //           |
  347       //           | Using TimeZone getOffset()
  348       //           V
  349       //   local standard millis
  350       //           |
  351       //           | Using Calendar-specific algorithm
  352       //           V
  353       //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
  354   
  355       // In general, a round trip from fields, through local and UTC millis, and
  356       // back out to fields is made when necessary.  This is implemented by the
  357       // complete() method.  Resolving a partial set of fields into a UTC millis
  358       // value allows all remaining fields to be generated from that value.  If
  359       // the Calendar is lenient, the fields are also renormalized to standard
  360       // ranges when they are regenerated.
  361   
  362       /**
  363        * Field number for <code>get</code> and <code>set</code> indicating the
  364        * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific
  365        * value; see subclass documentation.
  366        *
  367        * @see GregorianCalendar#AD
  368        * @see GregorianCalendar#BC
  369        */
  370       public final static int ERA = 0;
  371   
  372       /**
  373        * Field number for <code>get</code> and <code>set</code> indicating the
  374        * year. This is a calendar-specific value; see subclass documentation.
  375        */
  376       public final static int YEAR = 1;
  377   
  378       /**
  379        * Field number for <code>get</code> and <code>set</code> indicating the
  380        * month. This is a calendar-specific value. The first month of
  381        * the year in the Gregorian and Julian calendars is
  382        * <code>JANUARY</code> which is 0; the last depends on the number
  383        * of months in a year.
  384        *
  385        * @see #JANUARY
  386        * @see #FEBRUARY
  387        * @see #MARCH
  388        * @see #APRIL
  389        * @see #MAY
  390        * @see #JUNE
  391        * @see #JULY
  392        * @see #AUGUST
  393        * @see #SEPTEMBER
  394        * @see #OCTOBER
  395        * @see #NOVEMBER
  396        * @see #DECEMBER
  397        * @see #UNDECIMBER
  398        */
  399       public final static int MONTH = 2;
  400   
  401       /**
  402        * Field number for <code>get</code> and <code>set</code> indicating the
  403        * week number within the current year.  The first week of the year, as
  404        * defined by <code>getFirstDayOfWeek()</code> and
  405        * <code>getMinimalDaysInFirstWeek()</code>, has value 1.  Subclasses define
  406        * the value of <code>WEEK_OF_YEAR</code> for days before the first week of
  407        * the year.
  408        *
  409        * @see #getFirstDayOfWeek
  410        * @see #getMinimalDaysInFirstWeek
  411        */
  412       public final static int WEEK_OF_YEAR = 3;
  413   
  414       /**
  415        * Field number for <code>get</code> and <code>set</code> indicating the
  416        * week number within the current month.  The first week of the month, as
  417        * defined by <code>getFirstDayOfWeek()</code> and
  418        * <code>getMinimalDaysInFirstWeek()</code>, has value 1.  Subclasses define
  419        * the value of <code>WEEK_OF_MONTH</code> for days before the first week of
  420        * the month.
  421        *
  422        * @see #getFirstDayOfWeek
  423        * @see #getMinimalDaysInFirstWeek
  424        */
  425       public final static int WEEK_OF_MONTH = 4;
  426   
  427       /**
  428        * Field number for <code>get</code> and <code>set</code> indicating the
  429        * day of the month. This is a synonym for <code>DAY_OF_MONTH</code>.
  430        * The first day of the month has value 1.
  431        *
  432        * @see #DAY_OF_MONTH
  433        */
  434       public final static int DATE = 5;
  435   
  436       /**
  437        * Field number for <code>get</code> and <code>set</code> indicating the
  438        * day of the month. This is a synonym for <code>DATE</code>.
  439        * The first day of the month has value 1.
  440        *
  441        * @see #DATE
  442        */
  443       public final static int DAY_OF_MONTH = 5;
  444   
  445       /**
  446        * Field number for <code>get</code> and <code>set</code> indicating the day
  447        * number within the current year.  The first day of the year has value 1.
  448        */
  449       public final static int DAY_OF_YEAR = 6;
  450   
  451       /**
  452        * Field number for <code>get</code> and <code>set</code> indicating the day
  453        * of the week.  This field takes values <code>SUNDAY</code>,
  454        * <code>MONDAY</code>, <code>TUESDAY</code>, <code>WEDNESDAY</code>,
  455        * <code>THURSDAY</code>, <code>FRIDAY</code>, and <code>SATURDAY</code>.
  456        *
  457        * @see #SUNDAY
  458        * @see #MONDAY
  459        * @see #TUESDAY
  460        * @see #WEDNESDAY
  461        * @see #THURSDAY
  462        * @see #FRIDAY
  463        * @see #SATURDAY
  464        */
  465       public final static int DAY_OF_WEEK = 7;
  466   
  467       /**
  468        * Field number for <code>get</code> and <code>set</code> indicating the
  469        * ordinal number of the day of the week within the current month. Together
  470        * with the <code>DAY_OF_WEEK</code> field, this uniquely specifies a day
  471        * within a month.  Unlike <code>WEEK_OF_MONTH</code> and
  472        * <code>WEEK_OF_YEAR</code>, this field's value does <em>not</em> depend on
  473        * <code>getFirstDayOfWeek()</code> or
  474        * <code>getMinimalDaysInFirstWeek()</code>.  <code>DAY_OF_MONTH 1</code>
  475        * through <code>7</code> always correspond to <code>DAY_OF_WEEK_IN_MONTH
  476        * 1</code>; <code>8</code> through <code>14</code> correspond to
  477        * <code>DAY_OF_WEEK_IN_MONTH 2</code>, and so on.
  478        * <code>DAY_OF_WEEK_IN_MONTH 0</code> indicates the week before
  479        * <code>DAY_OF_WEEK_IN_MONTH 1</code>.  Negative values count back from the
  480        * end of the month, so the last Sunday of a month is specified as
  481        * <code>DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1</code>.  Because
  482        * negative values count backward they will usually be aligned differently
  483        * within the month than positive values.  For example, if a month has 31
  484        * days, <code>DAY_OF_WEEK_IN_MONTH -1</code> will overlap
  485        * <code>DAY_OF_WEEK_IN_MONTH 5</code> and the end of <code>4</code>.
  486        *
  487        * @see #DAY_OF_WEEK
  488        * @see #WEEK_OF_MONTH
  489        */
  490       public final static int DAY_OF_WEEK_IN_MONTH = 8;
  491   
  492       /**
  493        * Field number for <code>get</code> and <code>set</code> indicating
  494        * whether the <code>HOUR</code> is before or after noon.
  495        * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>.
  496        *
  497        * @see #AM
  498        * @see #PM
  499        * @see #HOUR
  500        */
  501       public final static int AM_PM = 9;
  502   
  503       /**
  504        * Field number for <code>get</code> and <code>set</code> indicating the
  505        * hour of the morning or afternoon. <code>HOUR</code> is used for the
  506        * 12-hour clock (0 - 11). Noon and midnight are represented by 0, not by 12.
  507        * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10.
  508        *
  509        * @see #AM_PM
  510        * @see #HOUR_OF_DAY
  511        */
  512       public final static int HOUR = 10;
  513   
  514       /**
  515        * Field number for <code>get</code> and <code>set</code> indicating the
  516        * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock.
  517        * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22.
  518        *
  519        * @see #HOUR
  520        */
  521       public final static int HOUR_OF_DAY = 11;
  522   
  523       /**
  524        * Field number for <code>get</code> and <code>set</code> indicating the
  525        * minute within the hour.
  526        * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4.
  527        */
  528       public final static int MINUTE = 12;
  529   
  530       /**
  531        * Field number for <code>get</code> and <code>set</code> indicating the
  532        * second within the minute.
  533        * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15.
  534        */
  535       public final static int SECOND = 13;
  536   
  537       /**
  538        * Field number for <code>get</code> and <code>set</code> indicating the
  539        * millisecond within the second.
  540        * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250.
  541        */
  542       public final static int MILLISECOND = 14;
  543   
  544       /**
  545        * Field number for <code>get</code> and <code>set</code>
  546        * indicating the raw offset from GMT in milliseconds.
  547        * <p>
  548        * This field reflects the correct GMT offset value of the time
  549        * zone of this <code>Calendar</code> if the
  550        * <code>TimeZone</code> implementation subclass supports
  551        * historical GMT offset changes.
  552        */
  553       public final static int ZONE_OFFSET = 15;
  554   
  555       /**
  556        * Field number for <code>get</code> and <code>set</code> indicating the
  557        * daylight saving offset in milliseconds.
  558        * <p>
  559        * This field reflects the correct daylight saving offset value of
  560        * the time zone of this <code>Calendar</code> if the
  561        * <code>TimeZone</code> implementation subclass supports
  562        * historical Daylight Saving Time schedule changes.
  563        */
  564       public final static int DST_OFFSET = 16;
  565   
  566       /**
  567        * The number of distinct fields recognized by <code>get</code> and <code>set</code>.
  568        * Field numbers range from <code>0..FIELD_COUNT-1</code>.
  569        */
  570       public final static int FIELD_COUNT = 17;
  571   
  572       /**
  573        * Value of the {@link #DAY_OF_WEEK} field indicating
  574        * Sunday.
  575        */
  576       public final static int SUNDAY = 1;
  577   
  578       /**
  579        * Value of the {@link #DAY_OF_WEEK} field indicating
  580        * Monday.
  581        */
  582       public final static int MONDAY = 2;
  583   
  584       /**
  585        * Value of the {@link #DAY_OF_WEEK} field indicating
  586        * Tuesday.
  587        */
  588       public final static int TUESDAY = 3;
  589   
  590       /**
  591        * Value of the {@link #DAY_OF_WEEK} field indicating
  592        * Wednesday.
  593        */
  594       public final static int WEDNESDAY = 4;
  595   
  596       /**
  597        * Value of the {@link #DAY_OF_WEEK} field indicating
  598        * Thursday.
  599        */
  600       public final static int THURSDAY = 5;
  601   
  602       /**
  603        * Value of the {@link #DAY_OF_WEEK} field indicating
  604        * Friday.
  605        */
  606       public final static int FRIDAY = 6;
  607   
  608       /**
  609        * Value of the {@link #DAY_OF_WEEK} field indicating
  610        * Saturday.
  611        */
  612       public final static int SATURDAY = 7;
  613   
  614       /**
  615        * Value of the {@link #MONTH} field indicating the
  616        * first month of the year in the Gregorian and Julian calendars.
  617        */
  618       public final static int JANUARY = 0;
  619   
  620       /**
  621        * Value of the {@link #MONTH} field indicating the
  622        * second month of the year in the Gregorian and Julian calendars.
  623        */
  624       public final static int FEBRUARY = 1;
  625   
  626       /**
  627        * Value of the {@link #MONTH} field indicating the
  628        * third month of the year in the Gregorian and Julian calendars.
  629        */
  630       public final static int MARCH = 2;
  631   
  632       /**
  633        * Value of the {@link #MONTH} field indicating the
  634        * fourth month of the year in the Gregorian and Julian calendars.
  635        */
  636       public final static int APRIL = 3;
  637   
  638       /**
  639        * Value of the {@link #MONTH} field indicating the
  640        * fifth month of the year in the Gregorian and Julian calendars.
  641        */
  642       public final static int MAY = 4;
  643   
  644       /**
  645        * Value of the {@link #MONTH} field indicating the
  646        * sixth month of the year in the Gregorian and Julian calendars.
  647        */
  648       public final static int JUNE = 5;
  649   
  650       /**
  651        * Value of the {@link #MONTH} field indicating the
  652        * seventh month of the year in the Gregorian and Julian calendars.
  653        */
  654       public final static int JULY = 6;
  655   
  656       /**
  657        * Value of the {@link #MONTH} field indicating the
  658        * eighth month of the year in the Gregorian and Julian calendars.
  659        */
  660       public final static int AUGUST = 7;
  661   
  662       /**
  663        * Value of the {@link #MONTH} field indicating the
  664        * ninth month of the year in the Gregorian and Julian calendars.
  665        */
  666       public final static int SEPTEMBER = 8;
  667   
  668       /**
  669        * Value of the {@link #MONTH} field indicating the
  670        * tenth month of the year in the Gregorian and Julian calendars.
  671        */
  672       public final static int OCTOBER = 9;
  673   
  674       /**
  675        * Value of the {@link #MONTH} field indicating the
  676        * eleventh month of the year in the Gregorian and Julian calendars.
  677        */
  678       public final static int NOVEMBER = 10;
  679   
  680       /**
  681        * Value of the {@link #MONTH} field indicating the
  682        * twelfth month of the year in the Gregorian and Julian calendars.
  683        */
  684       public final static int DECEMBER = 11;
  685   
  686       /**
  687        * Value of the {@link #MONTH} field indicating the
  688        * thirteenth month of the year. Although <code>GregorianCalendar</code>
  689        * does not use this value, lunar calendars do.
  690        */
  691       public final static int UNDECIMBER = 12;
  692   
  693       /**
  694        * Value of the {@link #AM_PM} field indicating the
  695        * period of the day from midnight to just before noon.
  696        */
  697       public final static int AM = 0;
  698   
  699       /**
  700        * Value of the {@link #AM_PM} field indicating the
  701        * period of the day from noon to just before midnight.
  702        */
  703       public final static int PM = 1;
  704   
  705       /**
  706        * A style specifier for {@link #getDisplayNames(int, int, Locale)
  707        * getDisplayNames} indicating names in all styles, such as
  708        * "January" and "Jan".
  709        *
  710        * @see #SHORT
  711        * @see #LONG
  712        * @since 1.6
  713        */
  714       public static final int ALL_STYLES = 0;
  715   
  716       /**
  717        * A style specifier for {@link #getDisplayName(int, int, Locale)
  718        * getDisplayName} and {@link #getDisplayNames(int, int, Locale)
  719        * getDisplayNames} indicating a short name, such as "Jan".
  720        *
  721        * @see #LONG
  722        * @since 1.6
  723        */
  724       public static final int SHORT = 1;
  725   
  726       /**
  727        * A style specifier for {@link #getDisplayName(int, int, Locale)
  728        * getDisplayName} and {@link #getDisplayNames(int, int, Locale)
  729        * getDisplayNames} indicating a long name, such as "January".
  730        *
  731        * @see #SHORT
  732        * @since 1.6
  733        */
  734       public static final int LONG = 2;
  735   
  736       // Internal notes:
  737       // Calendar contains two kinds of time representations: current "time" in
  738       // milliseconds, and a set of calendar "fields" representing the current time.
  739       // The two representations are usually in sync, but can get out of sync
  740       // as follows.
  741       // 1. Initially, no fields are set, and the time is invalid.
  742       // 2. If the time is set, all fields are computed and in sync.
  743       // 3. If a single field is set, the time is invalid.
  744       // Recomputation of the time and fields happens when the object needs
  745       // to return a result to the user, or use a result for a computation.
  746   
  747       /**
  748        * The calendar field values for the currently set time for this calendar.
  749        * This is an array of <code>FIELD_COUNT</code> integers, with index values
  750        * <code>ERA</code> through <code>DST_OFFSET</code>.
  751        * @serial
  752        */
  753       protected int           fields[];
  754   
  755       /**
  756        * The flags which tell if a specified calendar field for the calendar is set.
  757        * A new object has no fields set.  After the first call to a method
  758        * which generates the fields, they all remain set after that.
  759        * This is an array of <code>FIELD_COUNT</code> booleans, with index values
  760        * <code>ERA</code> through <code>DST_OFFSET</code>.
  761        * @serial
  762        */
  763       protected boolean       isSet[];
  764   
  765       /**
  766        * Pseudo-time-stamps which specify when each field was set. There
  767        * are two special values, UNSET and COMPUTED. Values from
  768        * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values.
  769        */
  770       transient private int   stamp[];
  771   
  772       /**
  773        * The currently set time for this calendar, expressed in milliseconds after
  774        * January 1, 1970, 0:00:00 GMT.
  775        * @see #isTimeSet
  776        * @serial
  777        */
  778       protected long          time;
  779   
  780       /**
  781        * True if then the value of <code>time</code> is valid.
  782        * The time is made invalid by a change to an item of <code>field[]</code>.
  783        * @see #time
  784        * @serial
  785        */
  786       protected boolean       isTimeSet;
  787   
  788       /**
  789        * True if <code>fields[]</code> are in sync with the currently set time.
  790        * If false, then the next attempt to get the value of a field will
  791        * force a recomputation of all fields from the current value of
  792        * <code>time</code>.
  793        * @serial
  794        */
  795       protected boolean       areFieldsSet;
  796   
  797       /**
  798        * True if all fields have been set.
  799        * @serial
  800        */
  801       transient boolean       areAllFieldsSet;
  802   
  803       /**
  804        * <code>True</code> if this calendar allows out-of-range field values during computation
  805        * of <code>time</code> from <code>fields[]</code>.
  806        * @see #setLenient
  807        * @see #isLenient
  808        * @serial
  809        */
  810       private boolean         lenient = true;
  811   
  812       /**
  813        * The <code>TimeZone</code> used by this calendar. <code>Calendar</code>
  814        * uses the time zone data to translate between locale and GMT time.
  815        * @serial
  816        */
  817       private TimeZone        zone;
  818   
  819       /**
  820        * <code>True</code> if zone references to a shared TimeZone object.
  821        */
  822       transient private boolean sharedZone = false;
  823   
  824       /**
  825        * The first day of the week, with possible values <code>SUNDAY</code>,
  826        * <code>MONDAY</code>, etc.  This is a locale-dependent value.
  827        * @serial
  828        */
  829       private int             firstDayOfWeek;
  830   
  831       /**
  832        * The number of days required for the first week in a month or year,
  833        * with possible values from 1 to 7.  This is a locale-dependent value.
  834        * @serial
  835        */
  836       private int             minimalDaysInFirstWeek;
  837   
  838       /**
  839        * Cache to hold the firstDayOfWeek and minimalDaysInFirstWeek
  840        * of a Locale.
  841        */
  842       private static final ConcurrentMap<Locale, int[]> cachedLocaleData
  843           = new ConcurrentHashMap<Locale, int[]>(3);
  844   
  845       // Special values of stamp[]
  846       /**
  847        * The corresponding fields[] has no value.
  848        */
  849       private static final int        UNSET = 0;
  850   
  851       /**
  852        * The value of the corresponding fields[] has been calculated internally.
  853        */
  854       private static final int        COMPUTED = 1;
  855   
  856       /**
  857        * The value of the corresponding fields[] has been set externally. Stamp
  858        * values which are greater than 1 represents the (pseudo) time when the
  859        * corresponding fields[] value was set.
  860        */
  861       private static final int        MINIMUM_USER_STAMP = 2;
  862   
  863       /**
  864        * The mask value that represents all of the fields.
  865        */
  866       static final int ALL_FIELDS = (1 << FIELD_COUNT) - 1;
  867   
  868       /**
  869        * The next available value for <code>stamp[]</code>, an internal array.
  870        * This actually should not be written out to the stream, and will probably
  871        * be removed from the stream in the near future.  In the meantime,
  872        * a value of <code>MINIMUM_USER_STAMP</code> should be used.
  873        * @serial
  874        */
  875       private int             nextStamp = MINIMUM_USER_STAMP;
  876   
  877       // the internal serial version which says which version was written
  878       // - 0 (default) for version up to JDK 1.1.5
  879       // - 1 for version from JDK 1.1.6, which writes a correct 'time' value
  880       //     as well as compatible values for other fields.  This is a
  881       //     transitional format.
  882       // - 2 (not implemented yet) a future version, in which fields[],
  883       //     areFieldsSet, and isTimeSet become transient, and isSet[] is
  884       //     removed. In JDK 1.1.6 we write a format compatible with version 2.
  885       static final int        currentSerialVersion = 1;
  886   
  887       /**
  888        * The version of the serialized data on the stream.  Possible values:
  889        * <dl>
  890        * <dt><b>0</b> or not present on stream</dt>
  891        * <dd>
  892        * JDK 1.1.5 or earlier.
  893        * </dd>
  894        * <dt><b>1</b></dt>
  895        * <dd>
  896        * JDK 1.1.6 or later.  Writes a correct 'time' value
  897        * as well as compatible values for other fields.  This is a
  898        * transitional format.
  899        * </dd>
  900        * </dl>
  901        * When streaming out this class, the most recent format
  902        * and the highest allowable <code>serialVersionOnStream</code>
  903        * is written.
  904        * @serial
  905        * @since JDK1.1.6
  906        */
  907       private int             serialVersionOnStream = currentSerialVersion;
  908   
  909       // Proclaim serialization compatibility with JDK 1.1
  910       static final long       serialVersionUID = -1807547505821590642L;
  911   
  912       // Mask values for calendar fields
  913       final static int ERA_MASK           = (1 << ERA);
  914       final static int YEAR_MASK          = (1 << YEAR);
  915       final static int MONTH_MASK         = (1 << MONTH);
  916       final static int WEEK_OF_YEAR_MASK  = (1 << WEEK_OF_YEAR);
  917       final static int WEEK_OF_MONTH_MASK = (1 << WEEK_OF_MONTH);
  918       final static int DAY_OF_MONTH_MASK  = (1 << DAY_OF_MONTH);
  919       final static int DATE_MASK          = DAY_OF_MONTH_MASK;
  920       final static int DAY_OF_YEAR_MASK   = (1 << DAY_OF_YEAR);
  921       final static int DAY_OF_WEEK_MASK   = (1 << DAY_OF_WEEK);
  922       final static int DAY_OF_WEEK_IN_MONTH_MASK  = (1 << DAY_OF_WEEK_IN_MONTH);
  923       final static int AM_PM_MASK         = (1 << AM_PM);
  924       final static int HOUR_MASK          = (1 << HOUR);
  925       final static int HOUR_OF_DAY_MASK   = (1 << HOUR_OF_DAY);
  926       final static int MINUTE_MASK        = (1 << MINUTE);
  927       final static int SECOND_MASK        = (1 << SECOND);
  928       final static int MILLISECOND_MASK   = (1 << MILLISECOND);
  929       final static int ZONE_OFFSET_MASK   = (1 << ZONE_OFFSET);
  930       final static int DST_OFFSET_MASK    = (1 << DST_OFFSET);
  931   
  932       /**
  933        * Constructs a Calendar with the default time zone
  934        * and locale.
  935        * @see     TimeZone#getDefault
  936        */
  937       protected Calendar()
  938       {
  939           this(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
  940           sharedZone = true;
  941       }
  942   
  943       /**
  944        * Constructs a calendar with the specified time zone and locale.
  945        *
  946        * @param zone the time zone to use
  947        * @param aLocale the locale for the week data
  948        */
  949       protected Calendar(TimeZone zone, Locale aLocale)
  950       {
  951           fields = new int[FIELD_COUNT];
  952           isSet = new boolean[FIELD_COUNT];
  953           stamp = new int[FIELD_COUNT];
  954   
  955           this.zone = zone;
  956           setWeekCountData(aLocale);
  957       }
  958   
  959       /**
  960        * Gets a calendar using the default time zone and locale. The
  961        * <code>Calendar</code> returned is based on the current time
  962        * in the default time zone with the default locale.
  963        *
  964        * @return a Calendar.
  965        */
  966       public static Calendar getInstance()
  967       {
  968           Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault(Locale.Category.FORMAT));
  969           cal.sharedZone = true;
  970           return cal;
  971       }
  972   
  973       /**
  974        * Gets a calendar using the specified time zone and default locale.
  975        * The <code>Calendar</code> returned is based on the current time
  976        * in the given time zone with the default locale.
  977        *
  978        * @param zone the time zone to use
  979        * @return a Calendar.
  980        */
  981       public static Calendar getInstance(TimeZone zone)
  982       {
  983           return createCalendar(zone, Locale.getDefault(Locale.Category.FORMAT));
  984       }
  985   
  986       /**
  987        * Gets a calendar using the default time zone and specified locale.
  988        * The <code>Calendar</code> returned is based on the current time
  989        * in the default time zone with the given locale.
  990        *
  991        * @param aLocale the locale for the week data
  992        * @return a Calendar.
  993        */
  994       public static Calendar getInstance(Locale aLocale)
  995       {
  996           Calendar cal = createCalendar(TimeZone.getDefaultRef(), aLocale);
  997           cal.sharedZone = true;
  998           return cal;
  999       }
 1000   
 1001       /**
 1002        * Gets a calendar with the specified time zone and locale.
 1003        * The <code>Calendar</code> returned is based on the current time
 1004        * in the given time zone with the given locale.
 1005        *
 1006        * @param zone the time zone to use
 1007        * @param aLocale the locale for the week data
 1008        * @return a Calendar.
 1009        */
 1010       public static Calendar getInstance(TimeZone zone,
 1011                                          Locale aLocale)
 1012       {
 1013           return createCalendar(zone, aLocale);
 1014       }
 1015   
 1016       private static Calendar createCalendar(TimeZone zone,
 1017                                              Locale aLocale)
 1018       {
 1019           Calendar cal = null;
 1020   
 1021           String caltype = aLocale.getUnicodeLocaleType("ca");
 1022           if (caltype == null) {
 1023               // Calendar type is not specified.
 1024               // If the specified locale is a Thai locale,
 1025               // returns a BuddhistCalendar instance.
 1026               if ("th".equals(aLocale.getLanguage())
 1027                       && ("TH".equals(aLocale.getCountry()))) {
 1028                   cal = new BuddhistCalendar(zone, aLocale);
 1029               } else {
 1030                   cal = new GregorianCalendar(zone, aLocale);
 1031               }
 1032           } else if (caltype.equals("japanese")) {
 1033               cal = new JapaneseImperialCalendar(zone, aLocale);
 1034           } else if (caltype.equals("buddhist")) {
 1035               cal = new BuddhistCalendar(zone, aLocale);
 1036           } else {
 1037               // Unsupported calendar type.
 1038               // Use Gregorian calendar as a fallback.
 1039               cal = new GregorianCalendar(zone, aLocale);
 1040           }
 1041   
 1042           return cal;
 1043       }
 1044   
 1045       /**
 1046        * Returns an array of all locales for which the <code>getInstance</code>
 1047        * methods of this class can return localized instances.
 1048        * The array returned must contain at least a <code>Locale</code>
 1049        * instance equal to {@link java.util.Locale#US Locale.US}.
 1050        *
 1051        * @return An array of locales for which localized
 1052        *         <code>Calendar</code> instances are available.
 1053        */
 1054       public static synchronized Locale[] getAvailableLocales()
 1055       {
 1056           return DateFormat.getAvailableLocales();
 1057       }
 1058   
 1059       /**
 1060        * Converts the current calendar field values in {@link #fields fields[]}
 1061        * to the millisecond time value
 1062        * {@link #time}.
 1063        *
 1064        * @see #complete()
 1065        * @see #computeFields()
 1066        */
 1067       protected abstract void computeTime();
 1068   
 1069       /**
 1070        * Converts the current millisecond time value {@link #time}
 1071        * to calendar field values in {@link #fields fields[]}.
 1072        * This allows you to sync up the calendar field values with
 1073        * a new time that is set for the calendar.  The time is <em>not</em>
 1074        * recomputed first; to recompute the time, then the fields, call the
 1075        * {@link #complete()} method.
 1076        *
 1077        * @see #computeTime()
 1078        */
 1079       protected abstract void computeFields();
 1080   
 1081       /**
 1082        * Returns a <code>Date</code> object representing this
 1083        * <code>Calendar</code>'s time value (millisecond offset from the <a
 1084        * href="#Epoch">Epoch</a>").
 1085        *
 1086        * @return a <code>Date</code> representing the time value.
 1087        * @see #setTime(Date)
 1088        * @see #getTimeInMillis()
 1089        */
 1090       public final Date getTime() {
 1091           return new Date(getTimeInMillis());
 1092       }
 1093   
 1094       /**
 1095        * Sets this Calendar's time with the given <code>Date</code>.
 1096        * <p>
 1097        * Note: Calling <code>setTime()</code> with
 1098        * <code>Date(Long.MAX_VALUE)</code> or <code>Date(Long.MIN_VALUE)</code>
 1099        * may yield incorrect field values from <code>get()</code>.
 1100        *
 1101        * @param date the given Date.
 1102        * @see #getTime()
 1103        * @see #setTimeInMillis(long)
 1104        */
 1105       public final void setTime(Date date) {
 1106           setTimeInMillis(date.getTime());
 1107       }
 1108   
 1109       /**
 1110        * Returns this Calendar's time value in milliseconds.
 1111        *
 1112        * @return the current time as UTC milliseconds from the epoch.
 1113        * @see #getTime()
 1114        * @see #setTimeInMillis(long)
 1115        */
 1116       public long getTimeInMillis() {
 1117           if (!isTimeSet) {
 1118               updateTime();
 1119           }
 1120           return time;
 1121       }
 1122   
 1123       /**
 1124        * Sets this Calendar's current time from the given long value.
 1125        *
 1126        * @param millis the new time in UTC milliseconds from the epoch.
 1127        * @see #setTime(Date)
 1128        * @see #getTimeInMillis()
 1129        */
 1130       public void setTimeInMillis(long millis) {
 1131           // If we don't need to recalculate the calendar field values,
 1132           // do nothing.
 1133           if (time == millis && isTimeSet && areFieldsSet && areAllFieldsSet
 1134               && (zone instanceof ZoneInfo) && !((ZoneInfo)zone).isDirty()) {
 1135               return;
 1136           }
 1137           time = millis;
 1138           isTimeSet = true;
 1139           areFieldsSet = false;
 1140           computeFields();
 1141           areAllFieldsSet = areFieldsSet = true;
 1142       }
 1143   
 1144       /**
 1145        * Returns the value of the given calendar field. In lenient mode,
 1146        * all calendar fields are normalized. In non-lenient mode, all
 1147        * calendar fields are validated and this method throws an
 1148        * exception if any calendar fields have out-of-range values. The
 1149        * normalization and validation are handled by the
 1150        * {@link #complete()} method, which process is calendar
 1151        * system dependent.
 1152        *
 1153        * @param field the given calendar field.
 1154        * @return the value for the given calendar field.
 1155        * @throws ArrayIndexOutOfBoundsException if the specified field is out of range
 1156        *             (<code>field &lt; 0 || field &gt;= FIELD_COUNT</code>).
 1157        * @see #set(int,int)
 1158        * @see #complete()
 1159        */
 1160       public int get(int field)
 1161       {
 1162           complete();
 1163           return internalGet(field);
 1164       }
 1165   
 1166       /**
 1167        * Returns the value of the given calendar field. This method does
 1168        * not involve normalization or validation of the field value.
 1169        *
 1170        * @param field the given calendar field.
 1171        * @return the value for the given calendar field.
 1172        * @see #get(int)
 1173        */
 1174       protected final int internalGet(int field)
 1175       {
 1176           return fields[field];
 1177       }
 1178   
 1179       /**
 1180        * Sets the value of the given calendar field. This method does
 1181        * not affect any setting state of the field in this
 1182        * <code>Calendar</code> instance.
 1183        *
 1184        * @throws IndexOutOfBoundsException if the specified field is out of range
 1185        *             (<code>field &lt; 0 || field &gt;= FIELD_COUNT</code>).
 1186        * @see #areFieldsSet
 1187        * @see #isTimeSet
 1188        * @see #areAllFieldsSet
 1189        * @see #set(int,int)
 1190        */
 1191       final void internalSet(int field, int value)
 1192       {
 1193           fields[field] = value;
 1194       }
 1195   
 1196       /**
 1197        * Sets the given calendar field to the given value. The value is not
 1198        * interpreted by this method regardless of the leniency mode.
 1199        *
 1200        * @param field the given calendar field.
 1201        * @param value the value to be set for the given calendar field.
 1202        * @throws ArrayIndexOutOfBoundsException if the specified field is out of range
 1203        *             (<code>field &lt; 0 || field &gt;= FIELD_COUNT</code>).
 1204        * in non-lenient mode.
 1205        * @see #set(int,int,int)
 1206        * @see #set(int,int,int,int,int)
 1207        * @see #set(int,int,int,int,int,int)
 1208        * @see #get(int)
 1209        */
 1210       public void set(int field, int value)
 1211       {
 1212           // If the fields are partially normalized, calculate all the
 1213           // fields before changing any fields.
 1214           if (areFieldsSet && !areAllFieldsSet) {
 1215               computeFields();
 1216           }
 1217           internalSet(field, value);
 1218           isTimeSet = false;
 1219           areFieldsSet = false;
 1220           isSet[field] = true;
 1221           stamp[field] = nextStamp++;
 1222           if (nextStamp == Integer.MAX_VALUE) {
 1223               adjustStamp();
 1224           }
 1225       }
 1226   
 1227       /**
 1228        * Sets the values for the calendar fields <code>YEAR</code>,
 1229        * <code>MONTH</code>, and <code>DAY_OF_MONTH</code>.
 1230        * Previous values of other calendar fields are retained.  If this is not desired,
 1231        * call {@link #clear()} first.
 1232        *
 1233        * @param year the value used to set the <code>YEAR</code> calendar field.
 1234        * @param month the value used to set the <code>MONTH</code> calendar field.
 1235        * Month value is 0-based. e.g., 0 for January.
 1236        * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field.
 1237        * @see #set(int,int)
 1238        * @see #set(int,int,int,int,int)
 1239        * @see #set(int,int,int,int,int,int)
 1240        */
 1241       public final void set(int year, int month, int date)
 1242       {
 1243           set(YEAR, year);
 1244           set(MONTH, month);
 1245           set(DATE, date);
 1246       }
 1247   
 1248       /**
 1249        * Sets the values for the calendar fields <code>YEAR</code>,
 1250        * <code>MONTH</code>, <code>DAY_OF_MONTH</code>,
 1251        * <code>HOUR_OF_DAY</code>, and <code>MINUTE</code>.
 1252        * Previous values of other fields are retained.  If this is not desired,
 1253        * call {@link #clear()} first.
 1254        *
 1255        * @param year the value used to set the <code>YEAR</code> calendar field.
 1256        * @param month the value used to set the <code>MONTH</code> calendar field.
 1257        * Month value is 0-based. e.g., 0 for January.
 1258        * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field.
 1259        * @param hourOfDay the value used to set the <code>HOUR_OF_DAY</code> calendar field.
 1260        * @param minute the value used to set the <code>MINUTE</code> calendar field.
 1261        * @see #set(int,int)
 1262        * @see #set(int,int,int)
 1263        * @see #set(int,int,int,int,int,int)
 1264        */
 1265       public final void set(int year, int month, int date, int hourOfDay, int minute)
 1266       {
 1267           set(YEAR, year);
 1268           set(MONTH, month);
 1269           set(DATE, date);
 1270           set(HOUR_OF_DAY, hourOfDay);
 1271           set(MINUTE, minute);
 1272       }
 1273   
 1274       /**
 1275        * Sets the values for the fields <code>YEAR</code>, <code>MONTH</code>,
 1276        * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, <code>MINUTE</code>, and
 1277        * <code>SECOND</code>.
 1278        * Previous values of other fields are retained.  If this is not desired,
 1279        * call {@link #clear()} first.
 1280        *
 1281        * @param year the value used to set the <code>YEAR</code> calendar field.
 1282        * @param month the value used to set the <code>MONTH</code> calendar field.
 1283        * Month value is 0-based. e.g., 0 for January.
 1284        * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field.
 1285        * @param hourOfDay the value used to set the <code>HOUR_OF_DAY</code> calendar field.
 1286        * @param minute the value used to set the <code>MINUTE</code> calendar field.
 1287        * @param second the value used to set the <code>SECOND</code> calendar field.
 1288        * @see #set(int,int)
 1289        * @see #set(int,int,int)
 1290        * @see #set(int,int,int,int,int)
 1291        */
 1292       public final void set(int year, int month, int date, int hourOfDay, int minute,
 1293                             int second)
 1294       {
 1295           set(YEAR, year);
 1296           set(MONTH, month);
 1297           set(DATE, date);
 1298           set(HOUR_OF_DAY, hourOfDay);
 1299           set(MINUTE, minute);
 1300           set(SECOND, second);
 1301       }
 1302   
 1303       /**
 1304        * Sets all the calendar field values and the time value
 1305        * (millisecond offset from the <a href="#Epoch">Epoch</a>) of
 1306        * this <code>Calendar</code> undefined. This means that {@link
 1307        * #isSet(int) isSet()} will return <code>false</code> for all the
 1308        * calendar fields, and the date and time calculations will treat
 1309        * the fields as if they had never been set. A
 1310        * <code>Calendar</code> implementation class may use its specific
 1311        * default field values for date/time calculations. For example,
 1312        * <code>GregorianCalendar</code> uses 1970 if the
 1313        * <code>YEAR</code> field value is undefined.
 1314        *
 1315        * @see #clear(int)
 1316        */
 1317       public final void clear()
 1318       {
 1319           for (int i = 0; i < fields.length; ) {
 1320               stamp[i] = fields[i] = 0; // UNSET == 0
 1321               isSet[i++] = false;
 1322           }
 1323           areAllFieldsSet = areFieldsSet = false;
 1324           isTimeSet = false;
 1325       }
 1326   
 1327       /**
 1328        * Sets the given calendar field value and the time value
 1329        * (millisecond offset from the <a href="#Epoch">Epoch</a>) of
 1330        * this <code>Calendar</code> undefined. This means that {@link
 1331        * #isSet(int) isSet(field)} will return <code>false</code>, and
 1332        * the date and time calculations will treat the field as if it
 1333        * had never been set. A <code>Calendar</code> implementation
 1334        * class may use the field's specific default value for date and
 1335        * time calculations.
 1336        *
 1337        * <p>The {@link #HOUR_OF_DAY}, {@link #HOUR} and {@link #AM_PM}
 1338        * fields are handled independently and the <a
 1339        * href="#time_resolution">the resolution rule for the time of
 1340        * day</a> is applied. Clearing one of the fields doesn't reset
 1341        * the hour of day value of this <code>Calendar</code>. Use {@link
 1342        * #set(int,int) set(Calendar.HOUR_OF_DAY, 0)} to reset the hour
 1343        * value.
 1344        *
 1345        * @param field the calendar field to be cleared.
 1346        * @see #clear()
 1347        */
 1348       public final void clear(int field)
 1349       {
 1350           fields[field] = 0;
 1351           stamp[field] = UNSET;
 1352           isSet[field] = false;
 1353   
 1354           areAllFieldsSet = areFieldsSet = false;
 1355           isTimeSet = false;
 1356       }
 1357   
 1358       /**
 1359        * Determines if the given calendar field has a value set,
 1360        * including cases that the value has been set by internal fields
 1361        * calculations triggered by a <code>get</code> method call.
 1362        *
 1363        * @return <code>true</code> if the given calendar field has a value set;
 1364        * <code>false</code> otherwise.
 1365        */
 1366       public final boolean isSet(int field)
 1367       {
 1368           return stamp[field] != UNSET;
 1369       }
 1370   
 1371       /**
 1372        * Returns the string representation of the calendar
 1373        * <code>field</code> value in the given <code>style</code> and
 1374        * <code>locale</code>.  If no string representation is
 1375        * applicable, <code>null</code> is returned. This method calls
 1376        * {@link Calendar#get(int) get(field)} to get the calendar
 1377        * <code>field</code> value if the string representation is
 1378        * applicable to the given calendar <code>field</code>.
 1379        *
 1380        * <p>For example, if this <code>Calendar</code> is a
 1381        * <code>GregorianCalendar</code> and its date is 2005-01-01, then
 1382        * the string representation of the {@link #MONTH} field would be
 1383        * "January" in the long style in an English locale or "Jan" in
 1384        * the short style. However, no string representation would be
 1385        * available for the {@link #DAY_OF_MONTH} field, and this method
 1386        * would return <code>null</code>.
 1387        *
 1388        * <p>The default implementation supports the calendar fields for
 1389        * which a {@link DateFormatSymbols} has names in the given
 1390        * <code>locale</code>.
 1391        *
 1392        * @param field
 1393        *        the calendar field for which the string representation
 1394        *        is returned
 1395        * @param style
 1396        *        the style applied to the string representation; one of
 1397        *        {@link #SHORT} or {@link #LONG}.
 1398        * @param locale
 1399        *        the locale for the string representation
 1400        * @return the string representation of the given
 1401        *        <code>field</code> in the given <code>style</code>, or
 1402        *        <code>null</code> if no string representation is
 1403        *        applicable.
 1404        * @exception IllegalArgumentException
 1405        *        if <code>field</code> or <code>style</code> is invalid,
 1406        *        or if this <code>Calendar</code> is non-lenient and any
 1407        *        of the calendar fields have invalid values
 1408        * @exception NullPointerException
 1409        *        if <code>locale</code> is null
 1410        * @since 1.6
 1411        */
 1412       public String getDisplayName(int field, int style, Locale locale) {
 1413           if (!checkDisplayNameParams(field, style, ALL_STYLES, LONG, locale,
 1414                                       ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) {
 1415               return null;
 1416           }
 1417   
 1418           DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale);
 1419           String[] strings = getFieldStrings(field, style, symbols);
 1420           if (strings != null) {
 1421               int fieldValue = get(field);
 1422               if (fieldValue < strings.length) {
 1423                   return strings[fieldValue];
 1424               }
 1425           }
 1426           return null;
 1427       }
 1428   
 1429       /**
 1430        * Returns a <code>Map</code> containing all names of the calendar
 1431        * <code>field</code> in the given <code>style</code> and
 1432        * <code>locale</code> and their corresponding field values. For
 1433        * example, if this <code>Calendar</code> is a {@link
 1434        * GregorianCalendar}, the returned map would contain "Jan" to
 1435        * {@link #JANUARY}, "Feb" to {@link #FEBRUARY}, and so on, in the
 1436        * {@linkplain #SHORT short} style in an English locale.
 1437        *
 1438        * <p>The values of other calendar fields may be taken into
 1439        * account to determine a set of display names. For example, if
 1440        * this <code>Calendar</code> is a lunisolar calendar system and
 1441        * the year value given by the {@link #YEAR} field has a leap
 1442        * month, this method would return month names containing the leap
 1443        * month name, and month names are mapped to their values specific
 1444        * for the year.
 1445        *
 1446        * <p>The default implementation supports display names contained in
 1447        * a {@link DateFormatSymbols}. For example, if <code>field</code>
 1448        * is {@link #MONTH} and <code>style</code> is {@link
 1449        * #ALL_STYLES}, this method returns a <code>Map</code> containing
 1450        * all strings returned by {@link DateFormatSymbols#getShortMonths()}
 1451        * and {@link DateFormatSymbols#getMonths()}.
 1452        *
 1453        * @param field
 1454        *        the calendar field for which the display names are returned
 1455        * @param style
 1456        *        the style applied to the display names; one of {@link
 1457        *        #SHORT}, {@link #LONG}, or {@link #ALL_STYLES}.
 1458        * @param locale
 1459        *        the locale for the display names
 1460        * @return a <code>Map</code> containing all display names in
 1461        *        <code>style</code> and <code>locale</code> and their
 1462        *        field values, or <code>null</code> if no display names
 1463        *        are defined for <code>field</code>
 1464        * @exception IllegalArgumentException
 1465        *        if <code>field</code> or <code>style</code> is invalid,
 1466        *        or if this <code>Calendar</code> is non-lenient and any
 1467        *        of the calendar fields have invalid values
 1468        * @exception NullPointerException
 1469        *        if <code>locale</code> is null
 1470        * @since 1.6
 1471        */
 1472       public Map<String, Integer> getDisplayNames(int field, int style, Locale locale) {
 1473           if (!checkDisplayNameParams(field, style, ALL_STYLES, LONG, locale,
 1474                                       ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) {
 1475               return null;
 1476           }
 1477   
 1478           // ALL_STYLES
 1479           if (style == ALL_STYLES) {
 1480               Map<String,Integer> shortNames = getDisplayNamesImpl(field, SHORT, locale);
 1481               if (field == ERA || field == AM_PM) {
 1482                   return shortNames;
 1483               }
 1484               Map<String,Integer> longNames = getDisplayNamesImpl(field, LONG, locale);
 1485               if (shortNames == null) {
 1486                   return longNames;
 1487               }
 1488               if (longNames != null) {
 1489                   shortNames.putAll(longNames);
 1490               }
 1491               return shortNames;
 1492           }
 1493   
 1494           // SHORT or LONG
 1495           return getDisplayNamesImpl(field, style, locale);
 1496       }
 1497   
 1498       private Map<String,Integer> getDisplayNamesImpl(int field, int style, Locale locale) {
 1499           DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale);
 1500           String[] strings = getFieldStrings(field, style, symbols);
 1501           if (strings != null) {
 1502               Map<String,Integer> names = new HashMap<String,Integer>();
 1503               for (int i = 0; i < strings.length; i++) {
 1504                   if (strings[i].length() == 0) {
 1505                       continue;
 1506                   }
 1507                   names.put(strings[i], i);
 1508               }
 1509               return names;
 1510           }
 1511           return null;
 1512       }
 1513   
 1514       boolean checkDisplayNameParams(int field, int style, int minStyle, int maxStyle,
 1515                                      Locale locale, int fieldMask) {
 1516           if (field < 0 || field >= fields.length ||
 1517               style < minStyle || style > maxStyle) {
 1518               throw new IllegalArgumentException();
 1519           }
 1520           if (locale == null) {
 1521               throw new NullPointerException();
 1522           }
 1523           return isFieldSet(fieldMask, field);
 1524       }
 1525   
 1526       private String[] getFieldStrings(int field, int style, DateFormatSymbols symbols) {
 1527           String[] strings = null;
 1528           switch (field) {
 1529           case ERA:
 1530               strings = symbols.getEras();
 1531               break;
 1532   
 1533           case MONTH:
 1534               strings = (style == LONG) ? symbols.getMonths() : symbols.getShortMonths();
 1535               break;
 1536   
 1537           case DAY_OF_WEEK:
 1538               strings = (style == LONG) ? symbols.getWeekdays() : symbols.getShortWeekdays();
 1539               break;
 1540   
 1541           case AM_PM:
 1542               strings = symbols.getAmPmStrings();
 1543               break;
 1544           }
 1545           return strings;
 1546       }
 1547   
 1548       /**
 1549        * Fills in any unset fields in the calendar fields. First, the {@link
 1550        * #computeTime()} method is called if the time value (millisecond offset
 1551        * from the <a href="#Epoch">Epoch</a>) has not been calculated from
 1552        * calendar field values. Then, the {@link #computeFields()} method is
 1553        * called to calculate all calendar field values.
 1554        */
 1555       protected void complete()
 1556       {
 1557           if (!isTimeSet)
 1558               updateTime();
 1559           if (!areFieldsSet || !areAllFieldsSet) {
 1560               computeFields(); // fills in unset fields
 1561               areAllFieldsSet = areFieldsSet = true;
 1562           }
 1563       }
 1564   
 1565       /**
 1566        * Returns whether the value of the specified calendar field has been set
 1567        * externally by calling one of the setter methods rather than by the
 1568        * internal time calculation.
 1569        *
 1570        * @return <code>true</code> if the field has been set externally,
 1571        * <code>false</code> otherwise.
 1572        * @exception IndexOutOfBoundsException if the specified
 1573        *                <code>field</code> is out of range
 1574        *               (<code>field &lt; 0 || field &gt;= FIELD_COUNT</code>).
 1575        * @see #selectFields()
 1576        * @see #setFieldsComputed(int)
 1577        */
 1578       final boolean isExternallySet(int field) {
 1579           return stamp[field] >= MINIMUM_USER_STAMP;
 1580       }
 1581   
 1582       /**
 1583        * Returns a field mask (bit mask) indicating all calendar fields that
 1584        * have the state of externally or internally set.
 1585        *
 1586        * @return a bit mask indicating set state fields
 1587        */
 1588       final int getSetStateFields() {
 1589           int mask = 0;
 1590           for (int i = 0; i < fields.length; i++) {
 1591               if (stamp[i] != UNSET) {
 1592                   mask |= 1 << i;
 1593               }
 1594           }
 1595           return mask;
 1596       }
 1597   
 1598       /**
 1599        * Sets the state of the specified calendar fields to
 1600        * <em>computed</em>. This state means that the specified calendar fields
 1601        * have valid values that have been set by internal time calculation
 1602        * rather than by calling one of the setter methods.
 1603        *
 1604        * @param fieldMask the field to be marked as computed.
 1605        * @exception IndexOutOfBoundsException if the specified
 1606        *                <code>field</code> is out of range
 1607        *               (<code>field &lt; 0 || field &gt;= FIELD_COUNT</code>).
 1608        * @see #isExternallySet(int)
 1609        * @see #selectFields()
 1610        */
 1611       final void setFieldsComputed(int fieldMask) {
 1612           if (fieldMask == ALL_FIELDS) {
 1613               for (int i = 0; i < fields.length; i++) {
 1614                   stamp[i] = COMPUTED;
 1615                   isSet[i] = true;
 1616               }
 1617               areFieldsSet = areAllFieldsSet = true;
 1618           } else {
 1619               for (int i = 0; i < fields.length; i++) {
 1620                   if ((fieldMask & 1) == 1) {
 1621                       stamp[i] = COMPUTED;
 1622                       isSet[i] = true;
 1623                   } else {
 1624                       if (areAllFieldsSet && !isSet[i]) {
 1625                           areAllFieldsSet = false;
 1626                       }
 1627                   }
 1628                   fieldMask >>>= 1;
 1629               }
 1630           }
 1631       }
 1632   
 1633       /**
 1634        * Sets the state of the calendar fields that are <em>not</em> specified
 1635        * by <code>fieldMask</code> to <em>unset</em>. If <code>fieldMask</code>
 1636        * specifies all the calendar fields, then the state of this
 1637        * <code>Calendar</code> becomes that all the calendar fields are in sync
 1638        * with the time value (millisecond offset from the Epoch).
 1639        *
 1640        * @param fieldMask the field mask indicating which calendar fields are in
 1641        * sync with the time value.
 1642        * @exception IndexOutOfBoundsException if the specified
 1643        *                <code>field</code> is out of range
 1644        *               (<code>field &lt; 0 || field &gt;= FIELD_COUNT</code>).
 1645        * @see #isExternallySet(int)
 1646        * @see #selectFields()
 1647        */
 1648       final void setFieldsNormalized(int fieldMask) {
 1649           if (fieldMask != ALL_FIELDS) {
 1650               for (int i = 0; i < fields.length; i++) {
 1651                   if ((fieldMask & 1) == 0) {
 1652                       stamp[i] = fields[i] = 0; // UNSET == 0
 1653                       isSet[i] = false;
 1654                   }
 1655                   fieldMask >>= 1;
 1656               }
 1657           }
 1658   
 1659           // Some or all of the fields are in sync with the
 1660           // milliseconds, but the stamp values are not normalized yet.
 1661           areFieldsSet = true;
 1662           areAllFieldsSet = false;
 1663       }
 1664   
 1665       /**
 1666        * Returns whether the calendar fields are partially in sync with the time
 1667        * value or fully in sync but not stamp values are not normalized yet.
 1668        */
 1669       final boolean isPartiallyNormalized() {
 1670           return areFieldsSet && !areAllFieldsSet;
 1671       }
 1672   
 1673       /**
 1674        * Returns whether the calendar fields are fully in sync with the time
 1675        * value.
 1676        */
 1677       final boolean isFullyNormalized() {
 1678           return areFieldsSet && areAllFieldsSet;
 1679       }
 1680   
 1681       /**
 1682        * Marks this Calendar as not sync'd.
 1683        */
 1684       final void setUnnormalized() {
 1685           areFieldsSet = areAllFieldsSet = false;
 1686       }
 1687   
 1688       /**
 1689        * Returns whether the specified <code>field</code> is on in the
 1690        * <code>fieldMask</code>.
 1691        */
 1692       static final boolean isFieldSet(int fieldMask, int field) {
 1693           return (fieldMask & (1 << field)) != 0;
 1694       }
 1695   
 1696       /**
 1697        * Returns a field mask indicating which calendar field values
 1698        * to be used to calculate the time value. The calendar fields are
 1699        * returned as a bit mask, each bit of which corresponds to a field, i.e.,
 1700        * the mask value of <code>field</code> is <code>(1 &lt;&lt;
 1701        * field)</code>. For example, 0x26 represents the <code>YEAR</code>,
 1702        * <code>MONTH</code>, and <code>DAY_OF_MONTH</code> fields (i.e., 0x26 is
 1703        * equal to
 1704        * <code>(1&lt;&lt;YEAR)|(1&lt;&lt;MONTH)|(1&lt;&lt;DAY_OF_MONTH))</code>.
 1705        *
 1706        * <p>This method supports the calendar fields resolution as described in
 1707        * the class description. If the bit mask for a given field is on and its
 1708        * field has not been set (i.e., <code>isSet(field)</code> is
 1709        * <code>false</code>), then the default value of the field has to be
 1710        * used, which case means that the field has been selected because the
 1711        * selected combination involves the field.
 1712        *
 1713        * @return a bit mask of selected fields
 1714        * @see #isExternallySet(int)
 1715        * @see #setInternallySetState(int)
 1716        */
 1717       final int selectFields() {
 1718           // This implementation has been taken from the GregorianCalendar class.
 1719   
 1720           // The YEAR field must always be used regardless of its SET
 1721           // state because YEAR is a mandatory field to determine the date
 1722           // and the default value (EPOCH_YEAR) may change through the
 1723           // normalization process.
 1724           int fieldMask = YEAR_MASK;
 1725   
 1726           if (stamp[ERA] != UNSET) {
 1727               fieldMask |= ERA_MASK;
 1728           }
 1729           // Find the most recent group of fields specifying the day within
 1730           // the year.  These may be any of the following combinations:
 1731           //   MONTH + DAY_OF_MONTH
 1732           //   MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
 1733           //   MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
 1734           //   DAY_OF_YEAR
 1735           //   WEEK_OF_YEAR + DAY_OF_WEEK
 1736           // We look for the most recent of the fields in each group to determine
 1737           // the age of the group.  For groups involving a week-related field such
 1738           // as WEEK_OF_MONTH, DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR, both the
 1739           // week-related field and the DAY_OF_WEEK must be set for the group as a
 1740           // whole to be considered.  (See bug 4153860 - liu 7/24/98.)
 1741           int dowStamp = stamp[DAY_OF_WEEK];
 1742           int monthStamp = stamp[MONTH];
 1743           int domStamp = stamp[DAY_OF_MONTH];
 1744           int womStamp = aggregateStamp(stamp[WEEK_OF_MONTH], dowStamp);
 1745           int dowimStamp = aggregateStamp(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp);
 1746           int doyStamp = stamp[DAY_OF_YEAR];
 1747           int woyStamp = aggregateStamp(stamp[WEEK_OF_YEAR], dowStamp);
 1748   
 1749           int bestStamp = domStamp;
 1750           if (womStamp > bestStamp) {
 1751               bestStamp = womStamp;
 1752           }
 1753           if (dowimStamp > bestStamp) {
 1754               bestStamp = dowimStamp;
 1755           }
 1756           if (doyStamp > bestStamp) {
 1757               bestStamp = doyStamp;
 1758           }
 1759           if (woyStamp > bestStamp) {
 1760               bestStamp = woyStamp;
 1761           }
 1762   
 1763           /* No complete combination exists.  Look for WEEK_OF_MONTH,
 1764            * DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR alone.  Treat DAY_OF_WEEK alone
 1765            * as DAY_OF_WEEK_IN_MONTH.
 1766            */
 1767           if (bestStamp == UNSET) {
 1768               womStamp = stamp[WEEK_OF_MONTH];
 1769               dowimStamp = Math.max(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp);
 1770               woyStamp = stamp[WEEK_OF_YEAR];
 1771               bestStamp = Math.max(Math.max(womStamp, dowimStamp), woyStamp);
 1772   
 1773               /* Treat MONTH alone or no fields at all as DAY_OF_MONTH.  This may
 1774                * result in bestStamp = domStamp = UNSET if no fields are set,
 1775                * which indicates DAY_OF_MONTH.
 1776                */
 1777               if (bestStamp == UNSET) {
 1778                   bestStamp = domStamp = monthStamp;
 1779               }
 1780           }
 1781   
 1782           if (bestStamp == domStamp ||
 1783              (bestStamp == womStamp && stamp[WEEK_OF_MONTH] >= stamp[WEEK_OF_YEAR]) ||
 1784              (bestStamp == dowimStamp && stamp[DAY_OF_WEEK_IN_MONTH] >= stamp[WEEK_OF_YEAR])) {
 1785               fieldMask |= MONTH_MASK;
 1786               if (bestStamp == domStamp) {
 1787                   fieldMask |= DAY_OF_MONTH_MASK;
 1788               } else {
 1789                   assert (bestStamp == womStamp || bestStamp == dowimStamp);
 1790                   if (dowStamp != UNSET) {
 1791                       fieldMask |= DAY_OF_WEEK_MASK;
 1792                   }
 1793                   if (womStamp == dowimStamp) {
 1794                       // When they are equal, give the priority to
 1795                       // WEEK_OF_MONTH for compatibility.
 1796                       if (stamp[WEEK_OF_MONTH] >= stamp[DAY_OF_WEEK_IN_MONTH]) {
 1797                           fieldMask |= WEEK_OF_MONTH_MASK;
 1798                       } else {
 1799                           fieldMask |= DAY_OF_WEEK_IN_MONTH_MASK;
 1800                       }
 1801                   } else {
 1802                       if (bestStamp == womStamp) {
 1803                           fieldMask |= WEEK_OF_MONTH_MASK;
 1804                       } else {
 1805                           assert (bestStamp == dowimStamp);
 1806                           if (stamp[DAY_OF_WEEK_IN_MONTH] != UNSET) {
 1807                               fieldMask |= DAY_OF_WEEK_IN_MONTH_MASK;
 1808                           }
 1809                       }
 1810                   }
 1811               }
 1812           } else {
 1813               assert (bestStamp == doyStamp || bestStamp == woyStamp ||
 1814                       bestStamp == UNSET);
 1815               if (bestStamp == doyStamp) {
 1816                   fieldMask |= DAY_OF_YEAR_MASK;
 1817               } else {
 1818                   assert (bestStamp == woyStamp);
 1819                   if (dowStamp != UNSET) {
 1820                       fieldMask |= DAY_OF_WEEK_MASK;
 1821                   }
 1822                   fieldMask |= WEEK_OF_YEAR_MASK;
 1823               }
 1824           }
 1825   
 1826           // Find the best set of fields specifying the time of day.  There
 1827           // are only two possibilities here; the HOUR_OF_DAY or the
 1828           // AM_PM and the HOUR.
 1829           int hourOfDayStamp = stamp[HOUR_OF_DAY];
 1830           int hourStamp = aggregateStamp(stamp[HOUR], stamp[AM_PM]);
 1831           bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp : hourOfDayStamp;
 1832   
 1833           // if bestStamp is still UNSET, then take HOUR or AM_PM. (See 4846659)
 1834           if (bestStamp == UNSET) {
 1835               bestStamp = Math.max(stamp[HOUR], stamp[AM_PM]);
 1836           }
 1837   
 1838           // Hours
 1839           if (bestStamp != UNSET) {
 1840               if (bestStamp == hourOfDayStamp) {
 1841                   fieldMask |= HOUR_OF_DAY_MASK;
 1842               } else {
 1843                   fieldMask |= HOUR_MASK;
 1844                   if (stamp[AM_PM] != UNSET) {
 1845                       fieldMask |= AM_PM_MASK;
 1846                   }
 1847               }
 1848           }
 1849           if (stamp[MINUTE] != UNSET) {
 1850               fieldMask |= MINUTE_MASK;
 1851           }
 1852           if (stamp[SECOND] != UNSET) {
 1853               fieldMask |= SECOND_MASK;
 1854           }
 1855           if (stamp[MILLISECOND] != UNSET) {
 1856               fieldMask |= MILLISECOND_MASK;
 1857           }
 1858           if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP) {
 1859                   fieldMask |= ZONE_OFFSET_MASK;
 1860           }
 1861           if (stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) {
 1862               fieldMask |= DST_OFFSET_MASK;
 1863           }
 1864   
 1865           return fieldMask;
 1866       }
 1867   
 1868       /**
 1869        * Returns the pseudo-time-stamp for two fields, given their
 1870        * individual pseudo-time-stamps.  If either of the fields
 1871        * is unset, then the aggregate is unset.  Otherwise, the
 1872        * aggregate is the later of the two stamps.
 1873        */
 1874       private static final int aggregateStamp(int stamp_a, int stamp_b) {
 1875           if (stamp_a == UNSET || stamp_b == UNSET) {
 1876               return UNSET;
 1877           }
 1878           return (stamp_a > stamp_b) ? stamp_a : stamp_b;
 1879       }
 1880   
 1881       /**
 1882        * Compares this <code>Calendar</code> to the specified
 1883        * <code>Object</code>.  The result is <code>true</code> if and only if
 1884        * the argument is a <code>Calendar</code> object of the same calendar
 1885        * system that represents the same time value (millisecond offset from the
 1886        * <a href="#Epoch">Epoch</a>) under the same
 1887        * <code>Calendar</code> parameters as this object.
 1888        *
 1889        * <p>The <code>Calendar</code> parameters are the values represented
 1890        * by the <code>isLenient</code>, <code>getFirstDayOfWeek</code>,
 1891        * <code>getMinimalDaysInFirstWeek</code> and <code>getTimeZone</code>
 1892        * methods. If there is any difference in those parameters
 1893        * between the two <code>Calendar</code>s, this method returns
 1894        * <code>false</code>.
 1895        *
 1896        * <p>Use the {@link #compareTo(Calendar) compareTo} method to
 1897        * compare only the time values.
 1898        *
 1899        * @param obj the object to compare with.
 1900        * @return <code>true</code> if this object is equal to <code>obj</code>;
 1901        * <code>false</code> otherwise.
 1902        */
 1903       public boolean equals(Object obj) {
 1904           if (this == obj)
 1905               return true;
 1906           try {
 1907               Calendar that = (Calendar)obj;
 1908               return compareTo(getMillisOf(that)) == 0 &&
 1909                   lenient == that.lenient &&
 1910                   firstDayOfWeek == that.firstDayOfWeek &&
 1911                   minimalDaysInFirstWeek == that.minimalDaysInFirstWeek &&
 1912                   zone.equals(that.zone);
 1913           } catch (Exception e) {
 1914               // Note: GregorianCalendar.computeTime throws
 1915               // IllegalArgumentException if the ERA value is invalid
 1916               // even it's in lenient mode.
 1917           }
 1918           return false;
 1919       }
 1920   
 1921       /**
 1922        * Returns a hash code for this calendar.
 1923        *
 1924        * @return a hash code value for this object.
 1925        * @since 1.2
 1926        */
 1927       public int hashCode() {
 1928           // 'otheritems' represents the hash code for the previous versions.
 1929           int otheritems = (lenient ? 1 : 0)
 1930               | (firstDayOfWeek << 1)
 1931               | (minimalDaysInFirstWeek << 4)
 1932               | (zone.hashCode() << 7);
 1933           long t = getMillisOf(this);
 1934           return (int) t ^ (int)(t >> 32) ^ otheritems;
 1935       }
 1936   
 1937       /**
 1938        * Returns whether this <code>Calendar</code> represents a time
 1939        * before the time represented by the specified
 1940        * <code>Object</code>. This method is equivalent to:
 1941        * <pre><blockquote>
 1942        *         compareTo(when) < 0
 1943        * </blockquote></pre>
 1944        * if and only if <code>when</code> is a <code>Calendar</code>
 1945        * instance. Otherwise, the method returns <code>false</code>.
 1946        *
 1947        * @param when the <code>Object</code> to be compared
 1948        * @return <code>true</code> if the time of this
 1949        * <code>Calendar</code> is before the time represented by
 1950        * <code>when</code>; <code>false</code> otherwise.
 1951        * @see     #compareTo(Calendar)
 1952        */
 1953       public boolean before(Object when) {
 1954           return when instanceof Calendar
 1955               && compareTo((Calendar)when) < 0;
 1956       }
 1957   
 1958       /**
 1959        * Returns whether this <code>Calendar</code> represents a time
 1960        * after the time represented by the specified
 1961        * <code>Object</code>. This method is equivalent to:
 1962        * <pre><blockquote>
 1963        *         compareTo(when) > 0
 1964        * </blockquote></pre>
 1965        * if and only if <code>when</code> is a <code>Calendar</code>
 1966        * instance. Otherwise, the method returns <code>false</code>.
 1967        *
 1968        * @param when the <code>Object</code> to be compared
 1969        * @return <code>true</code> if the time of this <code>Calendar</code> is
 1970        * after the time represented by <code>when</code>; <code>false</code>
 1971        * otherwise.
 1972        * @see     #compareTo(Calendar)
 1973        */
 1974       public boolean after(Object when) {
 1975           return when instanceof Calendar
 1976               && compareTo((Calendar)when) > 0;
 1977       }
 1978   
 1979       /**
 1980        * Compares the time values (millisecond offsets from the <a
 1981        * href="#Epoch">Epoch</a>) represented by two
 1982        * <code>Calendar</code> objects.
 1983        *
 1984        * @param anotherCalendar the <code>Calendar</code> to be compared.
 1985        * @return the value <code>0</code> if the time represented by the argument
 1986        * is equal to the time represented by this <code>Calendar</code>; a value
 1987        * less than <code>0</code> if the time of this <code>Calendar</code> is
 1988        * before the time represented by the argument; and a value greater than
 1989        * <code>0</code> if the time of this <code>Calendar</code> is after the
 1990        * time represented by the argument.
 1991        * @exception NullPointerException if the specified <code>Calendar</code> is
 1992        *            <code>null</code>.
 1993        * @exception IllegalArgumentException if the time value of the
 1994        * specified <code>Calendar</code> object can't be obtained due to
 1995        * any invalid calendar values.
 1996        * @since   1.5
 1997        */
 1998       public int compareTo(Calendar anotherCalendar) {
 1999           return compareTo(getMillisOf(anotherCalendar));
 2000       }
 2001   
 2002       /**
 2003        * Adds or subtracts the specified amount of time to the given calendar field,
 2004        * based on the calendar's rules. For example, to subtract 5 days from
 2005        * the current time of the calendar, you can achieve it by calling:
 2006        * <p><code>add(Calendar.DAY_OF_MONTH, -5)</code>.
 2007        *
 2008        * @param field the calendar field.
 2009        * @param amount the amount of date or time to be added to the field.
 2010        * @see #roll(int,int)
 2011        * @see #set(int,int)
 2012        */
 2013       abstract public void add(int field, int amount);
 2014   
 2015       /**
 2016        * Adds or subtracts (up/down) a single unit of time on the given time
 2017        * field without changing larger fields. For example, to roll the current
 2018        * date up by one day, you can achieve it by calling:
 2019        * <p>roll(Calendar.DATE, true).
 2020        * When rolling on the year or Calendar.YEAR field, it will roll the year
 2021        * value in the range between 1 and the value returned by calling
 2022        * <code>getMaximum(Calendar.YEAR)</code>.
 2023        * When rolling on the month or Calendar.MONTH field, other fields like
 2024        * date might conflict and, need to be changed. For instance,
 2025        * rolling the month on the date 01/31/96 will result in 02/29/96.
 2026        * When rolling on the hour-in-day or Calendar.HOUR_OF_DAY field, it will
 2027        * roll the hour value in the range between 0 and 23, which is zero-based.
 2028        *
 2029        * @param field the time field.
 2030        * @param up indicates if the value of the specified time field is to be
 2031        * rolled up or rolled down. Use true if rolling up, false otherwise.
 2032        * @see Calendar#add(int,int)
 2033        * @see Calendar#set(int,int)
 2034        */
 2035       abstract public void roll(int field, boolean up);
 2036   
 2037       /**
 2038        * Adds the specified (signed) amount to the specified calendar field
 2039        * without changing larger fields.  A negative amount means to roll
 2040        * down.
 2041        *
 2042        * <p>NOTE:  This default implementation on <code>Calendar</code> just repeatedly calls the
 2043        * version of {@link #roll(int,boolean) roll()} that rolls by one unit.  This may not
 2044        * always do the right thing.  For example, if the <code>DAY_OF_MONTH</code> field is 31,
 2045        * rolling through February will leave it set to 28.  The <code>GregorianCalendar</code>
 2046        * version of this function takes care of this problem.  Other subclasses
 2047        * should also provide overrides of this function that do the right thing.
 2048        *
 2049        * @param field the calendar field.
 2050        * @param amount the signed amount to add to the calendar <code>field</code>.
 2051        * @since 1.2
 2052        * @see #roll(int,boolean)
 2053        * @see #add(int,int)
 2054        * @see #set(int,int)
 2055        */
 2056       public void roll(int field, int amount)
 2057       {
 2058           while (amount > 0) {
 2059               roll(field, true);
 2060               amount--;
 2061           }
 2062           while (amount < 0) {
 2063               roll(field, false);
 2064               amount++;
 2065           }
 2066       }
 2067   
 2068       /**
 2069        * Sets the time zone with the given time zone value.
 2070        *
 2071        * @param value the given time zone.
 2072        */
 2073       public void setTimeZone(TimeZone value)
 2074       {
 2075           zone = value;
 2076           sharedZone = false;
 2077           /* Recompute the fields from the time using the new zone.  This also
 2078            * works if isTimeSet is false (after a call to set()).  In that case
 2079            * the time will be computed from the fields using the new zone, then
 2080            * the fields will get recomputed from that.  Consider the sequence of
 2081            * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST).
 2082            * Is cal set to 1 o'clock EST or 1 o'clock PST?  Answer: PST.  More
 2083            * generally, a call to setTimeZone() affects calls to set() BEFORE AND
 2084            * AFTER it up to the next call to complete().
 2085            */
 2086           areAllFieldsSet = areFieldsSet = false;
 2087       }
 2088   
 2089       /**
 2090        * Gets the time zone.
 2091        *
 2092        * @return the time zone object associated with this calendar.
 2093        */
 2094       public TimeZone getTimeZone()
 2095       {
 2096           // If the TimeZone object is shared by other Calendar instances, then
 2097           // create a clone.
 2098           if (sharedZone) {
 2099               zone = (TimeZone) zone.clone();
 2100               sharedZone = false;
 2101           }
 2102           return zone;
 2103       }
 2104   
 2105       /**
 2106        * Returns the time zone (without cloning).
 2107        */
 2108       TimeZone getZone() {
 2109           return zone;
 2110       }
 2111   
 2112       /**
 2113        * Sets the sharedZone flag to <code>shared</code>.
 2114        */
 2115       void setZoneShared(boolean shared) {
 2116           sharedZone = shared;
 2117       }
 2118   
 2119       /**
 2120        * Specifies whether or not date/time interpretation is to be lenient.  With
 2121        * lenient interpretation, a date such as "February 942, 1996" will be
 2122        * treated as being equivalent to the 941st day after February 1, 1996.
 2123        * With strict (non-lenient) interpretation, such dates will cause an exception to be
 2124        * thrown. The default is lenient.
 2125        *
 2126        * @param lenient <code>true</code> if the lenient mode is to be turned
 2127        * on; <code>false</code> if it is to be turned off.
 2128        * @see #isLenient()
 2129        * @see java.text.DateFormat#setLenient
 2130        */
 2131       public void setLenient(boolean lenient)
 2132       {
 2133           this.lenient = lenient;
 2134       }
 2135   
 2136       /**
 2137        * Tells whether date/time interpretation is to be lenient.
 2138        *
 2139        * @return <code>true</code> if the interpretation mode of this calendar is lenient;
 2140        * <code>false</code> otherwise.
 2141        * @see #setLenient(boolean)
 2142        */
 2143       public boolean isLenient()
 2144       {
 2145           return lenient;
 2146       }
 2147   
 2148       /**
 2149        * Sets what the first day of the week is; e.g., <code>SUNDAY</code> in the U.S.,
 2150        * <code>MONDAY</code> in France.
 2151        *
 2152        * @param value the given first day of the week.
 2153        * @see #getFirstDayOfWeek()
 2154        * @see #getMinimalDaysInFirstWeek()
 2155        */
 2156       public void setFirstDayOfWeek(int value)
 2157       {
 2158           if (firstDayOfWeek == value) {
 2159               return;
 2160           }
 2161           firstDayOfWeek = value;
 2162           invalidateWeekFields();
 2163       }
 2164   
 2165       /**
 2166        * Gets what the first day of the week is; e.g., <code>SUNDAY</code> in the U.S.,
 2167        * <code>MONDAY</code> in France.
 2168        *
 2169        * @return the first day of the week.
 2170        * @see #setFirstDayOfWeek(int)
 2171        * @see #getMinimalDaysInFirstWeek()
 2172        */
 2173       public int getFirstDayOfWeek()
 2174       {
 2175           return firstDayOfWeek;
 2176       }
 2177   
 2178       /**
 2179        * Sets what the minimal days required in the first week of the year are;
 2180        * For example, if the first week is defined as one that contains the first
 2181        * day of the first month of a year, call this method with value 1. If it
 2182        * must be a full week, use value 7.
 2183        *
 2184        * @param value the given minimal days required in the first week
 2185        * of the year.
 2186        * @see #getMinimalDaysInFirstWeek()
 2187        */
 2188       public void setMinimalDaysInFirstWeek(int value)
 2189       {
 2190           if (minimalDaysInFirstWeek == value) {
 2191               return;
 2192           }
 2193           minimalDaysInFirstWeek = value;
 2194           invalidateWeekFields();
 2195       }
 2196   
 2197       /**
 2198        * Gets what the minimal days required in the first week of the year are;
 2199        * e.g., if the first week is defined as one that contains the first day
 2200        * of the first month of a year, this method returns 1. If
 2201        * the minimal days required must be a full week, this method
 2202        * returns 7.
 2203        *
 2204        * @return the minimal days required in the first week of the year.
 2205        * @see #setMinimalDaysInFirstWeek(int)
 2206        */
 2207       public int getMinimalDaysInFirstWeek()
 2208       {
 2209           return minimalDaysInFirstWeek;
 2210       }
 2211   
 2212       /**
 2213        * Returns whether this {@code Calendar} supports week dates.
 2214        *
 2215        * <p>The default implementation of this method returns {@code false}.
 2216        *
 2217        * @return {@code true} if this {@code Calendar} supports week dates;
 2218        *         {@code false} otherwise.
 2219        * @see #getWeekYear()
 2220        * @see #setWeekDate(int,int,int)
 2221        * @see #getWeeksInWeekYear()
 2222        * @since 1.7
 2223        */
 2224       public boolean isWeekDateSupported() {
 2225           return false;
 2226       }
 2227   
 2228       /**
 2229        * Returns the week year represented by this {@code Calendar}. The
 2230        * week year is in sync with the week cycle. The {@linkplain
 2231        * #getFirstDayOfWeek() first day of the first week} is the first
 2232        * day of the week year.
 2233        *
 2234        * <p>The default implementation of this method throws an
 2235        * {@link UnsupportedOperationException}.
 2236        *
 2237        * @return the week year of this {@code Calendar}
 2238        * @exception UnsupportedOperationException
 2239        *            if any week year numbering isn't supported
 2240        *            in this {@code Calendar}.
 2241        * @see #isWeekDateSupported()
 2242        * @see #getFirstDayOfWeek()
 2243        * @see #getMinimalDaysInFirstWeek()
 2244        * @since 1.7
 2245        */
 2246       public int getWeekYear() {
 2247           throw new UnsupportedOperationException();
 2248       }
 2249   
 2250       /**
 2251        * Sets the date of this {@code Calendar} with the the given date
 2252        * specifiers - week year, week of year, and day of week.
 2253        *
 2254        * <p>Unlike the {@code set} method, all of the calendar fields
 2255        * and {@code time} values are calculated upon return.
 2256        *
 2257        * <p>If {@code weekOfYear} is out of the valid week-of-year range
 2258        * in {@code weekYear}, the {@code weekYear} and {@code
 2259        * weekOfYear} values are adjusted in lenient mode, or an {@code
 2260        * IllegalArgumentException} is thrown in non-lenient mode.
 2261        *
 2262        * <p>The default implementation of this method throws an
 2263        * {@code UnsupportedOperationException}.
 2264        *
 2265        * @param weekYear   the week year
 2266        * @param weekOfYear the week number based on {@code weekYear}
 2267        * @param dayOfWeek  the day of week value: one of the constants
 2268        *                   for the {@link #DAY_OF_WEEK} field: {@link
 2269        *                   #SUNDAY}, ..., {@link #SATURDAY}.
 2270        * @exception IllegalArgumentException
 2271        *            if any of the given date specifiers is invalid
 2272        *            or any of the calendar fields are inconsistent
 2273        *            with the given date specifiers in non-lenient mode
 2274        * @exception UnsupportedOperationException
 2275        *            if any week year numbering isn't supported in this
 2276        *            {@code Calendar}.
 2277        * @see #isWeekDateSupported()
 2278        * @see #getFirstDayOfWeek()
 2279        * @see #getMinimalDaysInFirstWeek()
 2280        * @since 1.7
 2281        */
 2282       public void setWeekDate(int weekYear, int weekOfYear, int dayOfWeek) {
 2283           throw new UnsupportedOperationException();
 2284       }
 2285   
 2286       /**
 2287        * Returns the number of weeks in the week year represented by this
 2288        * {@code Calendar}.
 2289        *
 2290        * <p>The default implementation of this method throws an
 2291        * {@code UnsupportedOperationException}.
 2292        *
 2293        * @return the number of weeks in the week year.
 2294        * @exception UnsupportedOperationException
 2295        *            if any week year numbering isn't supported in this
 2296        *            {@code Calendar}.
 2297        * @see #WEEK_OF_YEAR
 2298        * @see #isWeekDateSupported()
 2299        * @see #getWeekYear()
 2300        * @see #getActualMaximum(int)
 2301        * @since 1.7
 2302        */
 2303       public int getWeeksInWeekYear() {
 2304           throw new UnsupportedOperationException();
 2305       }
 2306   
 2307       /**
 2308        * Returns the minimum value for the given calendar field of this
 2309        * <code>Calendar</code> instance. The minimum value is defined as
 2310        * the smallest value returned by the {@link #get(int) get} method
 2311        * for any possible time value.  The minimum value depends on
 2312        * calendar system specific parameters of the instance.
 2313        *
 2314        * @param field the calendar field.
 2315        * @return the minimum value for the given calendar field.
 2316        * @see #getMaximum(int)
 2317        * @see #getGreatestMinimum(int)
 2318        * @see #getLeastMaximum(int)
 2319        * @see #getActualMinimum(int)
 2320        * @see #getActualMaximum(int)
 2321        */
 2322       abstract public int getMinimum(int field);
 2323   
 2324       /**
 2325        * Returns the maximum value for the given calendar field of this
 2326        * <code>Calendar</code> instance. The maximum value is defined as
 2327        * the largest value returned by the {@link #get(int) get} method
 2328        * for any possible time value. The maximum value depends on
 2329        * calendar system specific parameters of the instance.
 2330        *
 2331        * @param field the calendar field.
 2332        * @return the maximum value for the given calendar field.
 2333        * @see #getMinimum(int)
 2334        * @see #getGreatestMinimum(int)
 2335        * @see #getLeastMaximum(int)
 2336        * @see #getActualMinimum(int)
 2337        * @see #getActualMaximum(int)
 2338        */
 2339       abstract public int getMaximum(int field);
 2340   
 2341       /**
 2342        * Returns the highest minimum value for the given calendar field
 2343        * of this <code>Calendar</code> instance. The highest minimum
 2344        * value is defined as the largest value returned by {@link
 2345        * #getActualMinimum(int)} for any possible time value. The
 2346        * greatest minimum value depends on calendar system specific
 2347        * parameters of the instance.
 2348        *
 2349        * @param field the calendar field.
 2350        * @return the highest minimum value for the given calendar field.
 2351        * @see #getMinimum(int)
 2352        * @see #getMaximum(int)
 2353        * @see #getLeastMaximum(int)
 2354        * @see #getActualMinimum(int)
 2355        * @see #getActualMaximum(int)
 2356        */
 2357       abstract public int getGreatestMinimum(int field);
 2358   
 2359       /**
 2360        * Returns the lowest maximum value for the given calendar field
 2361        * of this <code>Calendar</code> instance. The lowest maximum
 2362        * value is defined as the smallest value returned by {@link
 2363        * #getActualMaximum(int)} for any possible time value. The least
 2364        * maximum value depends on calendar system specific parameters of
 2365        * the instance. For example, a <code>Calendar</code> for the
 2366        * Gregorian calendar system returns 28 for the
 2367        * <code>DAY_OF_MONTH</code> field, because the 28th is the last
 2368        * day of the shortest month of this calendar, February in a
 2369        * common year.
 2370        *
 2371        * @param field the calendar field.
 2372        * @return the lowest maximum value for the given calendar field.
 2373        * @see #getMinimum(int)
 2374        * @see #getMaximum(int)
 2375        * @see #getGreatestMinimum(int)
 2376        * @see #getActualMinimum(int)
 2377        * @see #getActualMaximum(int)
 2378        */
 2379       abstract public int getLeastMaximum(int field);
 2380   
 2381       /**
 2382        * Returns the minimum value that the specified calendar field
 2383        * could have, given the time value of this <code>Calendar</code>.
 2384        *
 2385        * <p>The default implementation of this method uses an iterative
 2386        * algorithm to determine the actual minimum value for the
 2387        * calendar field. Subclasses should, if possible, override this
 2388        * with a more efficient implementation - in many cases, they can
 2389        * simply return <code>getMinimum()</code>.
 2390        *
 2391        * @param field the calendar field
 2392        * @return the minimum of the given calendar field for the time
 2393        * value of this <code>Calendar</code>
 2394        * @see #getMinimum(int)
 2395        * @see #getMaximum(int)
 2396        * @see #getGreatestMinimum(int)
 2397        * @see #getLeastMaximum(int)
 2398        * @see #getActualMaximum(int)
 2399        * @since 1.2
 2400        */
 2401       public int getActualMinimum(int field) {
 2402           int fieldValue = getGreatestMinimum(field);
 2403           int endValue = getMinimum(field);
 2404   
 2405           // if we know that the minimum value is always the same, just return it
 2406           if (fieldValue == endValue) {
 2407               return fieldValue;
 2408           }
 2409   
 2410           // clone the calendar so we don't mess with the real one, and set it to
 2411           // accept anything for the field values
 2412           Calendar work = (Calendar)this.clone();
 2413           work.setLenient(true);
 2414   
 2415           // now try each value from getLeastMaximum() to getMaximum() one by one until
 2416           // we get a value that normalizes to another value.  The last value that
 2417           // normalizes to itself is the actual minimum for the current date
 2418           int result = fieldValue;
 2419   
 2420           do {
 2421               work.set(field, fieldValue);
 2422               if (work.get(field) != fieldValue) {
 2423                   break;
 2424               } else {
 2425                   result = fieldValue;
 2426                   fieldValue--;
 2427               }
 2428           } while (fieldValue >= endValue);
 2429   
 2430           return result;
 2431       }
 2432   
 2433       /**
 2434        * Returns the maximum value that the specified calendar field
 2435        * could have, given the time value of this
 2436        * <code>Calendar</code>. For example, the actual maximum value of
 2437        * the <code>MONTH</code> field is 12 in some years, and 13 in
 2438        * other years in the Hebrew calendar system.
 2439        *
 2440        * <p>The default implementation of this method uses an iterative
 2441        * algorithm to determine the actual maximum value for the
 2442        * calendar field. Subclasses should, if possible, override this
 2443        * with a more efficient implementation.
 2444        *
 2445        * @param field the calendar field
 2446        * @return the maximum of the given calendar field for the time
 2447        * value of this <code>Calendar</code>
 2448        * @see #getMinimum(int)
 2449        * @see #getMaximum(int)
 2450        * @see #getGreatestMinimum(int)
 2451        * @see #getLeastMaximum(int)
 2452        * @see #getActualMinimum(int)
 2453        * @since 1.2
 2454        */
 2455       public int getActualMaximum(int field) {
 2456           int fieldValue = getLeastMaximum(field);
 2457           int endValue = getMaximum(field);
 2458   
 2459           // if we know that the maximum value is always the same, just return it.
 2460           if (fieldValue == endValue) {
 2461               return fieldValue;
 2462           }
 2463   
 2464           // clone the calendar so we don't mess with the real one, and set it to
 2465           // accept anything for the field values.
 2466           Calendar work = (Calendar)this.clone();
 2467           work.setLenient(true);
 2468   
 2469           // if we're counting weeks, set the day of the week to Sunday.  We know the
 2470           // last week of a month or year will contain the first day of the week.
 2471           if (field == WEEK_OF_YEAR || field == WEEK_OF_MONTH)
 2472               work.set(DAY_OF_WEEK, firstDayOfWeek);
 2473   
 2474           // now try each value from getLeastMaximum() to getMaximum() one by one until
 2475           // we get a value that normalizes to another value.  The last value that
 2476           // normalizes to itself is the actual maximum for the current date
 2477           int result = fieldValue;
 2478   
 2479           do {
 2480               work.set(field, fieldValue);
 2481               if (work.get(field) != fieldValue) {
 2482                   break;
 2483               } else {
 2484                   result = fieldValue;
 2485                   fieldValue++;
 2486               }
 2487           } while (fieldValue <= endValue);
 2488   
 2489           return result;
 2490       }
 2491   
 2492       /**
 2493        * Creates and returns a copy of this object.
 2494        *
 2495        * @return a copy of this object.
 2496        */
 2497       public Object clone()
 2498       {
 2499           try {
 2500               Calendar other = (Calendar) super.clone();
 2501   
 2502               other.fields = new int[FIELD_COUNT];
 2503               other.isSet = new boolean[FIELD_COUNT];
 2504               other.stamp = new int[FIELD_COUNT];
 2505               for (int i = 0; i < FIELD_COUNT; i++) {
 2506                   other.fields[i] = fields[i];
 2507                   other.stamp[i] = stamp[i];
 2508                   other.isSet[i] = isSet[i];
 2509               }
 2510               other.zone = (TimeZone) zone.clone();
 2511               return other;
 2512           }
 2513           catch (CloneNotSupportedException e) {
 2514               // this shouldn't happen, since we are Cloneable
 2515               throw new InternalError();
 2516           }
 2517       }
 2518   
 2519       private static final String[] FIELD_NAME = {
 2520           "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH",
 2521           "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR",
 2522           "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET",
 2523           "DST_OFFSET"
 2524       };
 2525   
 2526       /**
 2527        * Returns the name of the specified calendar field.
 2528        *
 2529        * @param field the calendar field
 2530        * @return the calendar field name
 2531        * @exception IndexOutOfBoundsException if <code>field</code> is negative,
 2532        * equal to or greater then <code>FIELD_COUNT</code>.
 2533        */
 2534       static final String getFieldName(int field) {
 2535           return FIELD_NAME[field];
 2536       }
 2537   
 2538       /**
 2539        * Return a string representation of this calendar. This method
 2540        * is intended to be used only for debugging purposes, and the
 2541        * format of the returned string may vary between implementations.
 2542        * The returned string may be empty but may not be <code>null</code>.
 2543        *
 2544        * @return  a string representation of this calendar.
 2545        */
 2546       public String toString() {
 2547           // NOTE: BuddhistCalendar.toString() interprets the string
 2548           // produced by this method so that the Gregorian year number
 2549           // is substituted by its B.E. year value. It relies on
 2550           // "...,YEAR=<year>,..." or "...,YEAR=?,...".
 2551           StringBuilder buffer = new StringBuilder(800);
 2552           buffer.append(getClass().getName()).append('[');
 2553           appendValue(buffer, "time", isTimeSet, time);
 2554           buffer.append(",areFieldsSet=").append(areFieldsSet);
 2555           buffer.append(",areAllFieldsSet=").append(areAllFieldsSet);
 2556           buffer.append(",lenient=").append(lenient);
 2557           buffer.append(",zone=").append(zone);
 2558           appendValue(buffer, ",firstDayOfWeek", true, (long) firstDayOfWeek);
 2559           appendValue(buffer, ",minimalDaysInFirstWeek", true, (long) minimalDaysInFirstWeek);
 2560           for (int i = 0; i < FIELD_COUNT; ++i) {
 2561               buffer.append(',');
 2562               appendValue(buffer, FIELD_NAME[i], isSet(i), (long) fields[i]);
 2563           }
 2564           buffer.append(']');
 2565           return buffer.toString();
 2566       }
 2567   
 2568       // =======================privates===============================
 2569   
 2570       private static final void appendValue(StringBuilder sb, String item, boolean valid, long value) {
 2571           sb.append(item).append('=');
 2572           if (valid) {
 2573               sb.append(value);
 2574           } else {
 2575               sb.append('?');
 2576           }
 2577       }
 2578   
 2579       /**
 2580        * Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent.
 2581        * They are used to figure out the week count for a specific date for
 2582        * a given locale. These must be set when a Calendar is constructed.
 2583        * @param desiredLocale the given locale.
 2584        */
 2585       private void setWeekCountData(Locale desiredLocale)
 2586       {
 2587           /* try to get the Locale data from the cache */
 2588           int[] data = cachedLocaleData.get(desiredLocale);
 2589           if (data == null) {  /* cache miss */
 2590               ResourceBundle bundle = LocaleData.getCalendarData(desiredLocale);
 2591               data = new int[2];
 2592               data[0] = Integer.parseInt(bundle.getString("firstDayOfWeek"));
 2593               data[1] = Integer.parseInt(bundle.getString("minimalDaysInFirstWeek"));
 2594               cachedLocaleData.putIfAbsent(desiredLocale, data);
 2595           }
 2596           firstDayOfWeek = data[0];
 2597           minimalDaysInFirstWeek = data[1];
 2598       }
 2599   
 2600       /**
 2601        * Recomputes the time and updates the status fields isTimeSet
 2602        * and areFieldsSet.  Callers should check isTimeSet and only
 2603        * call this method if isTimeSet is false.
 2604        */
 2605       private void updateTime() {
 2606           computeTime();
 2607           // The areFieldsSet and areAllFieldsSet values are no longer
 2608           // controlled here (as of 1.5).
 2609           isTimeSet = true;
 2610       }
 2611   
 2612       private int compareTo(long t) {
 2613           long thisTime = getMillisOf(this);
 2614           return (thisTime > t) ? 1 : (thisTime == t) ? 0 : -1;
 2615       }
 2616   
 2617       private static final long getMillisOf(Calendar calendar) {
 2618           if (calendar.isTimeSet) {
 2619               return calendar.time;
 2620           }
 2621           Calendar cal = (Calendar) calendar.clone();
 2622           cal.setLenient(true);
 2623           return cal.getTimeInMillis();
 2624       }
 2625   
 2626       /**
 2627        * Adjusts the stamp[] values before nextStamp overflow. nextStamp
 2628        * is set to the next stamp value upon the return.
 2629        */
 2630       private final void adjustStamp() {
 2631           int max = MINIMUM_USER_STAMP;
 2632           int newStamp = MINIMUM_USER_STAMP;
 2633   
 2634           for (;;) {
 2635               int min = Integer.MAX_VALUE;
 2636               for (int i = 0; i < stamp.length; i++) {
 2637                   int v = stamp[i];
 2638                   if (v >= newStamp && min > v) {
 2639                       min = v;
 2640                   }
 2641                   if (max < v) {
 2642                       max = v;
 2643                   }
 2644               }
 2645               if (max != min && min == Integer.MAX_VALUE) {
 2646                   break;
 2647               }
 2648               for (int i = 0; i < stamp.length; i++) {
 2649                   if (stamp[i] == min) {
 2650                       stamp[i] = newStamp;
 2651                   }
 2652               }
 2653               newStamp++;
 2654               if (min == max) {
 2655                   break;
 2656               }
 2657           }
 2658           nextStamp = newStamp;
 2659       }
 2660   
 2661       /**
 2662        * Sets the WEEK_OF_MONTH and WEEK_OF_YEAR fields to new values with the
 2663        * new parameter value if they have been calculated internally.
 2664        */
 2665       private void invalidateWeekFields()
 2666       {
 2667           if (stamp[WEEK_OF_MONTH] != COMPUTED &&
 2668               stamp[WEEK_OF_YEAR] != COMPUTED) {
 2669               return;
 2670           }
 2671   
 2672           // We have to check the new values of these fields after changing
 2673           // firstDayOfWeek and/or minimalDaysInFirstWeek. If the field values
 2674           // have been changed, then set the new values. (4822110)
 2675           Calendar cal = (Calendar) clone();
 2676           cal.setLenient(true);
 2677           cal.clear(WEEK_OF_MONTH);
 2678           cal.clear(WEEK_OF_YEAR);
 2679   
 2680           if (stamp[WEEK_OF_MONTH] == COMPUTED) {
 2681               int weekOfMonth = cal.get(WEEK_OF_MONTH);
 2682               if (fields[WEEK_OF_MONTH] != weekOfMonth) {
 2683                   fields[WEEK_OF_MONTH] = weekOfMonth;
 2684               }
 2685           }
 2686   
 2687           if (stamp[WEEK_OF_YEAR] == COMPUTED) {
 2688               int weekOfYear = cal.get(WEEK_OF_YEAR);
 2689               if (fields[WEEK_OF_YEAR] != weekOfYear) {
 2690                   fields[WEEK_OF_YEAR] = weekOfYear;
 2691               }
 2692           }
 2693       }
 2694   
 2695       /**
 2696        * Save the state of this object to a stream (i.e., serialize it).
 2697        *
 2698        * Ideally, <code>Calendar</code> would only write out its state data and
 2699        * the current time, and not write any field data out, such as
 2700        * <code>fields[]</code>, <code>isTimeSet</code>, <code>areFieldsSet</code>,
 2701        * and <code>isSet[]</code>.  <code>nextStamp</code> also should not be part
 2702        * of the persistent state. Unfortunately, this didn't happen before JDK 1.1
 2703        * shipped. To be compatible with JDK 1.1, we will always have to write out
 2704        * the field values and state flags.  However, <code>nextStamp</code> can be
 2705        * removed from the serialization stream; this will probably happen in the
 2706        * near future.
 2707        */
 2708       private void writeObject(ObjectOutputStream stream)
 2709            throws IOException
 2710       {
 2711           // Try to compute the time correctly, for the future (stream
 2712           // version 2) in which we don't write out fields[] or isSet[].
 2713           if (!isTimeSet) {
 2714               try {
 2715                   updateTime();
 2716               }
 2717               catch (IllegalArgumentException e) {}
 2718           }
 2719   
 2720           // If this Calendar has a ZoneInfo, save it and set a
 2721           // SimpleTimeZone equivalent (as a single DST schedule) for
 2722           // backward compatibility.
 2723           TimeZone savedZone = null;
 2724           if (zone instanceof ZoneInfo) {
 2725               SimpleTimeZone stz = ((ZoneInfo)zone).getLastRuleInstance();
 2726               if (stz == null) {
 2727                   stz = new SimpleTimeZone(zone.getRawOffset(), zone.getID());
 2728               }
 2729               savedZone = zone;
 2730               zone = stz;
 2731           }
 2732   
 2733           // Write out the 1.1 FCS object.
 2734           stream.defaultWriteObject();
 2735   
 2736           // Write out the ZoneInfo object
 2737           // 4802409: we write out even if it is null, a temporary workaround
 2738           // the real fix for bug 4844924 in corba-iiop
 2739           stream.writeObject(savedZone);
 2740           if (savedZone != null) {
 2741               zone = savedZone;
 2742           }
 2743       }
 2744   
 2745       private static class CalendarAccessControlContext {
 2746           private static final AccessControlContext INSTANCE;
 2747           static {
 2748               RuntimePermission perm = new RuntimePermission("accessClassInPackage.sun.util.calendar");
 2749               PermissionCollection perms = perm.newPermissionCollection();
 2750               perms.add(perm);
 2751               INSTANCE = new AccessControlContext(new ProtectionDomain[] {
 2752                                                       new ProtectionDomain(null, perms)
 2753                                                   });
 2754           }
 2755       }
 2756   
 2757       /**
 2758        * Reconstitutes this object from a stream (i.e., deserialize it).
 2759        */
 2760       private void readObject(ObjectInputStream stream)
 2761            throws IOException, ClassNotFoundException
 2762       {
 2763           final ObjectInputStream input = stream;
 2764           input.defaultReadObject();
 2765   
 2766           stamp = new int[FIELD_COUNT];
 2767   
 2768           // Starting with version 2 (not implemented yet), we expect that
 2769           // fields[], isSet[], isTimeSet, and areFieldsSet may not be
 2770           // streamed out anymore.  We expect 'time' to be correct.
 2771           if (serialVersionOnStream >= 2)
 2772           {
 2773               isTimeSet = true;
 2774               if (fields == null) fields = new int[FIELD_COUNT];
 2775               if (isSet == null) isSet = new boolean[FIELD_COUNT];
 2776           }
 2777           else if (serialVersionOnStream >= 0)
 2778           {
 2779               for (int i=0; i<FIELD_COUNT; ++i)
 2780                   stamp[i] = isSet[i] ? COMPUTED : UNSET;
 2781           }
 2782   
 2783           serialVersionOnStream = currentSerialVersion;
 2784   
 2785           // If there's a ZoneInfo object, use it for zone.
 2786           ZoneInfo zi = null;
 2787           try {
 2788               zi = AccessController.doPrivileged(
 2789                       new PrivilegedExceptionAction<ZoneInfo>() {
 2790                           public ZoneInfo run() throws Exception {
 2791                               return (ZoneInfo) input.readObject();
 2792                           }
 2793                       },
 2794                       CalendarAccessControlContext.INSTANCE);
 2795           } catch (PrivilegedActionException pae) {
 2796               Exception e = pae.getException();
 2797               if (!(e instanceof OptionalDataException)) {
 2798                   if (e instanceof RuntimeException) {
 2799                       throw (RuntimeException) e;
 2800                   } else if (e instanceof IOException) {
 2801                       throw (IOException) e;
 2802                   } else if (e instanceof ClassNotFoundException) {
 2803                       throw (ClassNotFoundException) e;
 2804                   }
 2805                   throw new RuntimeException(e);
 2806               }
 2807           }
 2808           if (zi != null) {
 2809               zone = zi;
 2810           }
 2811   
 2812           // If the deserialized object has a SimpleTimeZone, try to
 2813           // replace it with a ZoneInfo equivalent (as of 1.4) in order
 2814           // to be compatible with the SimpleTimeZone-based
 2815           // implementation as much as possible.
 2816           if (zone instanceof SimpleTimeZone) {
 2817               String id = zone.getID();
 2818               TimeZone tz = TimeZone.getTimeZone(id);
 2819               if (tz != null && tz.hasSameRules(zone) && tz.getID().equals(id)) {
 2820                   zone = tz;
 2821               }
 2822           }
 2823       }
 2824   }

Save This Page
Home » openjdk-7 » java » util » [javadoc | source]