Home | History | Annotate | Download | only in util
      1 /*
      2  *   Copyright (C) 1996-2015, International Business Machines
      3  *   Corporation and others.  All Rights Reserved.
      4  */
      5 
      6 package com.ibm.icu.util;
      7 
      8 import java.io.IOException;
      9 import java.io.ObjectInputStream;
     10 import java.io.ObjectOutputStream;
     11 import java.io.Serializable;
     12 import java.text.StringCharacterIterator;
     13 import java.util.ArrayList;
     14 import java.util.Date;
     15 import java.util.Locale;
     16 import java.util.MissingResourceException;
     17 
     18 import com.ibm.icu.impl.CalendarData;
     19 import com.ibm.icu.impl.CalendarUtil;
     20 import com.ibm.icu.impl.ICUCache;
     21 import com.ibm.icu.impl.ICUResourceBundle;
     22 import com.ibm.icu.impl.SimpleCache;
     23 import com.ibm.icu.impl.SoftCache;
     24 import com.ibm.icu.text.DateFormat;
     25 import com.ibm.icu.text.DateFormatSymbols;
     26 import com.ibm.icu.text.MessageFormat;
     27 import com.ibm.icu.text.SimpleDateFormat;
     28 import com.ibm.icu.util.ULocale.Category;
     29 
     30 /**
     31  * {@icuenhanced java.util.Calendar}.{@icu _usage_}
     32  *
     33  * <p><code>Calendar</code> is an abstract base class for converting between
     34  * a <code>Date</code> object and a set of integer fields such as
     35  * <code>YEAR</code>, <code>MONTH</code>, <code>DAY</code>, <code>HOUR</code>,
     36  * and so on. (A <code>Date</code> object represents a specific instant in
     37  * time with millisecond precision. See
     38  * {@link Date}
     39  * for information about the <code>Date</code> class.)
     40  *
     41  * <p>Subclasses of <code>Calendar</code> interpret a <code>Date</code>
     42  * according to the rules of a specific calendar system.  ICU4J contains
     43  * several subclasses implementing different international calendar systems.
     44  *
     45  * <p>
     46  * Like other locale-sensitive classes, <code>Calendar</code> provides a
     47  * class method, <code>getInstance</code>, for getting a generally useful
     48  * object of this type. <code>Calendar</code>'s <code>getInstance</code> method
     49  * returns a calendar of a type appropriate to the locale, whose
     50  * time fields have been initialized with the current date and time:
     51  * <blockquote>
     52  * <pre>Calendar rightNow = Calendar.getInstance()</pre>
     53  * </blockquote>
     54  *
     55  * <p>When a <code>ULocale</code> is used by <code>getInstance</code>, its
     56  * '<code>calendar</code>' tag and value are retrieved if present.  If a recognized
     57  * value is supplied, a calendar is provided and configured as appropriate.
     58  * Currently recognized tags are "buddhist", "chinese", "coptic", "ethiopic",
     59  * "gregorian", "hebrew", "islamic", "islamic-civil", "japanese", and "roc".  For
     60  * example: <blockquote>
     61  * <pre>Calendar cal = Calendar.getInstance(new ULocale("en_US@calendar=japanese"));</pre>
     62  * </blockquote> will return an instance of JapaneseCalendar (using en_US conventions for
     63  * minimum days in first week, start day of week, et cetera).
     64  *
     65  * <p>A <code>Calendar</code> object can produce all the time field values
     66  * needed to implement the date-time formatting for a particular language and
     67  * calendar style (for example, Japanese-Gregorian, Japanese-Traditional).
     68  * <code>Calendar</code> defines the range of values returned by certain fields,
     69  * as well as their meaning.  For example, the first month of the year has value
     70  * <code>MONTH</code> == <code>JANUARY</code> for all calendars.  Other values
     71  * are defined by the concrete subclass, such as <code>ERA</code> and
     72  * <code>YEAR</code>.  See individual field documentation and subclass
     73  * documentation for details.
     74  *
     75  * <p>When a <code>Calendar</code> is <em>lenient</em>, it accepts a wider range
     76  * of field values than it produces.  For example, a lenient
     77  * <code>GregorianCalendar</code> interprets <code>MONTH</code> ==
     78  * <code>JANUARY</code>, <code>DAY_OF_MONTH</code> == 32 as February 1.  A
     79  * non-lenient <code>GregorianCalendar</code> throws an exception when given
     80  * out-of-range field settings.  When calendars recompute field values for
     81  * return by <code>get()</code>, they normalize them.  For example, a
     82  * <code>GregorianCalendar</code> always produces <code>DAY_OF_MONTH</code>
     83  * values between 1 and the length of the month.
     84  *
     85  * <p><code>Calendar</code> defines a locale-specific seven day week using two
     86  * parameters: the first day of the week and the minimal days in first week
     87  * (from 1 to 7).  These numbers are taken from the locale resource data when a
     88  * <code>Calendar</code> is constructed.  They may also be specified explicitly
     89  * through the API.
     90  *
     91  * <p>When setting or getting the <code>WEEK_OF_MONTH</code> or
     92  * <code>WEEK_OF_YEAR</code> fields, <code>Calendar</code> must determine the
     93  * first week of the month or year as a reference point.  The first week of a
     94  * month or year is defined as the earliest seven day period beginning on
     95  * <code>getFirstDayOfWeek()</code> and containing at least
     96  * <code>getMinimalDaysInFirstWeek()</code> days of that month or year.  Weeks
     97  * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow
     98  * it.  Note that the normalized numbering returned by <code>get()</code> may be
     99  * different.  For example, a specific <code>Calendar</code> subclass may
    100  * designate the week before week 1 of a year as week <em>n</em> of the previous
    101  * year.
    102  *
    103  * <p> When computing a <code>Date</code> from time fields, some special
    104  * circumstances may arise: there may be insufficient information to compute the
    105  * <code>Date</code> (such as only year and month but no day in the month),
    106  * there may be inconsistent information (such as "Tuesday, July 15, 1996" --
    107  * July 15, 1996 is actually a Monday), or the input time might be ambiguous
    108  * because of time zone transition.
    109  *
    110  * <p><strong>Insufficient information.</strong> The calendar will use default
    111  * information to specify the missing fields. This may vary by calendar; for
    112  * the Gregorian calendar, the default for a field is the same as that of the
    113  * start of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc.
    114  *
    115  * <p><strong>Inconsistent information.</strong> If fields conflict, the calendar
    116  * will give preference to fields set more recently. For example, when
    117  * determining the day, the calendar will look for one of the following
    118  * combinations of fields.  The most recent combination, as determined by the
    119  * most recently set single field, will be used.
    120  *
    121  * <blockquote>
    122  * <pre>
    123  * MONTH + DAY_OF_MONTH
    124  * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
    125  * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
    126  * DAY_OF_YEAR
    127  * DAY_OF_WEEK + WEEK_OF_YEAR</pre>
    128  * </blockquote>
    129  *
    130  * For the time of day:
    131  *
    132  * <blockquote>
    133  * <pre>
    134  * HOUR_OF_DAY
    135  * AM_PM + HOUR</pre>
    136  * </blockquote>
    137  *
    138  * <p><strong>Ambiguous Wall Clock Time.</strong> When time offset from UTC has
    139  * changed, it produces an ambiguous time slot around the transition. For example,
    140  * many US locations observe daylight saving time. On the date switching to daylight
    141  * saving time in US, wall clock time jumps from 12:59 AM (standard) to 2:00 AM
    142  * (daylight). Therefore, wall clock time from 1:00 AM to 1:59 AM do not exist on
    143  * the date. When the input wall time fall into this missing time slot, the ICU
    144  * Calendar resolves the time using the UTC offset before the transition by default.
    145  * In this example, 1:30 AM is interpreted as 1:30 AM standard time (non-exist),
    146  * so the final result will be 2:30 AM daylight time.
    147  *
    148  * <p>On the date switching back to standard time, wall clock time is moved back one
    149  * hour at 2:00 AM. So wall clock time from 1:00 AM to 1:59 AM occur twice. In this
    150  * case, the ICU Calendar resolves the time using the UTC offset after the transition
    151  * by default. For example, 1:30 AM on the date is resolved as 1:30 AM standard time.
    152  *
    153  * <p>Ambiguous wall clock time resolution behaviors can be customized by Calendar APIs
    154  * {@link #setRepeatedWallTimeOption(int)} and {@link #setSkippedWallTimeOption(int)}.
    155  * These methods are available in ICU 49 or later versions.
    156  *
    157  * <p><strong>Note:</strong> for some non-Gregorian calendars, different
    158  * fields may be necessary for complete disambiguation. For example, a full
    159  * specification of the historial Arabic astronomical calendar requires year,
    160  * month, day-of-month <em>and</em> day-of-week in some cases.
    161  *
    162  * <p><strong>Note:</strong> There are certain possible ambiguities in
    163  * interpretation of certain singular times, which are resolved in the
    164  * following ways:
    165  * <ol>
    166  *     <li> 24:00:00 "belongs" to the following day. That is,
    167  *          23:59 on Dec 31, 1969 &lt; 24:00 on Jan 1, 1970 &lt; 24:01:00 on Jan 1, 1970
    168  *
    169  *     <li> Although historically not precise, midnight also belongs to "am",
    170  *          and noon belongs to "pm", so on the same day,
    171  *          12:00 am (midnight) &lt; 12:01 am, and 12:00 pm (noon) &lt; 12:01 pm
    172  * </ol>
    173  *
    174  * <p>The date or time format strings are not part of the definition of a
    175  * calendar, as those must be modifiable or overridable by the user at
    176  * runtime. Use {@link DateFormat}
    177  * to format dates.
    178  *
    179  * <p><strong>Field manipulation methods</strong></p>
    180  *
    181  * <p><code>Calendar</code> fields can be changed using three methods:
    182  * <code>set()</code>, <code>add()</code>, and <code>roll()</code>.</p>
    183  *
    184  * <p><strong><code>set(f, value)</code></strong> changes field
    185  * <code>f</code> to <code>value</code>.  In addition, it sets an
    186  * internal member variable to indicate that field <code>f</code> has
    187  * been changed. Although field <code>f</code> is changed immediately,
    188  * the calendar's milliseconds is not recomputed until the next call to
    189  * <code>get()</code>, <code>getTime()</code>, or
    190  * <code>getTimeInMillis()</code> is made. Thus, multiple calls to
    191  * <code>set()</code> do not trigger multiple, unnecessary
    192  * computations. As a result of changing a field using
    193  * <code>set()</code>, other fields may also change, depending on the
    194  * field, the field value, and the calendar system. In addition,
    195  * <code>get(f)</code> will not necessarily return <code>value</code>
    196  * after the fields have been recomputed. The specifics are determined by
    197  * the concrete calendar class.</p>
    198  *
    199  * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
    200  * originally set to August 31, 1999. Calling <code>set(Calendar.MONTH,
    201  * Calendar.SEPTEMBER)</code> sets the calendar to September 31,
    202  * 1999. This is a temporary internal representation that resolves to
    203  * October 1, 1999 if <code>getTime()</code>is then called. However, a
    204  * call to <code>set(Calendar.DAY_OF_MONTH, 30)</code> before the call to
    205  * <code>getTime()</code> sets the calendar to September 30, 1999, since
    206  * no recomputation occurs after <code>set()</code> itself.</p>
    207  *
    208  * <p><strong><code>add(f, delta)</code></strong> adds <code>delta</code>
    209  * to field <code>f</code>.  This is equivalent to calling <code>set(f,
    210  * get(f) + delta)</code> with two adjustments:</p>
    211  *
    212  * <blockquote>
    213  *   <p><strong>Add rule 1</strong>. The value of field <code>f</code>
    214  *   after the call minus the value of field <code>f</code> before the
    215  *   call is <code>delta</code>, modulo any overflow that has occurred in
    216  *   field <code>f</code>. Overflow occurs when a field value exceeds its
    217  *   range and, as a result, the next larger field is incremented or
    218  *   decremented and the field value is adjusted back into its range.</p>
    219  *
    220  *   <p><strong>Add rule 2</strong>. If a smaller field is expected to be
    221  *   invariant, but &nbsp; it is impossible for it to be equal to its
    222  *   prior value because of changes in its minimum or maximum after field
    223  *   <code>f</code> is changed, then its value is adjusted to be as close
    224  *   as possible to its expected value. A smaller field represents a
    225  *   smaller unit of time. <code>HOUR</code> is a smaller field than
    226  *   <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields
    227  *   that are not expected to be invariant. The calendar system
    228  *   determines what fields are expected to be invariant.</p>
    229  * </blockquote>
    230  *
    231  * <p>In addition, unlike <code>set()</code>, <code>add()</code> forces
    232  * an immediate recomputation of the calendar's milliseconds and all
    233  * fields.</p>
    234  *
    235  * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
    236  * originally set to August 31, 1999. Calling <code>add(Calendar.MONTH,
    237  * 13)</code> sets the calendar to September 30, 2000. <strong>Add rule
    238  * 1</strong> sets the <code>MONTH</code> field to September, since
    239  * adding 13 months to August gives September of the next year. Since
    240  * <code>DAY_OF_MONTH</code> cannot be 31 in September in a
    241  * <code>GregorianCalendar</code>, <strong>add rule 2</strong> sets the
    242  * <code>DAY_OF_MONTH</code> to 30, the closest possible value. Although
    243  * it is a smaller field, <code>DAY_OF_WEEK</code> is not adjusted by
    244  * rule 2, since it is expected to change when the month changes in a
    245  * <code>GregorianCalendar</code>.</p>
    246  *
    247  * <p><strong><code>roll(f, delta)</code></strong> adds
    248  * <code>delta</code> to field <code>f</code> without changing larger
    249  * fields. This is equivalent to calling <code>add(f, delta)</code> with
    250  * the following adjustment:</p>
    251  *
    252  * <blockquote>
    253  *   <p><strong>Roll rule</strong>. Larger fields are unchanged after the
    254  *   call. A larger field represents a larger unit of
    255  *   time. <code>DAY_OF_MONTH</code> is a larger field than
    256  *   <code>HOUR</code>.</p>
    257  * </blockquote>
    258  *
    259  * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
    260  * originally set to August 31, 1999. Calling <code>roll(Calendar.MONTH,
    261  * 8)</code> sets the calendar to April 30, <strong>1999</strong>.  Add
    262  * rule 1 sets the <code>MONTH</code> field to April. Using a
    263  * <code>GregorianCalendar</code>, the <code>DAY_OF_MONTH</code> cannot
    264  * be 31 in the month April. Add rule 2 sets it to the closest possible
    265  * value, 30. Finally, the <strong>roll rule</strong> maintains the
    266  * <code>YEAR</code> field value of 1999.</p>
    267  *
    268  * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
    269  * originally set to Sunday June 6, 1999. Calling
    270  * <code>roll(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to
    271  * Tuesday June 1, 1999, whereas calling
    272  * <code>add(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to
    273  * Sunday May 30, 1999. This is because the roll rule imposes an
    274  * additional constraint: The <code>MONTH</code> must not change when the
    275  * <code>WEEK_OF_MONTH</code> is rolled. Taken together with add rule 1,
    276  * the resultant date must be between Tuesday June 1 and Saturday June
    277  * 5. According to add rule 2, the <code>DAY_OF_WEEK</code>, an invariant
    278  * when changing the <code>WEEK_OF_MONTH</code>, is set to Tuesday, the
    279  * closest possible value to Sunday (where Sunday is the first day of the
    280  * week).</p>
    281  *
    282  * <p><strong>Usage model</strong>. To motivate the behavior of
    283  * <code>add()</code> and <code>roll()</code>, consider a user interface
    284  * component with increment and decrement buttons for the month, day, and
    285  * year, and an underlying <code>GregorianCalendar</code>. If the
    286  * interface reads January 31, 1999 and the user presses the month
    287  * increment button, what should it read? If the underlying
    288  * implementation uses <code>set()</code>, it might read March 3, 1999. A
    289  * better result would be February 28, 1999. Furthermore, if the user
    290  * presses the month increment button again, it should read March 31,
    291  * 1999, not March 28, 1999. By saving the original date and using either
    292  * <code>add()</code> or <code>roll()</code>, depending on whether larger
    293  * fields should be affected, the user interface can behave as most users
    294  * will intuitively expect.</p>
    295  *
    296  * <p><b>Note:</b> You should always use {@link #roll roll} and {@link #add add} rather
    297  * than attempting to perform arithmetic operations directly on the fields
    298  * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
    299  * to have fields with non-linear behavior, for example missing months
    300  * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
    301  * methods will take this into account, while simple arithmetic manipulations
    302  * may give invalid results.
    303  *
    304  * <p><big><big><b>Calendar Architecture in ICU4J</b></big></big></p>
    305  *
    306  * <p>Recently the implementation of <code>Calendar</code> has changed
    307  * significantly in order to better support subclassing. The original
    308  * <code>Calendar</code> class was designed to support subclassing, but
    309  * it had only one implemented subclass, <code>GregorianCalendar</code>.
    310  * With the implementation of several new calendar subclasses, including
    311  * the <code>BuddhistCalendar</code>, <code>ChineseCalendar</code>,
    312  * <code>HebrewCalendar</code>, <code>IslamicCalendar</code>, and
    313  * <code>JapaneseCalendar</code>, the subclassing API has been reworked
    314  * thoroughly. This section details the new subclassing API and other
    315  * ways in which <code>com.ibm.icu.util.Calendar</code> differs from
    316  * <code>java.util.Calendar</code>.
    317  * </p>
    318  *
    319  * <p><big><b>Changes</b></big></p>
    320  *
    321  * <p>Overview of changes between the classic <code>Calendar</code>
    322  * architecture and the new architecture.
    323  *
    324  * <ul>
    325  *
    326  *   <li>The <code>fields[]</code> array is <code>private</code> now
    327  *     instead of <code>protected</code>.  Subclasses must access it
    328  *     using the methods {@link #internalSet} and
    329  *     {@link #internalGet}.  <b>Motivation:</b> Subclasses should
    330  *     not directly access data members.</li>
    331  *
    332  *   <li>The <code>time</code> long word is <code>private</code> now
    333  *     instead of <code>protected</code>.  Subclasses may access it using
    334  *     the method {@link #internalGetTimeInMillis}, which does not
    335  *     provoke an update. <b>Motivation:</b> Subclasses should not
    336  *     directly access data members.</li>
    337  *
    338  *   <li>The scope of responsibility of subclasses has been drastically
    339  *     reduced. As much functionality as possible is implemented in the
    340  *     <code>Calendar</code> base class. As a result, it is much easier
    341  *     to subclass <code>Calendar</code>. <b>Motivation:</b> Subclasses
    342  *     should not have to reimplement common code. Certain behaviors are
    343  *     common across calendar systems: The definition and behavior of
    344  *     week-related fields and time fields, the arithmetic
    345  *     ({@link #add(int, int) add} and {@link #roll(int, int) roll}) behavior of many
    346  *     fields, and the field validation system.</li>
    347  *
    348  *   <li>The subclassing API has been completely redesigned.</li>
    349  *
    350  *   <li>The <code>Calendar</code> base class contains some Gregorian
    351  *     calendar algorithmic support that subclasses can use (specifically
    352  *     in {@link #handleComputeFields}).  Subclasses can use the
    353  *     methods <code>getGregorianXxx()</code> to obtain precomputed
    354  *     values. <b>Motivation:</b> This is required by all
    355  *     <code>Calendar</code> subclasses in order to implement consistent
    356  *     time zone behavior, and Gregorian-derived systems can use the
    357  *     already computed data.</li>
    358  *
    359  *   <li>The <code>FIELD_COUNT</code> constant has been removed. Use
    360  *     {@link #getFieldCount}.  In addition, framework API has been
    361  *     added to allow subclasses to define additional fields.
    362  *     <b>Motivation: </b>The number of fields is not constant across
    363  *     calendar systems.</li>
    364  *
    365  *   <li>The range of handled dates has been narrowed from +/-
    366  *     ~300,000,000 years to +/- ~5,000,000 years. In practical terms
    367  *     this should not affect clients. However, it does mean that client
    368  *     code cannot be guaranteed well-behaved results with dates such as
    369  *     <code>Date(Long.MIN_VALUE)</code> or
    370  *     <code>Date(Long.MAX_VALUE)</code>. Instead, the
    371  *     <code>Calendar</code> protected constants should be used.
    372  *     <b>Motivation:</b> With
    373  *     the addition of the {@link #JULIAN_DAY} field, Julian day
    374  *     numbers must be restricted to a 32-bit <code>int</code>.  This
    375  *     restricts the overall supported range. Furthermore, restricting
    376  *     the supported range simplifies the computations by removing
    377  *     special case code that was used to accomodate arithmetic overflow
    378  *     at millis near <code>Long.MIN_VALUE</code> and
    379  *     <code>Long.MAX_VALUE</code>.</li>
    380  *
    381  *   <li>New fields are implemented: {@link #JULIAN_DAY} defines
    382  *     single-field specification of the
    383  *     date. {@link #MILLISECONDS_IN_DAY} defines a single-field
    384  *     specification of the wall time. {@link #DOW_LOCAL} and
    385  *     {@link #YEAR_WOY} implement localized day-of-week and
    386  *     week-of-year behavior.</li>
    387  *
    388  *   <li>Subclasses can access protected millisecond constants
    389  *   defined in <code>Calendar</code>.</li>
    390  *
    391  *   <li>New API has been added to support calendar-specific subclasses
    392  *     of <code>DateFormat</code>.</li>
    393  *
    394  *   <li>Several subclasses have been implemented, representing
    395  *     various international calendar systems.</li>
    396  *
    397  * </ul>
    398  *
    399  * <p><big><b>Subclass API</b></big></p>
    400  *
    401  * <p>The original <code>Calendar</code> API was based on the experience
    402  * of implementing a only a single subclass,
    403  * <code>GregorianCalendar</code>. As a result, all of the subclassing
    404  * kinks had not been worked out. The new subclassing API has been
    405  * refined based on several implemented subclasses. This includes methods
    406  * that must be overridden and methods for subclasses to call. Subclasses
    407  * no longer have direct access to <code>fields</code> and
    408  * <code>stamp</code>. Instead, they have new API to access
    409  * these. Subclasses are able to allocate the <code>fields</code> array
    410  * through a protected framework method; this allows subclasses to
    411  * specify additional fields. </p>
    412  *
    413  * <p>More functionality has been moved into the base class. The base
    414  * class now contains much of the computational machinery to support the
    415  * Gregorian calendar. This is based on two things: (1) Many calendars
    416  * are based on the Gregorian calendar (such as the Buddhist and Japanese
    417  * imperial calendars). (2) <em>All</em> calendars require basic
    418  * Gregorian support in order to handle timezone computations. </p>
    419  *
    420  * <p>Common computations have been moved into
    421  * <code>Calendar</code>. Subclasses no longer compute the week related
    422  * fields and the time related fields. These are commonly handled for all
    423  * calendars by the base class. </p>
    424  *
    425  * <p><b>Subclass computation of time <tt>=&gt;</tt> fields</b>
    426  *
    427  * <p>The {@link #ERA}, {@link #YEAR},
    428  * {@link #EXTENDED_YEAR}, {@link #MONTH},
    429  * {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields are
    430  * computed by the subclass, based on the Julian day. All other fields
    431  * are computed by <code>Calendar</code>.
    432  *
    433  * <ul>
    434  *
    435  *   <li>Subclasses should implement {@link #handleComputeFields}
    436  *     to compute the {@link #ERA}, {@link #YEAR},
    437  *     {@link #EXTENDED_YEAR}, {@link #MONTH},
    438  *     {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields,
    439  *     based on the value of the {@link #JULIAN_DAY} field. If there
    440  *     are calendar-specific fields not defined by <code>Calendar</code>,
    441  *     they must also be computed. These are the only fields that the
    442  *     subclass should compute. All other fields are computed by the base
    443  *     class, so time and week fields behave in a consistent way across
    444  *     all calendars. The default version of this method in
    445  *     <code>Calendar</code> implements a proleptic Gregorian
    446  *     calendar. Within this method, subclasses may call
    447  *     <code>getGregorianXxx()</code> to obtain the Gregorian calendar
    448  *     month, day of month, and extended year for the given date.</li>
    449  *
    450  * </ul>
    451  *
    452  * <p><b>Subclass computation of fields <tt>=&gt;</tt> time</b>
    453  *
    454  * <p>The interpretation of most field values is handled entirely by
    455  * <code>Calendar</code>. <code>Calendar</code> determines which fields
    456  * are set, which are not, which are set more recently, and so on. In
    457  * addition, <code>Calendar</code> handles the computation of the time
    458  * from the time fields and handles the week-related fields. The only
    459  * thing the subclass must do is determine the extended year, based on
    460  * the year fields, and then, given an extended year and a month, it must
    461  * return a Julian day number.
    462  *
    463  * <ul>
    464  *
    465  *   <li>Subclasses should implement {@link #handleGetExtendedYear}
    466  *     to return the extended year for this calendar system, based on the
    467  *     {@link #YEAR}, {@link #EXTENDED_YEAR}, and any fields that
    468  *     the calendar system uses that are larger than a year, such as
    469  *     {@link #ERA}.</li>
    470  *
    471  *   <li>Subclasses should implement {@link #handleComputeMonthStart}
    472  *     to return the Julian day number
    473  *     associated with a month and extended year. This is the Julian day
    474  *     number of the day before the first day of the month. The month
    475  *     number is zero-based. This computation should not depend on any
    476  *     field values.</li>
    477  *
    478  * </ul>
    479  *
    480  * <p><b>Other methods</b>
    481  *
    482  * <ul>
    483  *
    484  *   <li>Subclasses should implement {@link #handleGetMonthLength}
    485  *     to return the number of days in a
    486  *     given month of a given extended year. The month number, as always,
    487  *     is zero-based.</li>
    488  *
    489  *   <li>Subclasses should implement {@link #handleGetYearLength}
    490  *     to return the number of days in the given
    491  *     extended year. This method is used by
    492  *     <tt>computeWeekFields</tt> to compute the
    493  *     {@link #WEEK_OF_YEAR} and {@link #YEAR_WOY} fields.</li>
    494  *
    495  *   <li>Subclasses should implement {@link #handleGetLimit}
    496  *     to return the protected values of a field, depending on the value of
    497  *     <code>limitType</code>. This method only needs to handle the
    498  *     fields {@link #ERA}, {@link #YEAR}, {@link #MONTH},
    499  *     {@link #WEEK_OF_YEAR}, {@link #WEEK_OF_MONTH},
    500  *     {@link #DAY_OF_MONTH}, {@link #DAY_OF_YEAR},
    501  *     {@link #DAY_OF_WEEK_IN_MONTH}, {@link #YEAR_WOY}, and
    502  *     {@link #EXTENDED_YEAR}.  Other fields are invariant (with
    503  *     respect to calendar system) and are handled by the base
    504  *     class.</li>
    505  *
    506  *   <li>Optionally, subclasses may override {@link #validateField}
    507  *     to check any subclass-specific fields. If the
    508  *     field's value is out of range, the method should throw an
    509  *     <code>IllegalArgumentException</code>. The method may call
    510  *     <code>super.validateField(field)</code> to handle fields in a
    511  *     generic way, that is, to compare them to the range
    512  *     <code>getMinimum(field)</code>..<code>getMaximum(field)</code>.</li>
    513  *
    514  *   <li>Optionally, subclasses may override
    515  *     {@link #handleCreateFields} to create an <code>int[]</code>
    516  *     array large enough to hold the calendar's fields. This is only
    517  *     necessary if the calendar defines additional fields beyond those
    518  *     defined by <code>Calendar</code>. The length of the result must be
    519  *     be between the base and maximum field counts.</li>
    520  *
    521  *   <li>Optionally, subclasses may override
    522  *     {@link #handleGetDateFormat} to create a
    523  *     <code>DateFormat</code> appropriate to this calendar. This is only
    524  *     required if a calendar subclass redefines the use of a field (for
    525  *     example, changes the {@link #ERA} field from a symbolic field
    526  *     to a numeric one) or defines an additional field.</li>
    527  *
    528  *   <li>Optionally, subclasses may override {@link #roll roll} and
    529  *     {@link #add add} to handle fields that are discontinuous. For
    530  *     example, in the Hebrew calendar the month &quot;Adar I&quot; only
    531  *     occurs in leap years; in other years the calendar jumps from
    532  *     Shevat (month #4) to Adar (month #6). The {@link
    533  *     HebrewCalendar#add HebrewCalendar.add} and {@link
    534  *     HebrewCalendar#roll HebrewCalendar.roll} methods take this into
    535  *     account, so that adding 1 month to Shevat gives the proper result
    536  *     (Adar) in a non-leap year. The protected utility method {@link
    537  *     #pinField pinField} is often useful when implementing these two
    538  *     methods. </li>
    539  *
    540  * </ul>
    541  *
    542  * <p><big><b>Normalized behavior</b></big>
    543  *
    544  * <p>The behavior of certain fields has been made consistent across all
    545  * calendar systems and implemented in <code>Calendar</code>.
    546  *
    547  * <ul>
    548  *
    549  *   <li>Time is normalized. Even though some calendar systems transition
    550  *     between days at sunset or at other times, all ICU4J calendars
    551  *     transition between days at <em>local zone midnight</em>.  This
    552  *     allows ICU4J to centralize the time computations in
    553  *     <code>Calendar</code> and to maintain basic correpsondences
    554  *     between calendar systems. Affected fields: {@link #AM_PM},
    555  *     {@link #HOUR}, {@link #HOUR_OF_DAY}, {@link #MINUTE},
    556  *     {@link #SECOND}, {@link #MILLISECOND},
    557  *     {@link #ZONE_OFFSET}, and {@link #DST_OFFSET}.</li>
    558  *
    559  *   <li>DST behavior is normalized. Daylight savings time behavior is
    560  *     computed the same for all calendar systems, and depends on the
    561  *     value of several <code>GregorianCalendar</code> fields: the
    562  *     {@link #YEAR}, {@link #MONTH}, and
    563  *     {@link #DAY_OF_MONTH}. As a result, <code>Calendar</code>
    564  *     always computes these fields, even for non-Gregorian calendar
    565  *     systems. These fields are available to subclasses.</li>
    566  *
    567  *   <li>Weeks are normalized. Although locales define the week
    568  *     differently, in terms of the day on which it starts, and the
    569  *     designation of week number one of a month or year, they all use a
    570  *     common mechanism. Furthermore, the day of the week has a simple
    571  *     and consistent definition throughout history. For example,
    572  *     although the Gregorian calendar introduced a discontinuity when
    573  *     first instituted, the day of week was not disrupted. For this
    574  *     reason, the fields {@link #DAY_OF_WEEK}, <code>WEEK_OF_YEAR,
    575  *     WEEK_OF_MONTH</code>, {@link #DAY_OF_WEEK_IN_MONTH},
    576  *     {@link #DOW_LOCAL}, {@link #YEAR_WOY} are all computed in
    577  *     a consistent way in the base class, based on the
    578  *     {@link #EXTENDED_YEAR}, {@link #DAY_OF_YEAR},
    579  *     {@link #MONTH}, and {@link #DAY_OF_MONTH}, which are
    580  *     computed by the subclass.</li>
    581  *
    582  * </ul>
    583  *
    584  * <p><big><b>Supported range</b></big>
    585  *
    586  * <p>The allowable range of <code>Calendar</code> has been
    587  * narrowed. <code>GregorianCalendar</code> used to attempt to support
    588  * the range of dates with millisecond values from
    589  * <code>Long.MIN_VALUE</code> to <code>Long.MAX_VALUE</code>. This
    590  * introduced awkward constructions (hacks) which slowed down
    591  * performance. It also introduced non-uniform behavior at the
    592  * boundaries. The new <code>Calendar</code> protocol specifies the
    593  * maximum range of supportable dates as those having Julian day numbers
    594  * of <code>-0x7F000000</code> to <code>+0x7F000000</code>. This
    595  * corresponds to years from ~5,800,000 BCE to ~5,800,000 CE. Programmers
    596  * should use the protected constants in <code>Calendar</code> to
    597  * specify an extremely early or extremely late date.</p>
    598  *
    599  * <p><big><b>General notes</b></big>
    600  *
    601  * <ul>
    602  *
    603  *   <li>Calendars implementations are <em>proleptic</em>. For example,
    604  *     even though the Gregorian calendar was not instituted until the
    605  *     16th century, the <code>GregorianCalendar</code> class supports
    606  *     dates before the historical onset of the calendar by extending the
    607  *     calendar system backward in time. Similarly, the
    608  *     <code>HebrewCalendar</code> extends backward before the start of
    609  *     its epoch into zero and negative years. Subclasses do not throw
    610  *     exceptions because a date precedes the historical start of a
    611  *     calendar system. Instead, they implement
    612  *     {@link #handleGetLimit} to return appropriate limits on
    613  *     {@link #YEAR}, {@link #ERA}, etc. fields. Then, if the
    614  *     calendar is set to not be lenient, out-of-range field values will
    615  *     trigger an exception.</li>
    616  *
    617  *   <li>Calendar system subclasses compute a <em>extended
    618  *     year</em>. This differs from the {@link #YEAR} field in that
    619  *     it ranges over all integer values, including zero and negative
    620  *     values, and it encapsulates the information of the
    621  *     {@link #YEAR} field and all larger fields.  Thus, for the
    622  *     Gregorian calendar, the {@link #EXTENDED_YEAR} is computed as
    623  *     <code>ERA==AD ? YEAR : 1-YEAR</code>. Another example is the Mayan
    624  *     long count, which has years (<code>KUN</code>) and nested cycles
    625  *     of years (<code>KATUN</code> and <code>BAKTUN</code>). The Mayan
    626  *     {@link #EXTENDED_YEAR} is computed as <code>TUN + 20 * (KATUN
    627  *     + 20 * BAKTUN)</code>. The <code>Calendar</code> base class uses
    628  *     the {@link #EXTENDED_YEAR} field to compute the week-related
    629  *     fields.</li>
    630  *
    631  * </ul>
    632  *
    633  * @see          Date
    634  * @see          GregorianCalendar
    635  * @see          TimeZone
    636  * @see          DateFormat
    637  * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu, Laura Werner
    638  * @stable ICU 2.0
    639  */
    640 public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {
    641 
    642     // Data flow in Calendar
    643     // ---------------------
    644 
    645     // The current time is represented in two ways by Calendar: as UTC
    646     // milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local
    647     // fields such as MONTH, HOUR, AM_PM, etc.  It is possible to compute the
    648     // millis from the fields, and vice versa.  The data needed to do this
    649     // conversion is encapsulated by a TimeZone object owned by the Calendar.
    650     // The data provided by the TimeZone object may also be overridden if the
    651     // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
    652     // keeps track of what information was most recently set by the caller, and
    653     // uses that to compute any other information as needed.
    654 
    655     // If the user sets the fields using set(), the data flow is as follows.
    656     // This is implemented by the Calendar subclass's computeTime() method.
    657     // During this process, certain fields may be ignored.  The disambiguation
    658     // algorithm for resolving which fields to pay attention to is described
    659     // above.
    660 
    661     //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
    662     //           |
    663     //           | Using Calendar-specific algorithm
    664     //           V
    665     //   local standard millis
    666     //           |
    667     //           | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
    668     //           V
    669     //   UTC millis (in time data member)
    670 
    671     // If the user sets the UTC millis using setTime(), the data flow is as
    672     // follows.  This is implemented by the Calendar subclass's computeFields()
    673     // method.
    674 
    675     //   UTC millis (in time data member)
    676     //           |
    677     //           | Using TimeZone getOffset()
    678     //           V
    679     //   local standard millis
    680     //           |
    681     //           | Using Calendar-specific algorithm
    682     //           V
    683     //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
    684 
    685     // In general, a round trip from fields, through local and UTC millis, and
    686     // back out to fields is made when necessary.  This is implemented by the
    687     // complete() method.  Resolving a partial set of fields into a UTC millis
    688     // value allows all remaining fields to be generated from that value.  If
    689     // the Calendar is lenient, the fields are also renormalized to standard
    690     // ranges when they are regenerated.
    691 
    692     /**
    693      * Field number for <code>get</code> and <code>set</code> indicating the
    694      * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific
    695      * value; see subclass documentation.
    696      * @see GregorianCalendar#AD
    697      * @see GregorianCalendar#BC
    698      * @stable ICU 2.0
    699      */
    700     public final static int ERA = 0;
    701 
    702     /**
    703      * Field number for <code>get</code> and <code>set</code> indicating the
    704      * year. This is a calendar-specific value; see subclass documentation.
    705      * @stable ICU 2.0
    706      */
    707     public final static int YEAR = 1;
    708 
    709     /**
    710      * Field number for <code>get</code> and <code>set</code> indicating the
    711      * month. This is a calendar-specific value. The first month of the year is
    712      * <code>JANUARY</code>; the last depends on the number of months in a year.
    713      * @see #JANUARY
    714      * @see #FEBRUARY
    715      * @see #MARCH
    716      * @see #APRIL
    717      * @see #MAY
    718      * @see #JUNE
    719      * @see #JULY
    720      * @see #AUGUST
    721      * @see #SEPTEMBER
    722      * @see #OCTOBER
    723      * @see #NOVEMBER
    724      * @see #DECEMBER
    725      * @see #UNDECIMBER
    726      * @stable ICU 2.0
    727      */
    728     public final static int MONTH = 2;
    729 
    730     /**
    731      * Field number for <code>get</code> and <code>set</code> indicating the
    732      * week number within the current year.  The first week of the year, as
    733      * defined by {@link #getFirstDayOfWeek()} and
    734      * {@link #getMinimalDaysInFirstWeek()}, has value 1.  Subclasses define
    735      * the value of {@link #WEEK_OF_YEAR} for days before the first week of
    736      * the year.
    737      * @see #getFirstDayOfWeek
    738      * @see #getMinimalDaysInFirstWeek
    739      * @stable ICU 2.0
    740      */
    741     public final static int WEEK_OF_YEAR = 3;
    742 
    743     /**
    744      * Field number for <code>get</code> and <code>set</code> indicating the
    745      * week number within the current month.  The first week of the month, as
    746      * defined by {@link #getFirstDayOfWeek()} and
    747      * {@link #getMinimalDaysInFirstWeek()}, has value 1.  Subclasses define
    748      * the value of {@link #WEEK_OF_MONTH} for days before the first week of
    749      * the month.
    750      * @see #getFirstDayOfWeek
    751      * @see #getMinimalDaysInFirstWeek
    752      * @stable ICU 2.0
    753      */
    754     public final static int WEEK_OF_MONTH = 4;
    755 
    756     /**
    757      * Field number for <code>get</code> and <code>set</code> indicating the
    758      * day of the month. This is a synonym for {@link #DAY_OF_MONTH}.
    759      * The first day of the month has value 1.
    760      * @see #DAY_OF_MONTH
    761      * @stable ICU 2.0
    762      */
    763     public final static int DATE = 5;
    764 
    765     /**
    766      * Field number for <code>get</code> and <code>set</code> indicating the
    767      * day of the month. This is a synonym for {@link #DATE}.
    768      * The first day of the month has value 1.
    769      * @see #DATE
    770      * @stable ICU 2.0
    771      */
    772     public final static int DAY_OF_MONTH = 5;
    773 
    774     /**
    775      * Field number for <code>get</code> and <code>set</code> indicating the day
    776      * number within the current year.  The first day of the year has value 1.
    777      * @stable ICU 2.0
    778      */
    779     public final static int DAY_OF_YEAR = 6;
    780 
    781     /**
    782      * Field number for <code>get</code> and <code>set</code> indicating the day
    783      * of the week.  This field takes values {@link #SUNDAY},
    784      * {@link #MONDAY}, {@link #TUESDAY}, {@link #WEDNESDAY},
    785      * {@link #THURSDAY}, {@link #FRIDAY}, and {@link #SATURDAY}.
    786      * @see #SUNDAY
    787      * @see #MONDAY
    788      * @see #TUESDAY
    789      * @see #WEDNESDAY
    790      * @see #THURSDAY
    791      * @see #FRIDAY
    792      * @see #SATURDAY
    793      * @stable ICU 2.0
    794      */
    795     public final static int DAY_OF_WEEK = 7;
    796 
    797     /**
    798      * Field number for <code>get</code> and <code>set</code> indicating the
    799      * ordinal number of the day of the week within the current month. Together
    800      * with the {@link #DAY_OF_WEEK} field, this uniquely specifies a day
    801      * within a month.  Unlike {@link #WEEK_OF_MONTH} and
    802      * {@link #WEEK_OF_YEAR}, this field's value does <em>not</em> depend on
    803      * {@link #getFirstDayOfWeek()} or
    804      * {@link #getMinimalDaysInFirstWeek()}.  <code>DAY_OF_MONTH 1</code>
    805      * through <code>7</code> always correspond to <code>DAY_OF_WEEK_IN_MONTH
    806      * 1</code>; <code>8</code> through <code>15</code> correspond to
    807      * <code>DAY_OF_WEEK_IN_MONTH 2</code>, and so on.
    808      * <code>DAY_OF_WEEK_IN_MONTH 0</code> indicates the week before
    809      * <code>DAY_OF_WEEK_IN_MONTH 1</code>.  Negative values count back from the
    810      * end of the month, so the last Sunday of a month is specified as
    811      * <code>DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1</code>.  Because
    812      * negative values count backward they will usually be aligned differently
    813      * within the month than positive values.  For example, if a month has 31
    814      * days, <code>DAY_OF_WEEK_IN_MONTH -1</code> will overlap
    815      * <code>DAY_OF_WEEK_IN_MONTH 5</code> and the end of <code>4</code>.
    816      * @see #DAY_OF_WEEK
    817      * @see #WEEK_OF_MONTH
    818      * @stable ICU 2.0
    819      */
    820     public final static int DAY_OF_WEEK_IN_MONTH = 8;
    821 
    822     /**
    823      * Field number for <code>get</code> and <code>set</code> indicating
    824      * whether the <code>HOUR</code> is before or after noon.
    825      * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>.
    826      * @see #AM
    827      * @see #PM
    828      * @see #HOUR
    829      * @stable ICU 2.0
    830      */
    831     public final static int AM_PM = 9;
    832 
    833     /**
    834      * Field number for <code>get</code> and <code>set</code> indicating the
    835      * hour of the morning or afternoon. <code>HOUR</code> is used for the 12-hour
    836      * clock.
    837      * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10.
    838      * @see #AM_PM
    839      * @see #HOUR_OF_DAY
    840      * @stable ICU 2.0
    841      */
    842     public final static int HOUR = 10;
    843 
    844     /**
    845      * Field number for <code>get</code> and <code>set</code> indicating the
    846      * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock.
    847      * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22.
    848      * @see #HOUR
    849      * @stable ICU 2.0
    850      */
    851     public final static int HOUR_OF_DAY = 11;
    852 
    853     /**
    854      * Field number for <code>get</code> and <code>set</code> indicating the
    855      * minute within the hour.
    856      * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4.
    857      * @stable ICU 2.0
    858      */
    859     public final static int MINUTE = 12;
    860 
    861     /**
    862      * Field number for <code>get</code> and <code>set</code> indicating the
    863      * second within the minute.
    864      * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15.
    865      * @stable ICU 2.0
    866      */
    867     public final static int SECOND = 13;
    868 
    869     /**
    870      * Field number for <code>get</code> and <code>set</code> indicating the
    871      * millisecond within the second.
    872      * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250.
    873      * @stable ICU 2.0
    874      */
    875     public final static int MILLISECOND = 14;
    876 
    877     /**
    878      * Field number for <code>get</code> and <code>set</code> indicating the
    879      * raw offset from GMT in milliseconds.
    880      * @stable ICU 2.0
    881      */
    882     public final static int ZONE_OFFSET = 15;
    883 
    884     /**
    885      * Field number for <code>get</code> and <code>set</code> indicating the
    886      * daylight savings offset in milliseconds.
    887      * @stable ICU 2.0
    888      */
    889     public final static int DST_OFFSET = 16;
    890 
    891     /**
    892      * {@icu} Field number for <code>get()</code> and <code>set()</code>
    893      * indicating the extended year corresponding to the
    894      * {@link #WEEK_OF_YEAR} field.  This may be one greater or less
    895      * than the value of {@link #EXTENDED_YEAR}.
    896      * @stable ICU 2.0
    897      */
    898     public static final int YEAR_WOY = 17;
    899 
    900     /**
    901      * {@icu} Field number for <code>get()</code> and <code>set()</code>
    902      * indicating the localized day of week.  This will be a value from 1
    903      * to 7 inclusive, with 1 being the localized first day of the week.
    904      * @stable ICU 2.0
    905      */
    906     public static final int DOW_LOCAL = 18;
    907 
    908     /**
    909      * {@icu} Field number for <code>get()</code> and <code>set()</code>
    910      * indicating the extended year.  This is a single number designating
    911      * the year of this calendar system, encompassing all supra-year
    912      * fields.  For example, for the Julian calendar system, year numbers
    913      * are positive, with an era of BCE or CE.  An extended year value for
    914      * the Julian calendar system assigns positive values to CE years and
    915      * negative values to BCE years, with 1 BCE being year 0.
    916      * @stable ICU 2.0
    917      */
    918     public static final int EXTENDED_YEAR = 19;
    919 
    920     /**
    921      * {@icu} Field number for <code>get()</code> and <code>set()</code>
    922      * indicating the modified Julian day number.  This is different from
    923      * the conventional Julian day number in two regards.  First, it
    924      * demarcates days at local zone midnight, rather than noon GMT.
    925      * Second, it is a local number; that is, it depends on the local time
    926      * zone.  It can be thought of as a single number that encompasses all
    927      * the date-related fields.
    928      * @stable ICU 2.0
    929      */
    930     public static final int JULIAN_DAY = 20;
    931 
    932     /**
    933      * {@icu} Field number for <code>get()</code> and <code>set()</code>
    934      * indicating the milliseconds in the day.  This ranges from 0 to
    935      * 23:59:59.999 (regardless of DST).  This field behaves
    936      * <em>exactly</em> like a composite of all time-related fields, not
    937      * including the zone fields.  As such, it also reflects
    938      * discontinuities of those fields on DST transition days.  On a day of
    939      * DST onset, it will jump forward.  On a day of DST cessation, it will
    940      * jump backward.  This reflects the fact that is must be combined with
    941      * the DST_OFFSET field to obtain a unique local time value.
    942      * @stable ICU 2.0
    943      */
    944     public static final int MILLISECONDS_IN_DAY = 21;
    945 
    946     /**
    947      * {@icu} Field indicating whether or not the current month is a leap month.
    948      * Should have a value of 0 for non-leap months, and 1 for leap months.
    949      * @stable ICU 4.4
    950      */
    951     public static final int IS_LEAP_MONTH = 22;
    952 
    953     /**
    954      * The number of fields defined by this class.  Subclasses may define
    955      * addition fields starting with this number.
    956      * @stable ICU 2.0
    957      */
    958     protected static final int BASE_FIELD_COUNT = 23;
    959 
    960     /**
    961      * The maximum number of fields possible.  Subclasses must not define
    962      * more total fields than this number.
    963      * @stable ICU 2.0
    964      */
    965     protected static final int MAX_FIELD_COUNT = 32;
    966 
    967     /**
    968      * Value of the <code>DAY_OF_WEEK</code> field indicating
    969      * Sunday.
    970      * @stable ICU 2.0
    971      */
    972     public final static int SUNDAY = 1;
    973 
    974     /**
    975      * Value of the <code>DAY_OF_WEEK</code> field indicating
    976      * Monday.
    977      * @stable ICU 2.0
    978      */
    979     public final static int MONDAY = 2;
    980 
    981     /**
    982      * Value of the <code>DAY_OF_WEEK</code> field indicating
    983      * Tuesday.
    984      * @stable ICU 2.0
    985      */
    986     public final static int TUESDAY = 3;
    987 
    988     /**
    989      * Value of the <code>DAY_OF_WEEK</code> field indicating
    990      * Wednesday.
    991      * @stable ICU 2.0
    992      */
    993     public final static int WEDNESDAY = 4;
    994 
    995     /**
    996      * Value of the <code>DAY_OF_WEEK</code> field indicating
    997      * Thursday.
    998      * @stable ICU 2.0
    999      */
   1000     public final static int THURSDAY = 5;
   1001 
   1002     /**
   1003      * Value of the <code>DAY_OF_WEEK</code> field indicating
   1004      * Friday.
   1005      * @stable ICU 2.0
   1006      */
   1007     public final static int FRIDAY = 6;
   1008 
   1009     /**
   1010      * Value of the <code>DAY_OF_WEEK</code> field indicating
   1011      * Saturday.
   1012      * @stable ICU 2.0
   1013      */
   1014     public final static int SATURDAY = 7;
   1015 
   1016     /**
   1017      * Value of the <code>MONTH</code> field indicating the
   1018      * first month of the year.
   1019      * @stable ICU 2.0
   1020      */
   1021     public final static int JANUARY = 0;
   1022 
   1023     /**
   1024      * Value of the <code>MONTH</code> field indicating the
   1025      * second month of the year.
   1026      * @stable ICU 2.0
   1027      */
   1028     public final static int FEBRUARY = 1;
   1029 
   1030     /**
   1031      * Value of the <code>MONTH</code> field indicating the
   1032      * third month of the year.
   1033      * @stable ICU 2.0
   1034      */
   1035     public final static int MARCH = 2;
   1036 
   1037     /**
   1038      * Value of the <code>MONTH</code> field indicating the
   1039      * fourth month of the year.
   1040      * @stable ICU 2.0
   1041      */
   1042     public final static int APRIL = 3;
   1043 
   1044     /**
   1045      * Value of the <code>MONTH</code> field indicating the
   1046      * fifth month of the year.
   1047      * @stable ICU 2.0
   1048      */
   1049     public final static int MAY = 4;
   1050 
   1051     /**
   1052      * Value of the <code>MONTH</code> field indicating the
   1053      * sixth month of the year.
   1054      * @stable ICU 2.0
   1055      */
   1056     public final static int JUNE = 5;
   1057 
   1058     /**
   1059      * Value of the <code>MONTH</code> field indicating the
   1060      * seventh month of the year.
   1061      * @stable ICU 2.0
   1062      */
   1063     public final static int JULY = 6;
   1064 
   1065     /**
   1066      * Value of the <code>MONTH</code> field indicating the
   1067      * eighth month of the year.
   1068      * @stable ICU 2.0
   1069      */
   1070     public final static int AUGUST = 7;
   1071 
   1072     /**
   1073      * Value of the <code>MONTH</code> field indicating the
   1074      * ninth month of the year.
   1075      * @stable ICU 2.0
   1076      */
   1077     public final static int SEPTEMBER = 8;
   1078 
   1079     /**
   1080      * Value of the <code>MONTH</code> field indicating the
   1081      * tenth month of the year.
   1082      * @stable ICU 2.0
   1083      */
   1084     public final static int OCTOBER = 9;
   1085 
   1086     /**
   1087      * Value of the <code>MONTH</code> field indicating the
   1088      * eleventh month of the year.
   1089      * @stable ICU 2.0
   1090      */
   1091     public final static int NOVEMBER = 10;
   1092 
   1093     /**
   1094      * Value of the <code>MONTH</code> field indicating the
   1095      * twelfth month of the year.
   1096      * @stable ICU 2.0
   1097      */
   1098     public final static int DECEMBER = 11;
   1099 
   1100     /**
   1101      * Value of the <code>MONTH</code> field indicating the
   1102      * thirteenth month of the year. Although {@link GregorianCalendar}
   1103      * does not use this value, lunar calendars do.
   1104      * @stable ICU 2.0
   1105      */
   1106     public final static int UNDECIMBER = 12;
   1107 
   1108     /**
   1109      * Value of the <code>AM_PM</code> field indicating the
   1110      * period of the day from midnight to just before noon.
   1111      * @stable ICU 2.0
   1112      */
   1113     public final static int AM = 0;
   1114 
   1115     /**
   1116      * Value of the <code>AM_PM</code> field indicating the
   1117      * period of the day from noon to just before midnight.
   1118      * @stable ICU 2.0
   1119      */
   1120     public final static int PM = 1;
   1121 
   1122     /**
   1123      * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
   1124      * weekday.
   1125      * @see #WEEKEND
   1126      * @see #WEEKEND_ONSET
   1127      * @see #WEEKEND_CEASE
   1128      * @see #getDayOfWeekType
   1129      * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)}
   1130      */
   1131     @Deprecated
   1132     public static final int WEEKDAY = 0;
   1133 
   1134     /**
   1135      * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
   1136      * weekend day.
   1137      * @see #WEEKDAY
   1138      * @see #WEEKEND_ONSET
   1139      * @see #WEEKEND_CEASE
   1140      * @see #getDayOfWeekType
   1141      * @deprecated  ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)}
   1142      */
   1143     @Deprecated
   1144     public static final int WEEKEND = 1;
   1145 
   1146     /**
   1147      * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
   1148      * day that starts as a weekday and transitions to the weekend.
   1149      * Call getWeekendTransition() to get the point of transition.
   1150      * @see #WEEKDAY
   1151      * @see #WEEKEND
   1152      * @see #WEEKEND_CEASE
   1153      * @see #getDayOfWeekType
   1154      * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)}
   1155      */
   1156     @Deprecated
   1157     public static final int WEEKEND_ONSET = 2;
   1158 
   1159     /**
   1160      * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
   1161      * day that starts as the weekend and transitions to a weekday.
   1162      * Call getWeekendTransition() to get the point of transition.
   1163      * @see #WEEKDAY
   1164      * @see #WEEKEND
   1165      * @see #WEEKEND_ONSET
   1166      * @see #getDayOfWeekType
   1167      * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)}
   1168      */
   1169     @Deprecated
   1170     public static final int WEEKEND_CEASE = 3;
   1171 
   1172     /**
   1173      * {@icu}Option used by {@link #setRepeatedWallTimeOption(int)} and
   1174      * {@link #setSkippedWallTimeOption(int)} specifying an ambiguous wall time
   1175      * to be interpreted as the latest.
   1176      * @see #setRepeatedWallTimeOption(int)
   1177      * @see #getRepeatedWallTimeOption()
   1178      * @see #setSkippedWallTimeOption(int)
   1179      * @see #getSkippedWallTimeOption()
   1180      * @stable ICU 49
   1181      */
   1182     public static final int WALLTIME_LAST = 0;
   1183 
   1184     /**
   1185      * {@icu}Option used by {@link #setRepeatedWallTimeOption(int)} and
   1186      * {@link #setSkippedWallTimeOption(int)} specifying an ambiguous wall time
   1187      * to be interpreted as the earliest.
   1188      * @see #setRepeatedWallTimeOption(int)
   1189      * @see #getRepeatedWallTimeOption()
   1190      * @see #setSkippedWallTimeOption(int)
   1191      * @see #getSkippedWallTimeOption()
   1192      * @stable ICU 49
   1193      */
   1194     public static final int WALLTIME_FIRST = 1;
   1195 
   1196     /**
   1197      * {@icu}Option used by {@link #setSkippedWallTimeOption(int)} specifying an
   1198      * ambiguous wall time to be interpreted as the next valid wall time.
   1199      * @see #setSkippedWallTimeOption(int)
   1200      * @see #getSkippedWallTimeOption()
   1201      * @stable ICU 49
   1202      */
   1203     public static final int WALLTIME_NEXT_VALID = 2;
   1204 
   1205     /**
   1206      * The number of milliseconds in one second.
   1207      * @stable ICU 2.0
   1208      */
   1209     protected static final int  ONE_SECOND = 1000;
   1210 
   1211     /**
   1212      * The number of milliseconds in one minute.
   1213      * @stable ICU 2.0
   1214      */
   1215     protected static final int  ONE_MINUTE = 60*ONE_SECOND;
   1216 
   1217     /**
   1218      * The number of milliseconds in one hour.
   1219      * @stable ICU 2.0
   1220      */
   1221     protected static final int  ONE_HOUR   = 60*ONE_MINUTE;
   1222 
   1223     /**
   1224      * The number of milliseconds in one day.  Although ONE_DAY and
   1225      * ONE_WEEK can fit into ints, they must be longs in order to prevent
   1226      * arithmetic overflow when performing (bug 4173516).
   1227      * @stable ICU 2.0
   1228      */
   1229     protected static final long ONE_DAY    = 24*ONE_HOUR;
   1230 
   1231     /**
   1232      * The number of milliseconds in one week.  Although ONE_DAY and
   1233      * ONE_WEEK can fit into ints, they must be longs in order to prevent
   1234      * arithmetic overflow when performing (bug 4173516).
   1235      * @stable ICU 2.0
   1236      */
   1237     protected static final long ONE_WEEK   = 7*ONE_DAY;
   1238 
   1239     /**
   1240      * The Julian day of the Gregorian epoch, that is, January 1, 1 on the
   1241      * Gregorian calendar.
   1242      * @stable ICU 2.0
   1243      */
   1244     protected static final int JAN_1_1_JULIAN_DAY = 1721426;
   1245 
   1246     /**
   1247      * The Julian day of the epoch, that is, January 1, 1970 on the
   1248      * Gregorian calendar.
   1249      * @stable ICU 2.0
   1250      */
   1251     protected static final int EPOCH_JULIAN_DAY   = 2440588;
   1252 
   1253     /**
   1254      * The minimum supported Julian day.  This value is equivalent to
   1255      * {@link #MIN_MILLIS} and {@link #MIN_DATE}.
   1256      * @see #JULIAN_DAY
   1257      * @stable ICU 2.0
   1258      */
   1259     protected static final int MIN_JULIAN = -0x7F000000;
   1260 
   1261     /**
   1262      * The minimum supported epoch milliseconds.  This value is equivalent
   1263      * to {@link #MIN_JULIAN} and {@link #MIN_DATE}.
   1264      * @stable ICU 2.0
   1265      */
   1266     protected static final long MIN_MILLIS = -184303902528000000L;
   1267 
   1268     // Get around bug in jikes 1.12 for now.  Later, use:
   1269     //protected static final long MIN_MILLIS = (MIN_JULIAN - EPOCH_JULIAN_DAY) * ONE_DAY;
   1270 
   1271     /**
   1272      * The minimum supported <code>Date</code>.  This value is equivalent
   1273      * to {@link #MIN_JULIAN} and {@link #MIN_MILLIS}.
   1274      * @stable ICU 2.0
   1275      */
   1276     protected static final Date MIN_DATE = new Date(MIN_MILLIS);
   1277 
   1278     /**
   1279      * The maximum supported Julian day.  This value is equivalent to
   1280      * {@link #MAX_MILLIS} and {@link #MAX_DATE}.
   1281      * @see #JULIAN_DAY
   1282      * @stable ICU 2.0
   1283      */
   1284     protected static final int MAX_JULIAN = +0x7F000000;
   1285 
   1286     /**
   1287      * The maximum supported epoch milliseconds.  This value is equivalent
   1288      * to {@link #MAX_JULIAN} and {@link #MAX_DATE}.
   1289      * @stable ICU 2.0
   1290      */
   1291     protected static final long MAX_MILLIS = (MAX_JULIAN - EPOCH_JULIAN_DAY) * ONE_DAY;
   1292 
   1293     /**
   1294      * The maximum supported <code>Date</code>.  This value is equivalent
   1295      * to {@link #MAX_JULIAN} and {@link #MAX_MILLIS}.
   1296      * @stable ICU 2.0
   1297      */
   1298     protected static final Date MAX_DATE = new Date(MAX_MILLIS);
   1299 
   1300     // Internal notes:
   1301     // Calendar contains two kinds of time representations: current "time" in
   1302     // milliseconds, and a set of time "fields" representing the current time.
   1303     // The two representations are usually in sync, but can get out of sync
   1304     // as follows.
   1305     // 1. Initially, no fields are set, and the time is invalid.
   1306     // 2. If the time is set, all fields are computed and in sync.
   1307     // 3. If a single field is set, the time is invalid.
   1308     // Recomputation of the time and fields happens when the object needs
   1309     // to return a result to the user, or use a result for a computation.
   1310 
   1311     /**
   1312      * The field values for the currently set time for this calendar.
   1313      * This is an array of at least {@link #BASE_FIELD_COUNT} integers.
   1314      * @see #handleCreateFields
   1315      * @serial
   1316      */
   1317     private transient int           fields[];
   1318 
   1319     /**
   1320      * Pseudo-time-stamps which specify when each field was set. There
   1321      * are two special values, UNSET and INTERNALLY_SET. Values from
   1322      * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values.
   1323      */
   1324     private transient int           stamp[];
   1325 
   1326     /**
   1327      * The currently set time for this calendar, expressed in milliseconds after
   1328      * January 1, 1970, 0:00:00 GMT.
   1329      * @serial
   1330      */
   1331     private long          time;
   1332 
   1333     /**
   1334      * True if then the value of <code>time</code> is valid.
   1335      * The time is made invalid by a change to an item of <code>field[]</code>.
   1336      * @see #time
   1337      * @serial
   1338      */
   1339     private transient boolean       isTimeSet;
   1340 
   1341     /**
   1342      * True if <code>fields[]</code> are in sync with the currently set time.
   1343      * If false, then the next attempt to get the value of a field will
   1344      * force a recomputation of all fields from the current value of
   1345      * <code>time</code>.
   1346      * @serial
   1347      */
   1348     private transient boolean       areFieldsSet;
   1349 
   1350     /**
   1351      * True if all fields have been set.  This is only false in a few
   1352      * situations: In a newly created, partially constructed object.  After
   1353      * a call to clear().  In an object just read from a stream using
   1354      * readObject().  Once computeFields() has been called this is set to
   1355      * true and stays true until one of the above situations recurs.
   1356      * @serial
   1357      */
   1358     private transient boolean       areAllFieldsSet;
   1359 
   1360     /**
   1361      * True if all fields have been virtually set, but have not yet been
   1362      * computed.  This occurs only in setTimeInMillis(), or after readObject().
   1363      * A calendar set to this state will compute all fields from the time if it
   1364      * becomes necessary, but otherwise will delay such computation.
   1365      */
   1366     private transient boolean areFieldsVirtuallySet;
   1367 
   1368     /**
   1369      * True if this calendar allows out-of-range field values during computation
   1370      * of <code>time</code> from <code>fields[]</code>.
   1371      * @see #setLenient
   1372      * @serial
   1373      */
   1374     private boolean         lenient = true;
   1375 
   1376     /**
   1377      * The {@link TimeZone} used by this calendar. {@link Calendar}
   1378      * uses the time zone data to translate between local and GMT time.
   1379      * @serial
   1380      */
   1381     private TimeZone        zone;
   1382 
   1383     /**
   1384      * The first day of the week, with possible values {@link #SUNDAY},
   1385      * {@link #MONDAY}, etc.  This is a locale-dependent value.
   1386      * @serial
   1387      */
   1388     private int             firstDayOfWeek;
   1389 
   1390     /**
   1391      * The number of days required for the first week in a month or year,
   1392      * with possible values from 1 to 7.  This is a locale-dependent value.
   1393      * @serial
   1394      */
   1395     private int             minimalDaysInFirstWeek;
   1396 
   1397     /**
   1398      * First day of the weekend in this calendar's locale.  Must be in
   1399      * the range SUNDAY...SATURDAY (1..7).  The weekend starts at
   1400      * weekendOnsetMillis milliseconds after midnight on that day of
   1401      * the week.  This value is taken from locale resource data.
   1402      */
   1403     private int weekendOnset;
   1404 
   1405     /**
   1406      * Milliseconds after midnight at which the weekend starts on the
   1407      * day of the week weekendOnset.  Times that are greater than or
   1408      * equal to weekendOnsetMillis are considered part of the weekend.
   1409      * Must be in the range 0..24*60*60*1000-1.  This value is taken
   1410      * from locale resource data.
   1411      */
   1412     private int weekendOnsetMillis;
   1413 
   1414     /**
   1415      * Day of the week when the weekend stops in this calendar's
   1416      * locale.  Must be in the range SUNDAY...SATURDAY (1..7).  The
   1417      * weekend stops at weekendCeaseMillis milliseconds after midnight
   1418      * on that day of the week.  This value is taken from locale
   1419      * resource data.
   1420      */
   1421     private int weekendCease;
   1422 
   1423     /**
   1424      * Milliseconds after midnight at which the weekend stops on the
   1425      * day of the week weekendCease.  Times that are greater than or
   1426      * equal to weekendCeaseMillis are considered not to be the
   1427      * weekend.  Must be in the range 0..24*60*60*1000-1.  This value
   1428      * is taken from locale resource data.
   1429      */
   1430     private int weekendCeaseMillis;
   1431 
   1432     /**
   1433      * Option used when the specified wall time occurs multiple times.
   1434      */
   1435     private int repeatedWallTime = WALLTIME_LAST;
   1436 
   1437     /**
   1438      * Option used when the specified wall time does not exist.
   1439      */
   1440     private int skippedWallTime = WALLTIME_LAST;
   1441 
   1442     /**
   1443      * Value of the time stamp <code>stamp[]</code> indicating that
   1444      * a field has not been set since the last call to <code>clear()</code>.
   1445      * @see #INTERNALLY_SET
   1446      * @see #MINIMUM_USER_STAMP
   1447      * @stable ICU 2.0
   1448      */
   1449     protected static final int UNSET = 0;
   1450 
   1451     /**
   1452      * Value of the time stamp <code>stamp[]</code> indicating that a field
   1453      * has been set via computations from the time or from other fields.
   1454      * @see #UNSET
   1455      * @see #MINIMUM_USER_STAMP
   1456      * @stable ICU 2.0
   1457      */
   1458     protected static final int INTERNALLY_SET = 1;
   1459 
   1460     /**
   1461      * If the time stamp <code>stamp[]</code> has a value greater than or
   1462      * equal to <code>MINIMUM_USER_SET</code> then it has been set by the
   1463      * user via a call to <code>set()</code>.
   1464      * @see #UNSET
   1465      * @see #INTERNALLY_SET
   1466      * @stable ICU 2.0
   1467      */
   1468     protected static final int MINIMUM_USER_STAMP = 2;
   1469 
   1470     /**
   1471      * The next available value for <code>stamp[]</code>, an internal array.
   1472      * @serial
   1473      */
   1474     private transient int             nextStamp = MINIMUM_USER_STAMP;
   1475 
   1476     /* Max value for stamp allowable before recalcution */
   1477     private static int STAMP_MAX = 10000;
   1478 
   1479     // the internal serial version which says which version was written
   1480     // - 0 (default) for version up to JDK 1.1.5
   1481     // - 1 for version from JDK 1.1.6, which writes a correct 'time' value
   1482     //     as well as compatible values for other fields.  This is a
   1483     //     transitional format.
   1484     // - 2 (not implemented yet) a future version, in which fields[],
   1485     //     areFieldsSet, and isTimeSet become transient, and isSet[] is
   1486     //     removed. In JDK 1.1.6 we write a format compatible with version 2.
   1487     // static final int        currentSerialVersion = 1;
   1488 
   1489     /**
   1490      * The version of the serialized data on the stream.  Possible values:
   1491      * <dl>
   1492      * <dt><b>0</b> or not present on stream</dt>
   1493      * <dd>
   1494      * JDK 1.1.5 or earlier.
   1495      * </dd>
   1496      * <dt><b>1</b></dt>
   1497      * <dd>
   1498      * JDK 1.1.6 or later.  Writes a correct 'time' value
   1499      * as well as compatible values for other fields.  This is a
   1500      * transitional format.
   1501      * </dd>
   1502      * </dl>
   1503      * When streaming out this class, the most recent format
   1504      * and the highest allowable <code>serialVersionOnStream</code>
   1505      * is written.
   1506      * @serial
   1507      * @since JDK1.1.6
   1508      */
   1509     // private int             serialVersionOnStream = currentSerialVersion;
   1510 
   1511     // Proclaim serialization compatibility with JDK 1.1
   1512     // static final long       serialVersionUID = -1807547505821590642L;
   1513 
   1514     // haven't been compatible for awhile, no longer try
   1515     // jdk1.4.2 serialver
   1516     private static final long serialVersionUID = 6222646104888790989L;
   1517 
   1518     /**
   1519      * Bitmask for internalSet() defining which fields may legally be set
   1520      * by subclasses.  Any attempt to set a field not in this bitmask
   1521      * results in an exception, because such fields must be set by the base
   1522      * class.
   1523      */
   1524     private transient int internalSetMask;
   1525 
   1526     /**
   1527      * The Gregorian year, as computed by computeGregorianFields() and
   1528      * returned by getGregorianYear().
   1529      */
   1530     private transient int gregorianYear;
   1531 
   1532     /**
   1533      * The Gregorian month, as computed by computeGregorianFields() and
   1534      * returned by getGregorianMonth().
   1535      */
   1536     private transient int gregorianMonth;
   1537 
   1538     /**
   1539      * The Gregorian day of the year, as computed by
   1540      * computeGregorianFields() and returned by getGregorianDayOfYear().
   1541      */
   1542     private transient int gregorianDayOfYear;
   1543 
   1544     /**
   1545      * The Gregorian day of the month, as computed by
   1546      * computeGregorianFields() and returned by getGregorianDayOfMonth().
   1547      */
   1548     private transient int gregorianDayOfMonth;
   1549 
   1550     /**
   1551      * Constructs a Calendar with the default time zone
   1552      * and the default <code>FORMAT</code> locale.
   1553      * @see     TimeZone#getDefault
   1554      * @see Category#FORMAT
   1555      * @stable ICU 2.0
   1556      */
   1557     protected Calendar()
   1558     {
   1559         this(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
   1560     }
   1561 
   1562     /**
   1563      * Constructs a calendar with the specified time zone and locale.
   1564      * @param zone the time zone to use
   1565      * @param aLocale the locale for the week data
   1566      * @stable ICU 2.0
   1567      */
   1568     protected Calendar(TimeZone zone, Locale aLocale)
   1569     {
   1570         this(zone, ULocale.forLocale(aLocale));
   1571     }
   1572 
   1573     /**
   1574      * Constructs a calendar with the specified time zone and locale.
   1575      * @param zone the time zone to use
   1576      * @param locale the ulocale for the week data
   1577      * @stable ICU 3.2
   1578      */
   1579     protected Calendar(TimeZone zone, ULocale locale)
   1580     {
   1581         this.zone = zone;
   1582 
   1583         // week data
   1584         setWeekData(getRegionForCalendar(locale));
   1585 
   1586         // set valid/actual locale
   1587         setCalendarLocale(locale);
   1588 
   1589         initInternal();
   1590     }
   1591 
   1592     /*
   1593      * Set valid/actual locale to this calendar during initialization.
   1594      *
   1595      * Valid or actual locale does not make much sense for Calendar
   1596      * object. An instance of Calendar is initialized by week data
   1597      * determine by region and calendar type (either region or keyword).
   1598      * Language is not really used for calendar creation.
   1599      */
   1600     private void setCalendarLocale(ULocale locale) {
   1601         ULocale calLocale = locale;
   1602 
   1603         if (locale.getVariant().length() != 0 || locale.getKeywords() != null) {
   1604             // Construct a ULocale, without variant and keywords (except calendar).
   1605             StringBuilder buf = new StringBuilder();
   1606 
   1607             buf.append(locale.getLanguage());
   1608 
   1609             String script = locale.getScript();
   1610             if (script.length() > 0) {
   1611                 buf.append("_").append(script);
   1612             }
   1613 
   1614             String region = locale.getCountry();
   1615             if (region.length() > 0) {
   1616                 buf.append("_").append(region);
   1617             }
   1618 
   1619             String calType = locale.getKeywordValue("calendar");
   1620             if (calType != null) {
   1621                 buf.append("@calendar=").append(calType);
   1622             }
   1623 
   1624             calLocale = new ULocale(buf.toString());
   1625         }
   1626 
   1627         setLocale(calLocale, calLocale);
   1628     }
   1629 
   1630     private void recalculateStamp() {
   1631         int index;
   1632         int currentValue;
   1633         int j, i;
   1634 
   1635         nextStamp = 1;
   1636 
   1637         for (j = 0; j < stamp.length; j++) {
   1638             currentValue = STAMP_MAX;
   1639             index = -1;
   1640 
   1641             for (i = 0; i < stamp.length; i++) {
   1642                 if (stamp[i] > nextStamp && stamp[i] < currentValue) {
   1643                     currentValue = stamp[i];
   1644                     index = i;
   1645                 }
   1646             }
   1647 
   1648             if (index >= 0) {
   1649                 stamp[index] = ++nextStamp;
   1650             } else {
   1651                 break;
   1652             }
   1653         }
   1654         nextStamp++;
   1655     }
   1656 
   1657     private void initInternal()
   1658     {
   1659         // Allocate fields through the framework method.  Subclasses
   1660         // may override this to define additional fields.
   1661         fields = handleCreateFields();
   1662         ///CLOVER:OFF
   1663         // todo: fix, difficult to test without subclassing
   1664         if (fields == null || fields.length < BASE_FIELD_COUNT ||
   1665                 fields.length > MAX_FIELD_COUNT) {
   1666             throw new IllegalStateException("Invalid fields[]");
   1667         }
   1668         ///CLOVER:ON
   1669         stamp = new int[fields.length];
   1670         int mask = (1 << ERA) |
   1671                 (1 << YEAR) |
   1672                 (1 << MONTH) |
   1673                 (1 << DAY_OF_MONTH) |
   1674                 (1 << DAY_OF_YEAR) |
   1675                 (1 << EXTENDED_YEAR) |
   1676                 (1 << IS_LEAP_MONTH);
   1677         for (int i=BASE_FIELD_COUNT; i<fields.length; ++i) {
   1678             mask |= (1 << i);
   1679         }
   1680         internalSetMask = mask;
   1681     }
   1682 
   1683     /**
   1684      * Returns a calendar using the default time zone and locale.
   1685      * @return a Calendar.
   1686      * @stable ICU 2.0
   1687      */
   1688     public static Calendar getInstance()
   1689     {
   1690         return getInstanceInternal(null, null);
   1691     }
   1692 
   1693     /**
   1694      * Returns a calendar using the specified time zone and default locale.
   1695      * @param zone the time zone to use
   1696      * @return a Calendar.
   1697      * @stable ICU 2.0
   1698      */
   1699     public static Calendar getInstance(TimeZone zone)
   1700     {
   1701         return getInstanceInternal(zone, null);
   1702     }
   1703 
   1704     /**
   1705      * Returns a calendar using the default time zone and specified locale.
   1706      * @param aLocale the locale for the week data
   1707      * @return a Calendar.
   1708      * @stable ICU 2.0
   1709      */
   1710     public static Calendar getInstance(Locale aLocale)
   1711     {
   1712         return getInstanceInternal(null, ULocale.forLocale(aLocale));
   1713     }
   1714 
   1715     /**
   1716      * Returns a calendar using the default time zone and specified locale.
   1717      * @param locale the ulocale for the week data
   1718      * @return a Calendar.
   1719      * @stable ICU 3.2
   1720      */
   1721     public static Calendar getInstance(ULocale locale)
   1722     {
   1723         return getInstanceInternal(null, locale);
   1724     }
   1725 
   1726     /**
   1727      * Returns a calendar with the specified time zone and locale.
   1728      * @param zone the time zone to use
   1729      * @param aLocale the locale for the week data
   1730      * @return a Calendar.
   1731      * @stable ICU 2.0
   1732      */
   1733     public static Calendar getInstance(TimeZone zone, Locale aLocale) {
   1734         return getInstanceInternal(zone, ULocale.forLocale(aLocale));
   1735     }
   1736 
   1737     /**
   1738      * Returns a calendar with the specified time zone and locale.
   1739      * @param zone the time zone to use
   1740      * @param locale the ulocale for the week data
   1741      * @return a Calendar.
   1742      * @stable ICU 3.2
   1743      */
   1744     public static Calendar getInstance(TimeZone zone, ULocale locale) {
   1745         return getInstanceInternal(zone, locale);
   1746     }
   1747 
   1748     /*
   1749      * All getInstance implementations call this private method to create a new
   1750      * Calendar instance.
   1751      */
   1752     private static Calendar getInstanceInternal(TimeZone tz, ULocale locale) {
   1753         if (locale == null) {
   1754             locale = ULocale.getDefault(Category.FORMAT);
   1755         }
   1756         if (tz == null) {
   1757             tz = TimeZone.getDefault();
   1758         }
   1759 
   1760         Calendar cal = createInstance(locale);
   1761         cal.setTimeZone(tz);
   1762         cal.setTimeInMillis(System.currentTimeMillis());
   1763         return cal;
   1764     }
   1765 
   1766     private static String getRegionForCalendar(ULocale loc) {
   1767         String region = loc.getCountry();
   1768         if (region.length() == 0) {
   1769             ULocale maxLocale = ULocale.addLikelySubtags(loc);
   1770             region = maxLocale.getCountry();
   1771             if (region.length() == 0) {
   1772                 region = "001";
   1773             }
   1774         }
   1775         return region;
   1776     }
   1777 
   1778     private enum CalType {
   1779         GREGORIAN("gregorian"),
   1780         ISO8601("iso8601"),
   1781 
   1782         BUDDHIST("buddhist"),
   1783         CHINESE("chinese"),
   1784         COPTIC("coptic"),
   1785         DANGI("dangi"),
   1786         ETHIOPIC("ethiopic"),
   1787         ETHIOPIC_AMETE_ALEM("ethiopic-amete-alem"),
   1788         HEBREW("hebrew"),
   1789         INDIAN("indian"),
   1790         ISLAMIC("islamic"),
   1791         ISLAMIC_CIVIL("islamic-civil"),
   1792         ISLAMIC_RGSA("islamic-rgsa"),
   1793         ISLAMIC_TBLA("islamic-tbla"),
   1794         ISLAMIC_UMALQURA("islamic-umalqura"),
   1795         JAPANESE("japanese"),
   1796         PERSIAN("persian"),
   1797         ROC("roc"),
   1798 
   1799         UNKNOWN("unknown");
   1800 
   1801         String id;
   1802 
   1803         CalType(String id) {
   1804             this.id = id;
   1805         }
   1806     }
   1807 
   1808     private static CalType getCalendarTypeForLocale(ULocale l) {
   1809         String s = CalendarUtil.getCalendarType(l);
   1810         if (s != null) {
   1811             s = s.toLowerCase(Locale.ENGLISH);
   1812             for (CalType type : CalType.values()) {
   1813                 if (s.equals(type.id)) {
   1814                     return type;
   1815                 }
   1816             }
   1817         }
   1818         return CalType.UNKNOWN;
   1819     }
   1820 
   1821     private static Calendar createInstance(ULocale locale) {
   1822         Calendar cal = null;
   1823         TimeZone zone = TimeZone.getDefault();
   1824         CalType calType = getCalendarTypeForLocale(locale);
   1825         if (calType == CalType.UNKNOWN) {
   1826             // fallback to Gregorian
   1827             calType = CalType.GREGORIAN;
   1828         }
   1829 
   1830         switch (calType) {
   1831         case GREGORIAN:
   1832             cal = new GregorianCalendar(zone, locale);
   1833             break;
   1834         case ISO8601:
   1835             // Only differs week numbering rule from Gregorian
   1836             cal = new GregorianCalendar(zone, locale);
   1837             cal.setFirstDayOfWeek(MONDAY);
   1838             cal.setMinimalDaysInFirstWeek(4);
   1839             break;
   1840 
   1841         case BUDDHIST:
   1842             cal = new BuddhistCalendar(zone, locale);
   1843             break;
   1844         case CHINESE:
   1845             cal = new ChineseCalendar(zone, locale);
   1846             break;
   1847         case COPTIC:
   1848             cal = new CopticCalendar(zone, locale);
   1849             break;
   1850         case DANGI:
   1851             cal = new DangiCalendar(zone, locale);
   1852             break;
   1853         case ETHIOPIC:
   1854             cal = new EthiopicCalendar(zone, locale);
   1855             break;
   1856         case ETHIOPIC_AMETE_ALEM:
   1857             cal = new EthiopicCalendar(zone, locale);
   1858             ((EthiopicCalendar)cal).setAmeteAlemEra(true);
   1859             break;
   1860         case HEBREW:
   1861             cal = new HebrewCalendar(zone, locale);
   1862             break;
   1863         case INDIAN:
   1864             cal = new IndianCalendar(zone, locale);
   1865             break;
   1866         case ISLAMIC_CIVIL:
   1867         case ISLAMIC_UMALQURA :
   1868         case ISLAMIC_TBLA:
   1869         case ISLAMIC_RGSA:
   1870         case ISLAMIC:
   1871             cal = new IslamicCalendar(zone, locale);
   1872             break;
   1873         case JAPANESE:
   1874             cal = new JapaneseCalendar(zone, locale);
   1875             break;
   1876         case PERSIAN:
   1877             cal = new PersianCalendar(zone, locale);
   1878             break;
   1879         case ROC:
   1880             cal = new TaiwanCalendar(zone, locale);
   1881             break;
   1882 
   1883         default:
   1884             // we must not get here, because unknown type is mapped to
   1885             // Gregorian at the beginning of this method.
   1886             throw new IllegalArgumentException("Unknown calendar type");
   1887         }
   1888 
   1889         return cal;
   1890     }
   1891 
   1892     /**
   1893      * Returns the list of locales for which Calendars are installed.
   1894      * @return the list of locales for which Calendars are installed.
   1895      * @stable ICU 2.0
   1896      */
   1897     public static Locale[] getAvailableLocales()
   1898     {
   1899         // TODO
   1900         return ICUResourceBundle.getAvailableLocales();
   1901     }
   1902 
   1903     /**
   1904      * {@icu} Returns the list of locales for which Calendars are installed.
   1905      * @return the list of locales for which Calendars are installed.
   1906      * @draft ICU 3.2 (retain)
   1907      * @provisional This API might change or be removed in a future release.
   1908      */
   1909     public static ULocale[] getAvailableULocales()
   1910     {
   1911         // TODO
   1912         return ICUResourceBundle.getAvailableULocales();
   1913     }
   1914 
   1915     /**
   1916      * {@icu} Given a key and a locale, returns an array of string values in a preferred
   1917      * order that would make a difference. These are all and only those values where
   1918      * the open (creation) of the service with the locale formed from the input locale
   1919      * plus input keyword and that value has different behavior than creation with the
   1920      * input locale alone.
   1921      * @param key           one of the keys supported by this service.  For now, only
   1922      *                      "calendar" is supported.
   1923      * @param locale        the locale
   1924      * @param commonlyUsed  if set to true it will return only commonly used values
   1925      *                      with the given locale in preferred order.  Otherwise,
   1926      *                      it will return all the available values for the locale.
   1927      * @return an array of string values for the given key and the locale.
   1928      * @stable ICU 4.2
   1929      */
   1930     public static final String[] getKeywordValuesForLocale(String key, ULocale locale,
   1931             boolean commonlyUsed) {
   1932         // Resolve region
   1933         String prefRegion = locale.getCountry();
   1934         if (prefRegion.length() == 0){
   1935             ULocale loc = ULocale.addLikelySubtags(locale);
   1936             prefRegion = loc.getCountry();
   1937         }
   1938 
   1939         // Read preferred calendar values from supplementalData calendarPreferences
   1940         ArrayList<String> values = new ArrayList<String>();
   1941 
   1942         UResourceBundle rb = UResourceBundle.getBundleInstance(
   1943                 ICUResourceBundle.ICU_BASE_NAME,
   1944                 "supplementalData",
   1945                 ICUResourceBundle.ICU_DATA_CLASS_LOADER);
   1946         UResourceBundle calPref = rb.get("calendarPreferenceData");
   1947         UResourceBundle order = null;
   1948         try {
   1949             order = calPref.get(prefRegion);
   1950         } catch (MissingResourceException mre) {
   1951             // use "001" as fallback
   1952             order = calPref.get("001");
   1953         }
   1954 
   1955         String[] caltypes = order.getStringArray();
   1956         if (commonlyUsed) {
   1957             // we have all commonly used calendar for the target region
   1958             return caltypes;
   1959         }
   1960 
   1961         // if not commonlyUsed, add all preferred calendars in the order
   1962         for (int i = 0; i < caltypes.length; i++) {
   1963             values.add(caltypes[i]);
   1964         }
   1965         // then, add other available clanedars
   1966         for (CalType t : CalType.values()) {
   1967             if (!values.contains(t.id)) {
   1968                 values.add(t.id);
   1969             }
   1970         }
   1971         return values.toArray(new String[values.size()]);
   1972     }
   1973 
   1974     /**
   1975      * Returns this Calendar's current time.
   1976      * @return the current time.
   1977      * @stable ICU 2.0
   1978      */
   1979     public final Date getTime() {
   1980         return new Date( getTimeInMillis() );
   1981     }
   1982 
   1983     /**
   1984      * Sets this Calendar's current time with the given Date.
   1985      *
   1986      * <p>Note: Calling <code>setTime</code> with
   1987      * <code>Date(Long.MAX_VALUE)</code> or <code>Date(Long.MIN_VALUE)</code>
   1988      * may yield incorrect field values from {@link #get(int)}.
   1989      * @param date the given Date.
   1990      * @stable ICU 2.0
   1991      */
   1992     public final void setTime(Date date) {
   1993         setTimeInMillis( date.getTime() );
   1994     }
   1995 
   1996     /**
   1997      * Returns this Calendar's current time as a long.
   1998      * @return the current time as UTC milliseconds from the epoch.
   1999      * @stable ICU 2.0
   2000      */
   2001     public long getTimeInMillis() {
   2002         if (!isTimeSet) updateTime();
   2003         return time;
   2004     }
   2005 
   2006     /**
   2007      * Sets this Calendar's current time from the given long value.
   2008      * An IllegalIcuArgumentException is thrown when millis is outside the range permitted
   2009      * by a Calendar object when in strict mode.
   2010      * When in lenient mode the out of range values are pinned to their respective min/max.
   2011      * @param millis the new time in UTC milliseconds from the epoch.
   2012      * @stable ICU 2.0
   2013      */
   2014     public void setTimeInMillis( long millis ) {
   2015         if (millis > MAX_MILLIS) {
   2016             if(isLenient()) {
   2017                 millis = MAX_MILLIS;
   2018             } else {
   2019                 throw new IllegalArgumentException("millis value greater than upper bounds for a Calendar : " + millis);
   2020             }
   2021         } else if (millis < MIN_MILLIS) {
   2022             if(isLenient()) {
   2023                 millis = MIN_MILLIS;
   2024             } else {
   2025                 throw new IllegalArgumentException("millis value less than lower bounds for a Calendar : " + millis);
   2026             }
   2027         }
   2028         time = millis;
   2029         areFieldsSet = areAllFieldsSet = false;
   2030         isTimeSet = areFieldsVirtuallySet = true;
   2031 
   2032         for (int i=0; i<fields.length; ++i) {
   2033             fields[i] = stamp[i] = 0; // UNSET == 0
   2034         }
   2035 
   2036     }
   2037 
   2038     /**
   2039      * Returns the value for a given time field.
   2040      * @param field the given time field.
   2041      * @return the value for the given time field.
   2042      * @stable ICU 2.0
   2043      */
   2044     public final int get(int field)
   2045     {
   2046         complete();
   2047         return fields[field];
   2048     }
   2049 
   2050     /**
   2051      * Returns the value for a given time field.  This is an internal method
   2052      * for subclasses that does <em>not</em> trigger any calculations.
   2053      * @param field the given time field.
   2054      * @return the value for the given time field.
   2055      * @stable ICU 2.0
   2056      */
   2057     protected final int internalGet(int field)
   2058     {
   2059         return fields[field];
   2060     }
   2061 
   2062     /**
   2063      * Returns the value for a given time field, or return the given default
   2064      * value if the field is not set.  This is an internal method for
   2065      * subclasses that does <em>not</em> trigger any calculations.
   2066      * @param field the given time field.
   2067      * @param defaultValue value to return if field is not set
   2068      * @return the value for the given time field of defaultValue if the
   2069      * field is unset
   2070      * @stable ICU 2.0
   2071      */
   2072     protected final int internalGet(int field, int defaultValue) {
   2073         return (stamp[field] > UNSET) ? fields[field] : defaultValue;
   2074     }
   2075 
   2076     /**
   2077      * Sets the time field with the given value.
   2078      * @param field the given time field.
   2079      * @param value the value to be set for the given time field.
   2080      * @stable ICU 2.0
   2081      */
   2082     public final void set(int field, int value)
   2083     {
   2084         if (areFieldsVirtuallySet) {
   2085             computeFields();
   2086         }
   2087         fields[field] = value;
   2088         /* Ensure that the fNextStamp value doesn't go pass max value for 32 bit integer */
   2089         if (nextStamp == STAMP_MAX) {
   2090             recalculateStamp();
   2091         }
   2092         stamp[field] = nextStamp++;
   2093         isTimeSet = areFieldsSet = areFieldsVirtuallySet = false;
   2094     }
   2095 
   2096     /**
   2097      * Sets the values for the fields year, month, and date.
   2098      * Previous values of other fields are retained.  If this is not desired,
   2099      * call {@link #clear()} first.
   2100      * @param year the value used to set the YEAR time field.
   2101      * @param month the value used to set the MONTH time field.
   2102      * Month value is 0-based. e.g., 0 for January.
   2103      * @param date the value used to set the DATE time field.
   2104      * @stable ICU 2.0
   2105      */
   2106     public final void set(int year, int month, int date)
   2107     {
   2108         set(YEAR, year);
   2109         set(MONTH, month);
   2110         set(DATE, date);
   2111     }
   2112 
   2113     /**
   2114      * Sets the values for the fields year, month, date, hour, and minute.
   2115      * Previous values of other fields are retained.  If this is not desired,
   2116      * call {@link #clear()} first.
   2117      * @param year the value used to set the YEAR time field.
   2118      * @param month the value used to set the MONTH time field.
   2119      * Month value is 0-based. e.g., 0 for January.
   2120      * @param date the value used to set the DATE time field.
   2121      * @param hour the value used to set the HOUR_OF_DAY time field.
   2122      * @param minute the value used to set the MINUTE time field.
   2123      * @stable ICU 2.0
   2124      */
   2125     public final void set(int year, int month, int date, int hour, int minute)
   2126     {
   2127         set(YEAR, year);
   2128         set(MONTH, month);
   2129         set(DATE, date);
   2130         set(HOUR_OF_DAY, hour);
   2131         set(MINUTE, minute);
   2132     }
   2133 
   2134     /**
   2135      * Sets the values for the fields year, month, date, hour, minute, and second.
   2136      * Previous values of other fields are retained.  If this is not desired,
   2137      * call {@link #clear} first.
   2138      * @param year the value used to set the YEAR time field.
   2139      * @param month the value used to set the MONTH time field.
   2140      * Month value is 0-based. e.g., 0 for January.
   2141      * @param date the value used to set the DATE time field.
   2142      * @param hour the value used to set the HOUR_OF_DAY time field.
   2143      * @param minute the value used to set the MINUTE time field.
   2144      * @param second the value used to set the SECOND time field.
   2145      * @stable ICU 2.0
   2146      */
   2147     public final void set(int year, int month, int date, int hour, int minute,
   2148             int second)
   2149     {
   2150         set(YEAR, year);
   2151         set(MONTH, month);
   2152         set(DATE, date);
   2153         set(HOUR_OF_DAY, hour);
   2154         set(MINUTE, minute);
   2155         set(SECOND, second);
   2156     }
   2157 
   2158     // -------------------------------------
   2159     // For now the full getRelatedYear implementation is here;
   2160     // per #10752 move the non-default implementation to subclasses
   2161     // (default implementation will do no year adjustment)
   2162 
   2163     /**
   2164      * utility function for getRelatedYear
   2165      */
   2166     private static int gregoYearFromIslamicStart(int year) {
   2167         // ad hoc conversion, improve under #10752
   2168         // rough est for now, ok for grego 1846-2138,
   2169         // otherwise occasionally wrong (for 3% of years)
   2170         int cycle, offset, shift = 0;
   2171         if (year >= 1397) {
   2172             cycle = (year - 1397) / 67;
   2173             offset = (year - 1397) % 67;
   2174             shift = 2*cycle + ((offset >= 33)? 1: 0);
   2175         } else {
   2176             cycle = (year - 1396) / 67 - 1;
   2177             offset = -(year - 1396) % 67;
   2178             shift = 2*cycle + ((offset <= 33)? 1: 0);
   2179         }
   2180         return year + 579 - shift;
   2181     }
   2182 
   2183     /**
   2184      * @internal
   2185      * @deprecated This API is ICU internal only.
   2186      */
   2187     @Deprecated
   2188     public final int getRelatedYear() {
   2189         int year = get(EXTENDED_YEAR);
   2190         CalType type = CalType.GREGORIAN;
   2191         String typeString = getType();
   2192         for (CalType testType : CalType.values()) {
   2193             if (typeString.equals(testType.id)) {
   2194                 type = testType;
   2195                 break;
   2196             }
   2197         }
   2198         switch (type) {
   2199             case PERSIAN:
   2200                 year += 622; break;
   2201             case HEBREW:
   2202                 year -= 3760; break;
   2203             case CHINESE:
   2204                 year -= 2637; break;
   2205             case INDIAN:
   2206                 year += 79; break;
   2207             case COPTIC:
   2208                 year += 284; break;
   2209             case ETHIOPIC:
   2210                 year += 8; break;
   2211             case ETHIOPIC_AMETE_ALEM:
   2212                 year -=5492; break;
   2213             case DANGI:
   2214                 year -= 2333; break;
   2215             case ISLAMIC_CIVIL:
   2216             case ISLAMIC:
   2217             case ISLAMIC_UMALQURA:
   2218             case ISLAMIC_TBLA:
   2219             case ISLAMIC_RGSA:
   2220                 year = gregoYearFromIslamicStart(year); break;
   2221             // case GREGORIAN:
   2222             // case JAPANESE:
   2223             // case BUDDHIST:
   2224             // case ROC:
   2225             // case ISO8601:
   2226             default:
   2227                 // do nothing, EXTENDED_YEAR same as Gregorian
   2228                 break;
   2229         }
   2230         return year;
   2231     }
   2232 
   2233     // -------------------------------------
   2234     // For now the full setRelatedYear implementation is here;
   2235     // per #10752 move the non-default implementation to subclasses
   2236     // (default implementation will do no year adjustment)
   2237 
   2238     /**
   2239      * utility function for setRelatedYear
   2240      */
   2241     private static int firstIslamicStartYearFromGrego(int year) {
   2242         // ad hoc conversion, improve under #10752
   2243         // rough est for now, ok for grego 1846-2138,
   2244         // otherwise occasionally wrong (for 3% of years)
   2245         int cycle, offset, shift = 0;
   2246         if (year >= 1977) {
   2247             cycle = (year - 1977) / 65;
   2248             offset = (year - 1977) % 65;
   2249             shift = 2*cycle + ((offset >= 32)? 1: 0);
   2250         } else {
   2251             cycle = (year - 1976) / 65 - 1;
   2252             offset = -(year - 1976) % 65;
   2253             shift = 2*cycle + ((offset <= 32)? 1: 0);
   2254         }
   2255         return year - 579 + shift;
   2256     }
   2257 
   2258     /**
   2259      * @internal
   2260      * @deprecated This API is ICU internal only.
   2261      */
   2262     @Deprecated
   2263     public final void setRelatedYear(int year) {
   2264         CalType type = CalType.GREGORIAN;
   2265         String typeString = getType();
   2266         for (CalType testType : CalType.values()) {
   2267             if (typeString.equals(testType.id)) {
   2268                 type = testType;
   2269                 break;
   2270             }
   2271         }
   2272         switch (type) {
   2273             case PERSIAN:
   2274                 year -= 622; break;
   2275             case HEBREW:
   2276                 year += 3760; break;
   2277             case CHINESE:
   2278                 year += 2637; break;
   2279             case INDIAN:
   2280                 year -= 79; break;
   2281             case COPTIC:
   2282                 year -= 284; break;
   2283             case ETHIOPIC:
   2284                 year -= 8; break;
   2285             case ETHIOPIC_AMETE_ALEM:
   2286                 year +=5492; break;
   2287             case DANGI:
   2288                 year += 2333; break;
   2289             case ISLAMIC_CIVIL:
   2290             case ISLAMIC:
   2291             case ISLAMIC_UMALQURA:
   2292             case ISLAMIC_TBLA:
   2293             case ISLAMIC_RGSA:
   2294                 year = firstIslamicStartYearFromGrego(year); break;
   2295             // case GREGORIAN:
   2296             // case JAPANESE:
   2297             // case BUDDHIST:
   2298             // case ROC:
   2299             // case ISO8601:
   2300             default:
   2301                 // do nothing, EXTENDED_YEAR same as Gregorian
   2302                 break;
   2303         }
   2304         set(EXTENDED_YEAR, year);
   2305     }
   2306 
   2307     /**
   2308      * Clears the values of all the time fields.
   2309      * @stable ICU 2.0
   2310      */
   2311     public final void clear()
   2312     {
   2313         for (int i=0; i<fields.length; ++i) {
   2314             fields[i] = stamp[i] = 0; // UNSET == 0
   2315         }
   2316         isTimeSet = areFieldsSet = areAllFieldsSet = areFieldsVirtuallySet = false;
   2317     }
   2318 
   2319     /**
   2320      * Clears the value in the given time field.
   2321      * @param field the time field to be cleared.
   2322      * @stable ICU 2.0
   2323      */
   2324     public final void clear(int field)
   2325     {
   2326         if (areFieldsVirtuallySet) {
   2327             computeFields();
   2328         }
   2329         fields[field] = 0;
   2330         stamp[field] = UNSET;
   2331         isTimeSet = areFieldsSet = areAllFieldsSet = areFieldsVirtuallySet = false;
   2332     }
   2333 
   2334     /**
   2335      * Determines if the given time field has a value set.
   2336      * @return true if the given time field has a value set; false otherwise.
   2337      * @stable ICU 2.0
   2338      */
   2339     public final boolean isSet(int field)
   2340     {
   2341         return areFieldsVirtuallySet || (stamp[field] != UNSET);
   2342     }
   2343 
   2344     /**
   2345      * Fills in any unset fields in the time field list.
   2346      * @stable ICU 2.0
   2347      */
   2348     protected void complete()
   2349     {
   2350         if (!isTimeSet) updateTime();
   2351         if (!areFieldsSet) {
   2352             computeFields(); // fills in unset fields
   2353             areFieldsSet = true;
   2354             areAllFieldsSet = true;
   2355         }
   2356     }
   2357 
   2358     /**
   2359      * Compares this calendar to the specified object.
   2360      * The result is <code>true</code> if and only if the argument is
   2361      * not <code>null</code> and is a <code>Calendar</code> object that
   2362      * represents the same calendar as this object.
   2363      * @param obj the object to compare with.
   2364      * @return <code>true</code> if the objects are the same;
   2365      * <code>false</code> otherwise.
   2366      * @stable ICU 2.0
   2367      */
   2368     public boolean equals(Object obj) {
   2369         if (obj == null) {
   2370             return false;
   2371         }
   2372         if (this == obj) {
   2373             return true;
   2374         }
   2375         if (this.getClass() != obj.getClass()) {
   2376             return false;
   2377         }
   2378 
   2379         Calendar that = (Calendar) obj;
   2380 
   2381         return isEquivalentTo(that) &&
   2382                 getTimeInMillis() == that.getTime().getTime();
   2383     }
   2384 
   2385     /**
   2386      * {@icu} Returns true if the given Calendar object is equivalent to this
   2387      * one.  An equivalent Calendar will behave exactly as this one
   2388      * does, but it may be set to a different time.  By contrast, for
   2389      * the equals() method to return true, the other Calendar must
   2390      * be set to the same time.
   2391      *
   2392      * @param other the Calendar to be compared with this Calendar
   2393      * @stable ICU 2.4
   2394      */
   2395     public boolean isEquivalentTo(Calendar other) {
   2396         return this.getClass() == other.getClass() &&
   2397                 isLenient() == other.isLenient() &&
   2398                 getFirstDayOfWeek() == other.getFirstDayOfWeek() &&
   2399                 getMinimalDaysInFirstWeek() == other.getMinimalDaysInFirstWeek() &&
   2400                 getTimeZone().equals(other.getTimeZone()) &&
   2401                 getRepeatedWallTimeOption() == other.getRepeatedWallTimeOption() &&
   2402                 getSkippedWallTimeOption() == other.getSkippedWallTimeOption();
   2403     }
   2404 
   2405     /**
   2406      * Returns a hash code for this calendar.
   2407      * @return a hash code value for this object.
   2408      * @stable ICU 2.0
   2409      */
   2410     public int hashCode() {
   2411         /* Don't include the time because (a) we don't want the hash value to
   2412          * move around just because a calendar is set to different times, and
   2413          * (b) we don't want to trigger a time computation just to get a hash.
   2414          * Note that it is not necessary for unequal objects to always have
   2415          * unequal hashes, but equal objects must have equal hashes.  */
   2416         return (lenient ? 1 : 0)
   2417                 | (firstDayOfWeek << 1)
   2418                 | (minimalDaysInFirstWeek << 4)
   2419                 | (repeatedWallTime << 7)
   2420                 | (skippedWallTime << 9)
   2421                 | (zone.hashCode() << 11);
   2422     }
   2423 
   2424     /**
   2425      * Returns the difference in milliseconds between the moment this
   2426      * calendar is set to and the moment the given calendar or Date object
   2427      * is set to.
   2428      */
   2429     private long compare(Object that) {
   2430         long thatMs;
   2431         if (that instanceof Calendar) {
   2432             thatMs = ((Calendar)that).getTimeInMillis();
   2433         } else if (that instanceof Date) {
   2434             thatMs = ((Date)that).getTime();
   2435         } else {
   2436             throw new IllegalArgumentException(that + "is not a Calendar or Date");
   2437         }
   2438         return getTimeInMillis() - thatMs;
   2439     }
   2440 
   2441     /**
   2442      * Compares the time field records.
   2443      * Equivalent to comparing result of conversion to UTC.
   2444      * @param when the Calendar to be compared with this Calendar.
   2445      * @return true if the current time of this Calendar is before
   2446      * the time of Calendar when; false otherwise.
   2447      * @stable ICU 2.0
   2448      */
   2449     public boolean before(Object when) {
   2450         return compare(when) < 0;
   2451     }
   2452 
   2453     /**
   2454      * Compares the time field records.
   2455      * Equivalent to comparing result of conversion to UTC.
   2456      * @param when the Calendar to be compared with this Calendar.
   2457      * @return true if the current time of this Calendar is after
   2458      * the time of Calendar when; false otherwise.
   2459      * @stable ICU 2.0
   2460      */
   2461     public boolean after(Object when) {
   2462         return compare(when) > 0;
   2463     }
   2464 
   2465     /**
   2466      * Returns the maximum value that this field could have, given the
   2467      * current date.  For example, with the Gregorian date February 3, 1997
   2468      * and the {@link #DAY_OF_MONTH DAY_OF_MONTH} field, the actual maximum
   2469      * is 28; for February 3, 1996 it is 29.
   2470      *
   2471      * <p>The actual maximum computation ignores smaller fields and the
   2472      * current value of like-sized fields.  For example, the actual maximum
   2473      * of the DAY_OF_YEAR or MONTH depends only on the year and supra-year
   2474      * fields.  The actual maximum of the DAY_OF_MONTH depends, in
   2475      * addition, on the MONTH field and any other fields at that
   2476      * granularity (such as IS_LEAP_MONTH).  The
   2477      * DAY_OF_WEEK_IN_MONTH field does not depend on the current
   2478      * DAY_OF_WEEK; it returns the maximum for any day of week in the
   2479      * current month.  Likewise for the WEEK_OF_MONTH and WEEK_OF_YEAR
   2480      * fields.
   2481      *
   2482      * @param field the field whose maximum is desired
   2483      * @return the maximum of the given field for the current date of this calendar
   2484      * @see #getMaximum
   2485      * @see #getLeastMaximum
   2486      * @stable ICU 2.0
   2487      */
   2488     public int getActualMaximum(int field) {
   2489         int result;
   2490 
   2491         switch (field) {
   2492         case DAY_OF_MONTH:
   2493         {
   2494             Calendar cal = (Calendar) clone();
   2495             cal.setLenient(true);
   2496             cal.prepareGetActual(field, false);
   2497             result = handleGetMonthLength(cal.get(EXTENDED_YEAR), cal.get(MONTH));
   2498         }
   2499         break;
   2500 
   2501         case DAY_OF_YEAR:
   2502         {
   2503             Calendar cal = (Calendar) clone();
   2504             cal.setLenient(true);
   2505             cal.prepareGetActual(field, false);
   2506             result = handleGetYearLength(cal.get(EXTENDED_YEAR));
   2507         }
   2508         break;
   2509 
   2510         case ERA:
   2511         case DAY_OF_WEEK:
   2512         case AM_PM:
   2513         case HOUR:
   2514         case HOUR_OF_DAY:
   2515         case MINUTE:
   2516         case SECOND:
   2517         case MILLISECOND:
   2518         case ZONE_OFFSET:
   2519         case DST_OFFSET:
   2520         case DOW_LOCAL:
   2521         case JULIAN_DAY:
   2522         case MILLISECONDS_IN_DAY:
   2523             // These fields all have fixed minima/maxima
   2524             result = getMaximum(field);
   2525             break;
   2526 
   2527         default:
   2528             // For all other fields, do it the hard way....
   2529             result = getActualHelper(field, getLeastMaximum(field), getMaximum(field));
   2530             break;
   2531         }
   2532         return result;
   2533     }
   2534 
   2535     /**
   2536      * Returns the minimum value that this field could have, given the current date.
   2537      * For most fields, this is the same as {@link #getMinimum getMinimum}
   2538      * and {@link #getGreatestMinimum getGreatestMinimum}.  However, some fields,
   2539      * especially those related to week number, are more complicated.
   2540      * <p>
   2541      * For example, assume {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
   2542      * returns 4 and {@link #getFirstDayOfWeek getFirstDayOfWeek} returns SUNDAY.
   2543      * If the first day of the month is Sunday, Monday, Tuesday, or Wednesday
   2544      * there will be four or more days in the first week, so it will be week number 1,
   2545      * and <code>getActualMinimum(WEEK_OF_MONTH)</code> will return 1.  However,
   2546      * if the first of the month is a Thursday, Friday, or Saturday, there are
   2547      * <em>not</em> four days in that week, so it is week number 0, and
   2548      * <code>getActualMinimum(WEEK_OF_MONTH)</code> will return 0.
   2549      * <p>
   2550      * @param field the field whose actual minimum value is desired.
   2551      * @return the minimum of the given field for the current date of this calendar
   2552      *
   2553      * @see #getMinimum
   2554      * @see #getGreatestMinimum
   2555      * @stable ICU 2.0
   2556      */
   2557     public int getActualMinimum(int field) {
   2558         int result;
   2559 
   2560         switch (field) {
   2561         case DAY_OF_WEEK:
   2562         case AM_PM:
   2563         case HOUR:
   2564         case HOUR_OF_DAY:
   2565         case MINUTE:
   2566         case SECOND:
   2567         case MILLISECOND:
   2568         case ZONE_OFFSET:
   2569         case DST_OFFSET:
   2570         case DOW_LOCAL:
   2571         case JULIAN_DAY:
   2572         case MILLISECONDS_IN_DAY:
   2573             // These fields all have fixed minima/maxima
   2574             result = getMinimum(field);
   2575             break;
   2576 
   2577         default:
   2578             // For all other fields, do it the hard way....
   2579             result = getActualHelper(field, getGreatestMinimum(field), getMinimum(field));
   2580             break;
   2581         }
   2582         return result;
   2583     }
   2584 
   2585     /**
   2586      * Prepare this calendar for computing the actual minimum or maximum.
   2587      * This method modifies this calendar's fields; it is called on a
   2588      * temporary calendar.
   2589      *
   2590      * <p>Rationale: The semantics of getActualXxx() is to return the
   2591      * maximum or minimum value that the given field can take, taking into
   2592      * account other relevant fields.  In general these other fields are
   2593      * larger fields.  For example, when computing the actual maximum
   2594      * DAY_OF_MONTH, the current value of DAY_OF_MONTH itself is ignored,
   2595      * as is the value of any field smaller.
   2596      *
   2597      * <p>The time fields all have fixed minima and maxima, so we don't
   2598      * need to worry about them.  This also lets us set the
   2599      * MILLISECONDS_IN_DAY to zero to erase any effects the time fields
   2600      * might have when computing date fields.
   2601      *
   2602      * <p>DAY_OF_WEEK is adjusted specially for the WEEK_OF_MONTH and
   2603      * WEEK_OF_YEAR fields to ensure that they are computed correctly.
   2604      * @stable ICU 2.0
   2605      */
   2606     protected void prepareGetActual(int field, boolean isMinimum) {
   2607         set(MILLISECONDS_IN_DAY, 0);
   2608 
   2609         switch (field) {
   2610         case YEAR:
   2611         case EXTENDED_YEAR:
   2612             set(DAY_OF_YEAR, getGreatestMinimum(DAY_OF_YEAR));
   2613             break;
   2614 
   2615         case YEAR_WOY:
   2616             set(WEEK_OF_YEAR, getGreatestMinimum(WEEK_OF_YEAR));
   2617             break;
   2618 
   2619         case MONTH:
   2620             set(DAY_OF_MONTH, getGreatestMinimum(DAY_OF_MONTH));
   2621             break;
   2622 
   2623         case DAY_OF_WEEK_IN_MONTH:
   2624             // For dowim, the maximum occurs for the DOW of the first of the
   2625             // month.
   2626             set(DAY_OF_MONTH, 1);
   2627             set(DAY_OF_WEEK, get(DAY_OF_WEEK)); // Make this user set
   2628             break;
   2629 
   2630         case WEEK_OF_MONTH:
   2631         case WEEK_OF_YEAR:
   2632             // If we're counting weeks, set the day of the week to either the
   2633             // first or last localized DOW.  We know the last week of a month
   2634             // or year will contain the first day of the week, and that the
   2635             // first week will contain the last DOW.
   2636         {
   2637             int dow = firstDayOfWeek;
   2638             if (isMinimum) {
   2639                 dow = (dow + 6) % 7; // set to last DOW
   2640                 if (dow < SUNDAY) {
   2641                     dow += 7;
   2642                 }
   2643             }
   2644             set(DAY_OF_WEEK, dow);
   2645         }
   2646         break;
   2647         }
   2648 
   2649         // Do this last to give it the newest time stamp
   2650         set(field, getGreatestMinimum(field));
   2651     }
   2652 
   2653     private int getActualHelper(int field, int startValue, int endValue) {
   2654 
   2655         if (startValue == endValue) {
   2656             // if we know that the maximum value is always the same, just return it
   2657             return startValue;
   2658         }
   2659 
   2660         final int delta = (endValue > startValue) ? 1 : -1;
   2661 
   2662         // clone the calendar so we don't mess with the real one, and set it to
   2663         // accept anything for the field values
   2664         Calendar work = (Calendar) clone();
   2665 
   2666         // need to resolve time here, otherwise, fields set for actual limit
   2667         // may cause conflict with fields previously set (but not yet resolved).
   2668         work.complete();
   2669 
   2670         work.setLenient(true);
   2671         work.prepareGetActual(field, delta < 0);
   2672 
   2673         // now try each value from the start to the end one by one until
   2674         // we get a value that normalizes to another value.  The last value that
   2675         // normalizes to itself is the actual maximum for the current date
   2676 
   2677         work.set(field, startValue);
   2678         // prepareGetActual sets the first day of week in the same week with
   2679         // the first day of a month.  Unlike WEEK_OF_YEAR, week number for the
   2680         // which week contains days from both previous and current month is
   2681         // not unique.  For example, last several days in the previous month
   2682         // is week 5, and the rest of week is week 1.
   2683         if (work.get(field) != startValue
   2684                 && field != WEEK_OF_MONTH && delta > 0) {
   2685             return startValue;
   2686         }
   2687         int result = startValue;
   2688         do {
   2689             startValue += delta;
   2690             work.add(field, delta);
   2691             if (work.get(field) != startValue) {
   2692                 break;
   2693             }
   2694             result = startValue;
   2695         } while (startValue != endValue);
   2696 
   2697         return result;
   2698     }
   2699 
   2700     /**
   2701      * Rolls (up/down) a single unit of time on the given field.  If the
   2702      * field is rolled past its maximum allowable value, it will "wrap" back
   2703      * to its minimum and continue rolling. For
   2704      * example, to roll the current date up by one day, you can call:
   2705      * <p>
   2706      * <code>roll({@link #DATE}, true)</code>
   2707      * <p>
   2708      * When rolling on the {@link #YEAR} field, it will roll the year
   2709      * value in the range between 1 and the value returned by calling
   2710      * {@link #getMaximum getMaximum}({@link #YEAR}).
   2711      * <p>
   2712      * When rolling on certain fields, the values of other fields may conflict and
   2713      * need to be changed.  For example, when rolling the <code>MONTH</code> field
   2714      * for the Gregorian date 1/31/96 upward, the <code>DAY_OF_MONTH</code> field
   2715      * must be adjusted so that the result is 2/29/96 rather than the invalid
   2716      * 2/31/96.
   2717      * <p>
   2718      * Rolling up always means rolling forward in time (unless
   2719      * the limit of the field is reached, in which case it may pin or wrap), so for the
   2720      * Gregorian calendar, starting with 100 BC and rolling the year up results in 99 BC.
   2721      * When eras have a definite beginning and end (as in the Chinese calendar, or as in
   2722      * most eras in the Japanese calendar) then rolling the year past either limit of the
   2723      * era will cause the year to wrap around. When eras only have a limit at one end,
   2724      * then attempting to roll the year past that limit will result in pinning the year
   2725      * at that limit. Note that for most calendars in which era 0 years move forward in
   2726      * time (such as Buddhist, Hebrew, or Islamic), it is possible for add or roll to
   2727      * result in negative years for era 0 (that is the only way to represent years before
   2728      * the calendar epoch in such calendars).
   2729      * <p>
   2730      * <b>Note:</b> Calling <tt>roll(field, true)</tt> N times is <em>not</em>
   2731      * necessarily equivalent to calling <tt>roll(field, N)</tt>.  For example,
   2732      * imagine that you start with the date Gregorian date January 31, 1995.  If you call
   2733      * <tt>roll(Calendar.MONTH, 2)</tt>, the result will be March 31, 1995.
   2734      * But if you call <tt>roll(Calendar.MONTH, true)</tt>, the result will be
   2735      * February 28, 1995.  Calling it one more time will give March 28, 1995, which
   2736      * is usually not the desired result.
   2737      * <p>
   2738      * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
   2739      * than attempting to perform arithmetic operations directly on the fields
   2740      * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
   2741      * to have fields with non-linear behavior, for example missing months
   2742      * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
   2743      * methods will take this into account, while simple arithmetic manipulations
   2744      * may give invalid results.
   2745      * <p>
   2746      * @param field the calendar field to roll.
   2747      *
   2748      * @param up    indicates if the value of the specified time field is to be
   2749      *              rolled up or rolled down. Use <code>true</code> if rolling up,
   2750      *              <code>false</code> otherwise.
   2751      *
   2752      * @exception   IllegalArgumentException if the field is invalid or refers
   2753      *              to a field that cannot be handled by this method.
   2754      * @see #roll(int, int)
   2755      * @see #add
   2756      * @stable ICU 2.0
   2757      */
   2758     public final void roll(int field, boolean up)
   2759     {
   2760         roll(field, up ? +1 : -1);
   2761     }
   2762 
   2763     /**
   2764      * Rolls (up/down) a specified amount time on the given field.  For
   2765      * example, to roll the current date up by three days, you can call
   2766      * <code>roll(Calendar.DATE, 3)</code>.  If the
   2767      * field is rolled past its maximum allowable value, it will "wrap" back
   2768      * to its minimum and continue rolling.
   2769      * For example, calling <code>roll(Calendar.DATE, 10)</code>
   2770      * on a Gregorian calendar set to 4/25/96 will result in the date 4/5/96.
   2771      * <p>
   2772      * When rolling on certain fields, the values of other fields may conflict and
   2773      * need to be changed.  For example, when rolling the {@link #MONTH MONTH} field
   2774      * for the Gregorian date 1/31/96 by +1, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
   2775      * must be adjusted so that the result is 2/29/96 rather than the invalid
   2776      * 2/31/96.
   2777      * <p>
   2778      * Rolling by a positive value always means rolling forward in time (unless
   2779      * the limit of the field is reached, in which case it may pin or wrap), so for the
   2780      * Gregorian calendar, starting with 100 BC and rolling the year by + 1 results in 99 BC.
   2781      * When eras have a definite beginning and end (as in the Chinese calendar, or as in
   2782      * most eras in the Japanese calendar) then rolling the year past either limit of the
   2783      * era will cause the year to wrap around. When eras only have a limit at one end,
   2784      * then attempting to roll the year past that limit will result in pinning the year
   2785      * at that limit. Note that for most calendars in which era 0 years move forward in
   2786      * time (such as Buddhist, Hebrew, or Islamic), it is possible for add or roll to
   2787      * result in negative years for era 0 (that is the only way to represent years before
   2788      * the calendar epoch in such calendars).
   2789      * <p>
   2790      * {@icunote} the ICU implementation of this method is able to roll
   2791      * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
   2792      * and {@link #ZONE_OFFSET ZONE_OFFSET}.  Subclasses may, of course, add support for
   2793      * additional fields in their overrides of <code>roll</code>.
   2794      * <p>
   2795      * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
   2796      * than attempting to perform arithmetic operations directly on the fields
   2797      * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
   2798      * to have fields with non-linear behavior, for example missing months
   2799      * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
   2800      * methods will take this into account, while simple arithmetic manipulations
   2801      * may give invalid results.
   2802      * <p>
   2803      * <b>Subclassing:</b><br>
   2804      * This implementation of <code>roll</code> assumes that the behavior of the
   2805      * field is continuous between its minimum and maximum, which are found by
   2806      * calling {@link #getActualMinimum getActualMinimum} and {@link #getActualMaximum getActualMaximum}.
   2807      * For most such fields, simple addition, subtraction, and modulus operations
   2808      * are sufficient to perform the roll.  For week-related fields,
   2809      * the results of {@link #getFirstDayOfWeek getFirstDayOfWeek} and
   2810      * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} are also necessary.
   2811      * Subclasses can override these two methods if their values differ from the defaults.
   2812      * <p>
   2813      * Subclasses that have fields for which the assumption of continuity breaks
   2814      * down must overide <code>roll</code> to handle those fields specially.
   2815      * For example, in the Hebrew calendar the month "Adar I"
   2816      * only occurs in leap years; in other years the calendar jumps from
   2817      * Shevat (month #4) to Adar (month #6).  The
   2818      * {@link HebrewCalendar#roll HebrewCalendar.roll} method takes this into account,
   2819      * so that rolling the month of Shevat by one gives the proper result (Adar) in a
   2820      * non-leap year.
   2821      * <p>
   2822      * @param field     the calendar field to roll.
   2823      * @param amount    the amount by which the field should be rolled.
   2824      *
   2825      * @exception   IllegalArgumentException if the field is invalid or refers
   2826      *              to a field that cannot be handled by this method.
   2827      * @see #roll(int, boolean)
   2828      * @see #add
   2829      * @stable ICU 2.0
   2830      */
   2831     public void roll(int field, int amount) {
   2832 
   2833         if (amount == 0) {
   2834             return; // Nothing to do
   2835         }
   2836 
   2837         complete();
   2838 
   2839         switch (field) {
   2840         case DAY_OF_MONTH:
   2841         case AM_PM:
   2842         case MINUTE:
   2843         case SECOND:
   2844         case MILLISECOND:
   2845         case MILLISECONDS_IN_DAY:
   2846         case ERA:
   2847             // These are the standard roll instructions.  These work for all
   2848             // simple cases, that is, cases in which the limits are fixed, such
   2849             // as the hour, the day of the month, and the era.
   2850         {
   2851             int min = getActualMinimum(field);
   2852             int max = getActualMaximum(field);
   2853             int gap = max - min + 1;
   2854 
   2855             int value = internalGet(field) + amount;
   2856             value = (value - min) % gap;
   2857             if (value < 0) {
   2858                 value += gap;
   2859             }
   2860             value += min;
   2861 
   2862             set(field, value);
   2863             return;
   2864         }
   2865 
   2866         case HOUR:
   2867         case HOUR_OF_DAY:
   2868             // Rolling the hour is difficult on the ONSET and CEASE days of
   2869             // daylight savings.  For example, if the change occurs at
   2870             // 2 AM, we have the following progression:
   2871             // ONSET: 12 Std -> 1 Std -> 3 Dst -> 4 Dst
   2872             // CEASE: 12 Dst -> 1 Dst -> 1 Std -> 2 Std
   2873             // To get around this problem we don't use fields; we manipulate
   2874             // the time in millis directly.
   2875         {
   2876             // Assume min == 0 in calculations below
   2877             long start = getTimeInMillis();
   2878             int oldHour = internalGet(field);
   2879             int max = getMaximum(field);
   2880             int newHour = (oldHour + amount) % (max + 1);
   2881             if (newHour < 0) {
   2882                 newHour += max + 1;
   2883             }
   2884             setTimeInMillis(start + ONE_HOUR * ((long)newHour - oldHour));
   2885             return;
   2886         }
   2887 
   2888         case MONTH:
   2889             // Rolling the month involves both pinning the final value
   2890             // and adjusting the DAY_OF_MONTH if necessary.  We only adjust the
   2891             // DAY_OF_MONTH if, after updating the MONTH field, it is illegal.
   2892             // E.g., <jan31>.roll(MONTH, 1) -> <feb28> or <feb29>.
   2893         {
   2894             int max = getActualMaximum(MONTH);
   2895             int mon = (internalGet(MONTH) + amount) % (max+1);
   2896 
   2897             if (mon < 0) {
   2898                 mon += (max + 1);
   2899             }
   2900             set(MONTH, mon);
   2901 
   2902             // Keep the day of month in range.  We don't want to spill over
   2903             // into the next month; e.g., we don't want jan31 + 1 mo -> feb31 ->
   2904             // mar3.
   2905             pinField(DAY_OF_MONTH);
   2906             return;
   2907         }
   2908 
   2909         case YEAR:
   2910         case YEAR_WOY:
   2911             // * If era==0 and years go backwards in time, change sign of amount.
   2912             // * Until we have new API per #9393, we temporarily hardcode knowledge of
   2913             //   which calendars have era 0 years that go backwards.
   2914         {
   2915             boolean era0WithYearsThatGoBackwards = false;
   2916             int era = get(ERA);
   2917             if (era == 0) {
   2918                 String calType = getType();
   2919                 if (calType.equals("gregorian") || calType.equals("roc") || calType.equals("coptic")) {
   2920                     amount = -amount;
   2921                     era0WithYearsThatGoBackwards = true;
   2922                 }
   2923             }
   2924             int newYear = internalGet(field) + amount;
   2925             if (era > 0 || newYear >= 1) {
   2926                 int maxYear = getActualMaximum(field);
   2927                 if (maxYear < 32768) {
   2928                     // this era has real bounds, roll should wrap years
   2929                     if (newYear < 1) {
   2930                         newYear = maxYear - ((-newYear) % maxYear);
   2931                     } else if (newYear > maxYear) {
   2932                         newYear = ((newYear - 1) % maxYear) + 1;
   2933                     }
   2934                     // else era is unbounded, just pin low year instead of wrapping
   2935                 } else if (newYear < 1) {
   2936                     newYear = 1;
   2937                 }
   2938                 // else we are in era 0 with newYear < 1;
   2939                 // calendars with years that go backwards must pin the year value at 0,
   2940                 // other calendars can have years < 0 in era 0
   2941             } else if (era0WithYearsThatGoBackwards) {
   2942                 newYear = 1;
   2943             }
   2944             set(field, newYear);
   2945             pinField(MONTH);
   2946             pinField(DAY_OF_MONTH);
   2947             return;
   2948         }
   2949         case EXTENDED_YEAR:
   2950             // Rolling the year can involve pinning the DAY_OF_MONTH.
   2951             set(field, internalGet(field) + amount);
   2952             pinField(MONTH);
   2953             pinField(DAY_OF_MONTH);
   2954             return;
   2955 
   2956         case WEEK_OF_MONTH:
   2957         {
   2958             // This is tricky, because during the roll we may have to shift
   2959             // to a different day of the week.  For example:
   2960 
   2961             //    s  m  t  w  r  f  s
   2962             //          1  2  3  4  5
   2963             //    6  7  8  9 10 11 12
   2964 
   2965             // When rolling from the 6th or 7th back one week, we go to the
   2966             // 1st (assuming that the first partial week counts).  The same
   2967             // thing happens at the end of the month.
   2968 
   2969             // The other tricky thing is that we have to figure out whether
   2970             // the first partial week actually counts or not, based on the
   2971             // minimal first days in the week.  And we have to use the
   2972             // correct first day of the week to delineate the week
   2973             // boundaries.
   2974 
   2975             // Here's our algorithm.  First, we find the real boundaries of
   2976             // the month.  Then we discard the first partial week if it
   2977             // doesn't count in this locale.  Then we fill in the ends with
   2978             // phantom days, so that the first partial week and the last
   2979             // partial week are full weeks.  We then have a nice square
   2980             // block of weeks.  We do the usual rolling within this block,
   2981             // as is done elsewhere in this method.  If we wind up on one of
   2982             // the phantom days that we added, we recognize this and pin to
   2983             // the first or the last day of the month.  Easy, eh?
   2984 
   2985             // Normalize the DAY_OF_WEEK so that 0 is the first day of the week
   2986             // in this locale.  We have dow in 0..6.
   2987             int dow = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek();
   2988             if (dow < 0) dow += 7;
   2989 
   2990             // Find the day of the week (normalized for locale) for the first
   2991             // of the month.
   2992             int fdm = (dow - internalGet(DAY_OF_MONTH) + 1) % 7;
   2993             if (fdm < 0) fdm += 7;
   2994 
   2995             // Get the first day of the first full week of the month,
   2996             // including phantom days, if any.  Figure out if the first week
   2997             // counts or not; if it counts, then fill in phantom days.  If
   2998             // not, advance to the first real full week (skip the partial week).
   2999             int start;
   3000             if ((7 - fdm) < getMinimalDaysInFirstWeek())
   3001                 start = 8 - fdm; // Skip the first partial week
   3002             else
   3003                 start = 1 - fdm; // This may be zero or negative
   3004 
   3005             // Get the day of the week (normalized for locale) for the last
   3006             // day of the month.
   3007             int monthLen = getActualMaximum(DAY_OF_MONTH);
   3008             int ldm = (monthLen - internalGet(DAY_OF_MONTH) + dow) % 7;
   3009             // We know monthLen >= DAY_OF_MONTH so we skip the += 7 step here.
   3010 
   3011             // Get the limit day for the blocked-off rectangular month; that
   3012             // is, the day which is one past the last day of the month,
   3013             // after the month has already been filled in with phantom days
   3014             // to fill out the last week.  This day has a normalized DOW of 0.
   3015             int limit = monthLen + 7 - ldm;
   3016 
   3017             // Now roll between start and (limit - 1).
   3018             int gap = limit - start;
   3019             int day_of_month = (internalGet(DAY_OF_MONTH) + amount*7 -
   3020                     start) % gap;
   3021             if (day_of_month < 0) day_of_month += gap;
   3022             day_of_month += start;
   3023 
   3024             // Finally, pin to the real start and end of the month.
   3025             if (day_of_month < 1) day_of_month = 1;
   3026             if (day_of_month > monthLen) day_of_month = monthLen;
   3027 
   3028             // Set the DAY_OF_MONTH.  We rely on the fact that this field
   3029             // takes precedence over everything else (since all other fields
   3030             // are also set at this point).  If this fact changes (if the
   3031             // disambiguation algorithm changes) then we will have to unset
   3032             // the appropriate fields here so that DAY_OF_MONTH is attended
   3033             // to.
   3034             set(DAY_OF_MONTH, day_of_month);
   3035             return;
   3036         }
   3037         case WEEK_OF_YEAR:
   3038         {
   3039             // This follows the outline of WEEK_OF_MONTH, except it applies
   3040             // to the whole year.  Please see the comment for WEEK_OF_MONTH
   3041             // for general notes.
   3042 
   3043             // Normalize the DAY_OF_WEEK so that 0 is the first day of the week
   3044             // in this locale.  We have dow in 0..6.
   3045             int dow = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek();
   3046             if (dow < 0) dow += 7;
   3047 
   3048             // Find the day of the week (normalized for locale) for the first
   3049             // of the year.
   3050             int fdy = (dow - internalGet(DAY_OF_YEAR) + 1) % 7;
   3051             if (fdy < 0) fdy += 7;
   3052 
   3053             // Get the first day of the first full week of the year,
   3054             // including phantom days, if any.  Figure out if the first week
   3055             // counts or not; if it counts, then fill in phantom days.  If
   3056             // not, advance to the first real full week (skip the partial week).
   3057             int start;
   3058             if ((7 - fdy) < getMinimalDaysInFirstWeek())
   3059                 start = 8 - fdy; // Skip the first partial week
   3060             else
   3061                 start = 1 - fdy; // This may be zero or negative
   3062 
   3063             // Get the day of the week (normalized for locale) for the last
   3064             // day of the year.
   3065             int yearLen = getActualMaximum(DAY_OF_YEAR);
   3066             int ldy = (yearLen - internalGet(DAY_OF_YEAR) + dow) % 7;
   3067             // We know yearLen >= DAY_OF_YEAR so we skip the += 7 step here.
   3068 
   3069             // Get the limit day for the blocked-off rectangular year; that
   3070             // is, the day which is one past the last day of the year,
   3071             // after the year has already been filled in with phantom days
   3072             // to fill out the last week.  This day has a normalized DOW of 0.
   3073             int limit = yearLen + 7 - ldy;
   3074 
   3075             // Now roll between start and (limit - 1).
   3076             int gap = limit - start;
   3077             int day_of_year = (internalGet(DAY_OF_YEAR) + amount*7 -
   3078                     start) % gap;
   3079             if (day_of_year < 0) day_of_year += gap;
   3080             day_of_year += start;
   3081 
   3082             // Finally, pin to the real start and end of the month.
   3083             if (day_of_year < 1) day_of_year = 1;
   3084             if (day_of_year > yearLen) day_of_year = yearLen;
   3085 
   3086             // Make sure that the year and day of year are attended to by
   3087             // clearing other fields which would normally take precedence.
   3088             // If the disambiguation algorithm is changed, this section will
   3089             // have to be updated as well.
   3090             set(DAY_OF_YEAR, day_of_year);
   3091             clear(MONTH);
   3092             return;
   3093         }
   3094         case DAY_OF_YEAR:
   3095         {
   3096             // Roll the day of year using millis.  Compute the millis for
   3097             // the start of the year, and get the length of the year.
   3098             long delta = amount * ONE_DAY; // Scale up from days to millis
   3099             long min2 = time - (internalGet(DAY_OF_YEAR) - 1) * ONE_DAY;
   3100             int yearLength = getActualMaximum(DAY_OF_YEAR);
   3101             time = (time + delta - min2) % (yearLength*ONE_DAY);
   3102             if (time < 0) time += yearLength*ONE_DAY;
   3103             setTimeInMillis(time + min2);
   3104             return;
   3105         }
   3106         case DAY_OF_WEEK:
   3107         case DOW_LOCAL:
   3108         {
   3109             // Roll the day of week using millis.  Compute the millis for
   3110             // the start of the week, using the first day of week setting.
   3111             // Restrict the millis to [start, start+7days).
   3112             long delta = amount * ONE_DAY; // Scale up from days to millis
   3113             // Compute the number of days before the current day in this
   3114             // week.  This will be a value 0..6.
   3115             int leadDays = internalGet(field);
   3116             leadDays -= (field == DAY_OF_WEEK) ? getFirstDayOfWeek() : 1;
   3117             if (leadDays < 0) leadDays += 7;
   3118             long min2 = time - leadDays * ONE_DAY;
   3119             time = (time + delta - min2) % ONE_WEEK;
   3120             if (time < 0) time += ONE_WEEK;
   3121             setTimeInMillis(time + min2);
   3122             return;
   3123         }
   3124         case DAY_OF_WEEK_IN_MONTH:
   3125         {
   3126             // Roll the day of week in the month using millis.  Determine
   3127             // the first day of the week in the month, and then the last,
   3128             // and then roll within that range.
   3129             long delta = amount * ONE_WEEK; // Scale up from weeks to millis
   3130             // Find the number of same days of the week before this one
   3131             // in this month.
   3132             int preWeeks = (internalGet(DAY_OF_MONTH) - 1) / 7;
   3133             // Find the number of same days of the week after this one
   3134             // in this month.
   3135             int postWeeks = (getActualMaximum(DAY_OF_MONTH) -
   3136                     internalGet(DAY_OF_MONTH)) / 7;
   3137             // From these compute the min and gap millis for rolling.
   3138             long min2 = time - preWeeks * ONE_WEEK;
   3139             long gap2 = ONE_WEEK * (preWeeks + postWeeks + 1); // Must add 1!
   3140             // Roll within this range
   3141             time = (time + delta - min2) % gap2;
   3142             if (time < 0) time += gap2;
   3143             setTimeInMillis(time + min2);
   3144             return;
   3145         }
   3146         case JULIAN_DAY:
   3147             set(field, internalGet(field) + amount);
   3148             return;
   3149         default:
   3150             // Other fields cannot be rolled by this method
   3151             throw new IllegalArgumentException("Calendar.roll(" + fieldName(field) +
   3152                     ") not supported");
   3153         }
   3154     }
   3155 
   3156     /**
   3157      * Add a signed amount to a specified field, using this calendar's rules.
   3158      * For example, to add three days to the current date, you can call
   3159      * <code>add(Calendar.DATE, 3)</code>.
   3160      * <p>
   3161      * When adding to certain fields, the values of other fields may conflict and
   3162      * need to be changed.  For example, when adding one to the {@link #MONTH MONTH} field
   3163      * for the Gregorian date 1/31/96, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
   3164      * must be adjusted so that the result is 2/29/96 rather than the invalid
   3165      * 2/31/96.
   3166      * <p>
   3167      * Adding a positive value always means moving forward in time, so for the Gregorian
   3168      * calendar, starting with 100 BC and adding +1 to year results in 99 BC (even though
   3169      * this actually reduces the numeric value of the field itself).
   3170      * <p>
   3171      * {@icunote} The ICU implementation of this method is able to add to
   3172      * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
   3173      * and {@link #ZONE_OFFSET ZONE_OFFSET}.  Subclasses may, of course, add support for
   3174      * additional fields in their overrides of <code>add</code>.
   3175      * <p>
   3176      * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
   3177      * than attempting to perform arithmetic operations directly on the fields
   3178      * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
   3179      * to have fields with non-linear behavior, for example missing months
   3180      * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
   3181      * methods will take this into account, while simple arithmetic manipulations
   3182      * may give invalid results.
   3183      * <p>
   3184      * <b>Subclassing:</b><br>
   3185      * This implementation of <code>add</code> assumes that the behavior of the
   3186      * field is continuous between its minimum and maximum, which are found by
   3187      * calling {@link #getActualMinimum getActualMinimum} and
   3188      * {@link #getActualMaximum getActualMaximum}.
   3189      * For such fields, simple arithmetic operations are sufficient to
   3190      * perform the add.
   3191      * <p>
   3192      * Subclasses that have fields for which this assumption of continuity breaks
   3193      * down must overide <code>add</code> to handle those fields specially.
   3194      * For example, in the Hebrew calendar the month "Adar I"
   3195      * only occurs in leap years; in other years the calendar jumps from
   3196      * Shevat (month #4) to Adar (month #6).  The
   3197      * {@link HebrewCalendar#add HebrewCalendar.add} method takes this into account,
   3198      * so that adding one month
   3199      * to a date in Shevat gives the proper result (Adar) in a non-leap year.
   3200      * <p>
   3201      * @param field     the time field.
   3202      * @param amount    the amount to add to the field.
   3203      *
   3204      * @exception   IllegalArgumentException if the field is invalid or refers
   3205      *              to a field that cannot be handled by this method.
   3206      * @see #roll(int, int)
   3207      * @stable ICU 2.0
   3208      */
   3209     @SuppressWarnings("fallthrough")
   3210     public void add(int field, int amount) {
   3211 
   3212         if (amount == 0) {
   3213             return;   // Do nothing!
   3214         }
   3215 
   3216         // We handle most fields in the same way.  The algorithm is to add
   3217         // a computed amount of millis to the current millis.  The only
   3218         // wrinkle is with DST (and/or a change to the zone's UTC offset, which
   3219         // we'll include with DST) -- for some fields, like the DAY_OF_MONTH,
   3220         // we don't want the wall time to shift due to changes in DST.  If the
   3221         // result of the add operation is to move from DST to Standard, or
   3222         // vice versa, we need to adjust by an hour forward or back,
   3223         // respectively.  For such fields we set keepWallTimeInvariant to true.
   3224 
   3225         // We only adjust the DST for fields larger than an hour.  For
   3226         // fields smaller than an hour, we cannot adjust for DST without
   3227         // causing problems.  for instance, if you add one hour to April 5,
   3228         // 1998, 1:00 AM, in PST, the time becomes "2:00 AM PDT" (an
   3229         // illegal value), but then the adjustment sees the change and
   3230         // compensates by subtracting an hour.  As a result the time
   3231         // doesn't advance at all.
   3232 
   3233         // For some fields larger than a day, such as a MONTH, we pin the
   3234         // DAY_OF_MONTH.  This allows <March 31>.add(MONTH, 1) to be
   3235         // <April 30>, rather than <April 31> => <May 1>.
   3236 
   3237         long delta = amount; // delta in ms
   3238         boolean keepWallTimeInvariant = true;
   3239 
   3240         switch (field) {
   3241         case ERA:
   3242             set(field, get(field) + amount);
   3243             pinField(ERA);
   3244             return;
   3245 
   3246         case YEAR:
   3247         case YEAR_WOY:
   3248             // * If era=0 and years go backwards in time, change sign of amount.
   3249             // * Until we have new API per #9393, we temporarily hardcode knowledge of
   3250             //   which calendars have era 0 years that go backwards.
   3251             // * Note that for YEAR (but not YEAR_WOY) we could instead handle
   3252             //   this by applying the amount to the EXTENDED_YEAR field; but since
   3253             //   we would still need to handle YEAR_WOY as below, might as well
   3254             //   also handle YEAR the same way.
   3255         {
   3256             int era = get(ERA);
   3257             if (era == 0) {
   3258                 String calType = getType();
   3259                 if (calType.equals("gregorian") || calType.equals("roc") || calType.equals("coptic")) {
   3260                     amount = -amount;
   3261                 }
   3262             }
   3263         }
   3264         // Fall through into standard handling
   3265         case EXTENDED_YEAR:
   3266         case MONTH:
   3267         {
   3268             boolean oldLenient = isLenient();
   3269             setLenient(true);
   3270             set(field, get(field) + amount);
   3271             pinField(DAY_OF_MONTH);
   3272             if(oldLenient==false) {
   3273                 complete();
   3274                 setLenient(oldLenient);
   3275             }
   3276         }
   3277         return;
   3278 
   3279         case WEEK_OF_YEAR:
   3280         case WEEK_OF_MONTH:
   3281         case DAY_OF_WEEK_IN_MONTH:
   3282             delta *= ONE_WEEK;
   3283             break;
   3284 
   3285         case AM_PM:
   3286             delta *= 12 * ONE_HOUR;
   3287             break;
   3288 
   3289         case DAY_OF_MONTH:
   3290         case DAY_OF_YEAR:
   3291         case DAY_OF_WEEK:
   3292         case DOW_LOCAL:
   3293         case JULIAN_DAY:
   3294             delta *= ONE_DAY;
   3295             break;
   3296 
   3297         case HOUR_OF_DAY:
   3298         case HOUR:
   3299             delta *= ONE_HOUR;
   3300             keepWallTimeInvariant = false;
   3301             break;
   3302 
   3303         case MINUTE:
   3304             delta *= ONE_MINUTE;
   3305             keepWallTimeInvariant = false;
   3306             break;
   3307 
   3308         case SECOND:
   3309             delta *= ONE_SECOND;
   3310             keepWallTimeInvariant = false;
   3311             break;
   3312 
   3313         case MILLISECOND:
   3314         case MILLISECONDS_IN_DAY:
   3315             keepWallTimeInvariant = false;
   3316             break;
   3317 
   3318         default:
   3319             throw new IllegalArgumentException("Calendar.add(" + fieldName(field) +
   3320                     ") not supported");
   3321         }
   3322 
   3323         // In order to keep the wall time invariant (for fields where this is
   3324         // appropriate), check the combined DST & ZONE offset before and
   3325         // after the add() operation. If it changes, then adjust the millis
   3326         // to compensate.
   3327         int prevOffset = 0;
   3328         int prevWallTime = 0;
   3329         if (keepWallTimeInvariant) {
   3330             prevOffset = get(DST_OFFSET) + get(ZONE_OFFSET);
   3331             prevWallTime = get(MILLISECONDS_IN_DAY);
   3332         }
   3333 
   3334         setTimeInMillis(getTimeInMillis() + delta);
   3335 
   3336         if (keepWallTimeInvariant) {
   3337             int newWallTime = get(MILLISECONDS_IN_DAY);
   3338             if (newWallTime != prevWallTime) {
   3339                 // There is at least one zone transition between the base
   3340                 // time and the result time. As the result, wall time has
   3341                 // changed.
   3342                 long t = internalGetTimeInMillis();
   3343                 int newOffset = get(DST_OFFSET) + get(ZONE_OFFSET);
   3344                 if (newOffset != prevOffset) {
   3345                     // When the difference of the previous UTC offset and
   3346                     // the new UTC offset exceeds 1 full day, we do not want
   3347                     // to roll over/back the date. For now, this only happens
   3348                     // in Samoa (Pacific/Apia) on Dec 30, 2011. See ticket:9452.
   3349                     long adjAmount = (prevOffset - newOffset) % ONE_DAY;
   3350                     if (adjAmount != 0) {
   3351                         setTimeInMillis(t + adjAmount);
   3352                         newWallTime = get(MILLISECONDS_IN_DAY);
   3353                     }
   3354                     if (newWallTime != prevWallTime) {
   3355                         // The result wall time or adjusted wall time was shifted because
   3356                         // the target wall time does not exist on the result date.
   3357                         switch (skippedWallTime) {
   3358                         case WALLTIME_FIRST:
   3359                             if (adjAmount > 0) {
   3360                                 setTimeInMillis(t);
   3361                             }
   3362                             break;
   3363                         case WALLTIME_LAST:
   3364                             if (adjAmount < 0) {
   3365                                 setTimeInMillis(t);
   3366                             }
   3367                             break;
   3368                         case WALLTIME_NEXT_VALID:
   3369                             long tmpT = adjAmount > 0 ? internalGetTimeInMillis() : t;
   3370                             Long immediatePrevTrans = getImmediatePreviousZoneTransition(tmpT);
   3371                             if (immediatePrevTrans != null) {
   3372                                 setTimeInMillis(immediatePrevTrans);
   3373                             } else {
   3374                                 throw new RuntimeException("Could not locate a time zone transition before " + tmpT);
   3375                             }
   3376                             break;
   3377                         }
   3378                     }
   3379                 }
   3380             }
   3381         }
   3382     }
   3383 
   3384     /**
   3385      * Returns the name of this calendar in the language of the given locale.
   3386      * @stable ICU 2.0
   3387      */
   3388     public String getDisplayName(Locale loc) {
   3389         return this.getClass().getName();
   3390     }
   3391 
   3392     /**
   3393      * Returns the name of this calendar in the language of the given locale.
   3394      * @stable ICU 3.2
   3395      */
   3396     public String getDisplayName(ULocale loc) {
   3397         return this.getClass().getName();
   3398     }
   3399 
   3400     /**
   3401      * Compares the times (in millis) represented by two
   3402      * <code>Calendar</code> objects.
   3403      *
   3404      * @param that the <code>Calendar</code> to compare to this.
   3405      * @return <code>0</code> if the time represented by
   3406      * this <code>Calendar</code> is equal to the time represented
   3407      * by that <code>Calendar</code>, a value less than
   3408      * <code>0</code> if the time represented by this is before
   3409      * the time represented by that, and a value greater than
   3410      * <code>0</code> if the time represented by this
   3411      * is after the time represented by that.
   3412      * @throws NullPointerException if that
   3413      * <code>Calendar</code> is null.
   3414      * @throws IllegalArgumentException if the time of that
   3415      * <code>Calendar</code> can't be obtained because of invalid
   3416      * calendar values.
   3417      * @stable ICU 3.4
   3418      */
   3419     public int compareTo(Calendar that) {
   3420         long v = getTimeInMillis() - that.getTimeInMillis();
   3421         return v < 0 ? -1 : (v > 0 ? 1 : 0);
   3422     }
   3423 
   3424     //-------------------------------------------------------------------------
   3425     // Interface for creating custon DateFormats for different types of Calendars
   3426     //-------------------------------------------------------------------------
   3427 
   3428     /**
   3429      * {@icu} Returns a <code>DateFormat</code> appropriate to this calendar.
   3430      * Subclasses wishing to specialize this behavior should override
   3431      * {@link #handleGetDateFormat}.
   3432      * @stable ICU 2.0
   3433      */
   3434     public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, Locale loc) {
   3435         return formatHelper(this, ULocale.forLocale(loc), dateStyle, timeStyle);
   3436     }
   3437 
   3438     /**
   3439      * {@icu} Returns a <code>DateFormat</code> appropriate to this calendar.
   3440      * Subclasses wishing to specialize this behavior should override
   3441      * {@link #handleGetDateFormat}.
   3442      * @stable ICU 3.2
   3443      */
   3444     public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, ULocale loc) {
   3445         return formatHelper(this, loc, dateStyle, timeStyle);
   3446     }
   3447 
   3448     /**
   3449      * Creates a <code>DateFormat</code> appropriate to this calendar.
   3450      * This is a framework method for subclasses to override.  This method
   3451      * is responsible for creating the calendar-specific DateFormat and
   3452      * DateFormatSymbols objects as needed.
   3453      * @param pattern the pattern, specific to the <code>DateFormat</code>
   3454      * subclass
   3455      * @param locale the locale for which the symbols should be drawn
   3456      * @return a <code>DateFormat</code> appropriate to this calendar
   3457      * @stable ICU 2.0
   3458      */
   3459     protected DateFormat handleGetDateFormat(String pattern, Locale locale) {
   3460         return handleGetDateFormat(pattern, null, ULocale.forLocale(locale));
   3461     }
   3462 
   3463     /**
   3464      * Creates a <code>DateFormat</code> appropriate to this calendar.
   3465      * This is a framework method for subclasses to override.  This method
   3466      * is responsible for creating the calendar-specific DateFormat and
   3467      * DateFormatSymbols objects as needed.
   3468      * @param pattern the pattern, specific to the <code>DateFormat</code>
   3469      * subclass
   3470      * @param override The override string.  A numbering system override string can take one of the following forms:
   3471      *     1). If just a numbering system name is specified, it applies to all numeric fields in the date format pattern.
   3472      *     2). To specify an alternate numbering system on a field by field basis, use the field letters from the pattern
   3473      *         followed by an = sign, followed by the numbering system name.  For example, to specify that just the year
   3474      *         be formatted using Hebrew digits, use the override "y=hebr".  Multiple overrides can be specified in a single
   3475      *         string by separating them with a semi-colon. For example, the override string "m=thai;y=deva" would format using
   3476      *         Thai digits for the month and Devanagari digits for the year.
   3477      * @param locale the locale for which the symbols should be drawn
   3478      * @return a <code>DateFormat</code> appropriate to this calendar
   3479      * @stable ICU 4.2
   3480      */
   3481     protected DateFormat handleGetDateFormat(String pattern, String override, Locale locale) {
   3482         return handleGetDateFormat(pattern, override, ULocale.forLocale(locale));
   3483     }
   3484 
   3485     /**
   3486      * Creates a <code>DateFormat</code> appropriate to this calendar.
   3487      * This is a framework method for subclasses to override.  This method
   3488      * is responsible for creating the calendar-specific DateFormat and
   3489      * DateFormatSymbols objects as needed.
   3490      * @param pattern the pattern, specific to the <code>DateFormat</code>
   3491      * subclass
   3492      * @param locale the locale for which the symbols should be drawn
   3493      * @return a <code>DateFormat</code> appropriate to this calendar
   3494      * @stable ICU 2.0
   3495      */
   3496     protected DateFormat handleGetDateFormat(String pattern, ULocale locale) {
   3497         return handleGetDateFormat(pattern, null, locale);
   3498     }
   3499 
   3500     /**
   3501      * Creates a <code>DateFormat</code> appropriate to this calendar.
   3502      * This is a framework method for subclasses to override.  This method
   3503      * is responsible for creating the calendar-specific DateFormat and
   3504      * DateFormatSymbols objects as needed.
   3505      * @param pattern the pattern, specific to the <code>DateFormat</code>
   3506      * subclass
   3507      * @param locale the locale for which the symbols should be drawn
   3508      * @return a <code>DateFormat</code> appropriate to this calendar
   3509      * @draft ICU 3.2 (retain)
   3510      * @provisional This API might change or be removed in a future release.
   3511      */
   3512     protected DateFormat handleGetDateFormat(String pattern, String override, ULocale locale) {
   3513         FormatConfiguration fmtConfig = new FormatConfiguration();
   3514         fmtConfig.pattern = pattern;
   3515         fmtConfig.override = override;
   3516         fmtConfig.formatData = new DateFormatSymbols(this, locale);
   3517         fmtConfig.loc = locale;
   3518         fmtConfig.cal = this;
   3519 
   3520         return SimpleDateFormat.getInstance(fmtConfig);
   3521     }
   3522 
   3523     // date format pattern cache
   3524     private static final ICUCache<String, PatternData> PATTERN_CACHE =
   3525             new SimpleCache<String, PatternData>();
   3526     // final fallback patterns
   3527     private static final String[] DEFAULT_PATTERNS = {
   3528         "HH:mm:ss z",
   3529         "HH:mm:ss z",
   3530         "HH:mm:ss",
   3531         "HH:mm",
   3532         "EEEE, yyyy MMMM dd",
   3533         "yyyy MMMM d",
   3534         "yyyy MMM d",
   3535         "yy/MM/dd",
   3536         "{1} {0}",
   3537         "{1} {0}",
   3538         "{1} {0}",
   3539         "{1} {0}",
   3540         "{1} {0}"
   3541     };
   3542 
   3543     static private DateFormat formatHelper(Calendar cal, ULocale loc, int dateStyle,
   3544             int timeStyle) {
   3545         if (timeStyle < DateFormat.NONE || timeStyle > DateFormat.SHORT) {
   3546             throw new IllegalArgumentException("Illegal time style " + timeStyle);
   3547         }
   3548         if (dateStyle < DateFormat.NONE || dateStyle > DateFormat.SHORT) {
   3549             throw new IllegalArgumentException("Illegal date style " + dateStyle);
   3550         }
   3551 
   3552         PatternData patternData = PatternData.make(cal, loc);
   3553         String override = null;
   3554 
   3555         // Resolve a pattern for the date/time style
   3556         String pattern = null;
   3557         if ((timeStyle >= 0) && (dateStyle >= 0)) {
   3558             pattern = MessageFormat.format(patternData.getDateTimePattern(dateStyle),
   3559                     new Object[] {patternData.patterns[timeStyle],
   3560                 patternData.patterns[dateStyle + 4]});
   3561             // Might need to merge the overrides from the date and time into a single
   3562             // override string TODO: Right now we are forcing the date's override into the
   3563             // time style.
   3564             if ( patternData.overrides != null ) {
   3565                 String dateOverride = patternData.overrides[dateStyle + 4];
   3566                 String timeOverride = patternData.overrides[timeStyle];
   3567                 override = mergeOverrideStrings(
   3568                         patternData.patterns[dateStyle+4],
   3569                         patternData.patterns[timeStyle],
   3570                         dateOverride, timeOverride);
   3571             }
   3572         } else if (timeStyle >= 0) {
   3573             pattern = patternData.patterns[timeStyle];
   3574             if ( patternData.overrides != null ) {
   3575                 override = patternData.overrides[timeStyle];
   3576             }
   3577         } else if (dateStyle >= 0) {
   3578             pattern = patternData.patterns[dateStyle + 4];
   3579             if ( patternData.overrides != null ) {
   3580                 override = patternData.overrides[dateStyle + 4];
   3581             }
   3582         } else {
   3583             throw new IllegalArgumentException("No date or time style specified");
   3584         }
   3585         DateFormat result = cal.handleGetDateFormat(pattern, override, loc);
   3586         result.setCalendar(cal);
   3587         return result;
   3588     }
   3589 
   3590     static class PatternData {
   3591         // TODO make this even more object oriented
   3592         private String[] patterns;
   3593         private String[] overrides;
   3594         public PatternData(String[] patterns, String[] overrides) {
   3595             this.patterns = patterns;
   3596             this.overrides = overrides;
   3597         }
   3598         private String getDateTimePattern(int dateStyle) {
   3599             int glueIndex = 8;
   3600             if (patterns.length >= 13) {
   3601                 glueIndex += (dateStyle + 1);
   3602             }
   3603             final String dateTimePattern = patterns[glueIndex];
   3604             return dateTimePattern;
   3605         }
   3606         private static PatternData make(Calendar cal, ULocale loc) {
   3607             // First, try to get a pattern from PATTERN_CACHE
   3608             String calType = cal.getType();
   3609             String key = loc.getBaseName() + "+" + calType;
   3610             PatternData patternData = PATTERN_CACHE.get(key);
   3611             if (patternData == null) {
   3612                 // Cache missed.  Get one from bundle
   3613                 try {
   3614                     CalendarData calData = new CalendarData(loc, calType);
   3615                     patternData = new PatternData(calData.getDateTimePatterns(),
   3616                             calData.getOverrides());
   3617                 } catch (MissingResourceException e) {
   3618                     patternData = new PatternData(DEFAULT_PATTERNS, null);
   3619                 }
   3620                 PATTERN_CACHE.put(key, patternData);
   3621             }
   3622             return patternData;
   3623         }
   3624     }
   3625 
   3626     /**
   3627      * @internal
   3628      * @deprecated This API is ICU internal only.
   3629      */
   3630     @Deprecated
   3631     public static String getDateTimePattern(Calendar cal, ULocale uLocale, int dateStyle) {
   3632         PatternData patternData = PatternData.make(cal, uLocale);
   3633         return patternData.getDateTimePattern(dateStyle);
   3634     }
   3635 
   3636     private static String mergeOverrideStrings( String datePattern, String timePattern,
   3637             String dateOverride, String timeOverride ) {
   3638 
   3639         if ( dateOverride == null && timeOverride == null ) {
   3640             return null;
   3641         }
   3642 
   3643         if ( dateOverride == null ) {
   3644             return expandOverride(timePattern,timeOverride);
   3645         }
   3646 
   3647         if ( timeOverride == null ) {
   3648             return expandOverride(datePattern,dateOverride);
   3649         }
   3650 
   3651         if ( dateOverride.equals(timeOverride) ) {
   3652             return dateOverride;
   3653         }
   3654 
   3655         return (expandOverride(datePattern,dateOverride)+";"+
   3656                 expandOverride(timePattern,timeOverride));
   3657 
   3658     }
   3659 
   3660     private static final char QUOTE = '\'';
   3661     private static String expandOverride(String pattern, String override) {
   3662 
   3663         if (override.indexOf('=') >= 0) {
   3664             return override;
   3665         }
   3666         boolean inQuotes = false;
   3667         char prevChar = ' ';
   3668         StringBuilder result = new StringBuilder();
   3669 
   3670         StringCharacterIterator it = new StringCharacterIterator(pattern);
   3671 
   3672         for (char c = it.first(); c!= StringCharacterIterator.DONE; c = it.next()) {
   3673             if ( c == QUOTE ) {
   3674                 inQuotes = !inQuotes;
   3675                 prevChar = c;
   3676                 continue;
   3677             }
   3678             if ( !inQuotes && c != prevChar ) {
   3679                 if (result.length() > 0) {
   3680                     result.append(";");
   3681                 }
   3682                 result.append(c);
   3683                 result.append("=");
   3684                 result.append(override);
   3685             }
   3686             prevChar = c;
   3687         }
   3688         return result.toString();
   3689     }
   3690     /**
   3691      * An instance of FormatConfiguration represents calendar specific
   3692      * date format configuration and used for calling the ICU private
   3693      * SimpleDateFormat factory method.
   3694      *
   3695      * @internal
   3696      * @deprecated This API is ICU internal only.
   3697      */
   3698     @Deprecated
   3699     public static class FormatConfiguration {
   3700         private String pattern;
   3701         private String override;
   3702         private DateFormatSymbols formatData;
   3703         private Calendar cal;
   3704         private ULocale loc;
   3705 
   3706         // Only Calendar can instantiate
   3707         private FormatConfiguration() {
   3708         }
   3709 
   3710         /**
   3711          * Returns the pattern string
   3712          * @return the format pattern string
   3713          * @internal
   3714          * @deprecated This API is ICU internal only.
   3715          */
   3716         @Deprecated
   3717         public String getPatternString() {
   3718             return pattern;
   3719         }
   3720 
   3721         /**
   3722          * @internal
   3723          * @deprecated This API is ICU internal only.
   3724          */
   3725         @Deprecated
   3726         public String getOverrideString() {
   3727             return override;
   3728         }
   3729 
   3730         /**
   3731          * Returns the calendar
   3732          * @return the calendar
   3733          * @internal
   3734          * @deprecated This API is ICU internal only.
   3735          */
   3736         @Deprecated
   3737         public Calendar getCalendar() {
   3738             return cal;
   3739         }
   3740 
   3741         /**
   3742          * Returns the locale
   3743          * @return the locale
   3744          * @internal
   3745          * @deprecated This API is ICU internal only.
   3746          */
   3747         @Deprecated
   3748         public ULocale getLocale() {
   3749             return loc;
   3750         }
   3751 
   3752         /**
   3753          * Returns the format symbols
   3754          * @return the format symbols
   3755          * @internal
   3756          * @deprecated This API is ICU internal only.
   3757          */
   3758         @Deprecated
   3759         public DateFormatSymbols getDateFormatSymbols() {
   3760             return formatData;
   3761         }
   3762     }
   3763 
   3764     //-------------------------------------------------------------------------
   3765     // Protected utility methods for use by subclasses.  These are very handy
   3766     // for implementing add, roll, and computeFields.
   3767     //-------------------------------------------------------------------------
   3768 
   3769     /**
   3770      * Adjust the specified field so that it is within
   3771      * the allowable range for the date to which this calendar is set.
   3772      * For example, in a Gregorian calendar pinning the {@link #DAY_OF_MONTH DAY_OF_MONTH}
   3773      * field for a calendar set to April 31 would cause it to be set
   3774      * to April 30.
   3775      * <p>
   3776      * <b>Subclassing:</b>
   3777      * <br>
   3778      * This utility method is intended for use by subclasses that need to implement
   3779      * their own overrides of {@link #roll roll} and {@link #add add}.
   3780      * <p>
   3781      * <b>Note:</b>
   3782      * <code>pinField</code> is implemented in terms of
   3783      * {@link #getActualMinimum getActualMinimum}
   3784      * and {@link #getActualMaximum getActualMaximum}.  If either of those methods uses
   3785      * a slow, iterative algorithm for a particular field, it would be
   3786      * unwise to attempt to call <code>pinField</code> for that field.  If you
   3787      * really do need to do so, you should override this method to do
   3788      * something more efficient for that field.
   3789      * <p>
   3790      * @param field The calendar field whose value should be pinned.
   3791      *
   3792      * @see #getActualMinimum
   3793      * @see #getActualMaximum
   3794      * @stable ICU 2.0
   3795      */
   3796     protected void pinField(int field) {
   3797         int max = getActualMaximum(field);
   3798         int min = getActualMinimum(field);
   3799 
   3800         if (fields[field] > max) {
   3801             set(field, max);
   3802         } else if (fields[field] < min) {
   3803             set(field, min);
   3804         }
   3805     }
   3806 
   3807     /**
   3808      * Returns the week number of a day, within a period. This may be the week number in
   3809      * a year or the week number in a month. Usually this will be a value >= 1, but if
   3810      * some initial days of the period are excluded from week 1, because
   3811      * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} is > 1, then
   3812      * the week number will be zero for those
   3813      * initial days. This method requires the day number and day of week for some
   3814      * known date in the period in order to determine the day of week
   3815      * on the desired day.
   3816      * <p>
   3817      * <b>Subclassing:</b>
   3818      * <br>
   3819      * This method is intended for use by subclasses in implementing their
   3820      * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods.
   3821      * It is often useful in {@link #getActualMinimum getActualMinimum} and
   3822      * {@link #getActualMaximum getActualMaximum} as well.
   3823      * <p>
   3824      * This variant is handy for computing the week number of some other
   3825      * day of a period (often the first or last day of the period) when its day
   3826      * of the week is not known but the day number and day of week for some other
   3827      * day in the period (e.g. the current date) <em>is</em> known.
   3828      * <p>
   3829      * @param desiredDay    The {@link #DAY_OF_YEAR DAY_OF_YEAR} or
   3830      *              {@link #DAY_OF_MONTH DAY_OF_MONTH} whose week number is desired.
   3831      *              Should be 1 for the first day of the period.
   3832      *
   3833      * @param dayOfPeriod   The {@link #DAY_OF_YEAR DAY_OF_YEAR}
   3834      *              or {@link #DAY_OF_MONTH DAY_OF_MONTH} for a day in the period whose
   3835      *              {@link #DAY_OF_WEEK DAY_OF_WEEK} is specified by the
   3836      *              <code>dayOfWeek</code> parameter.
   3837      *              Should be 1 for first day of period.
   3838      *
   3839      * @param dayOfWeek  The {@link #DAY_OF_WEEK DAY_OF_WEEK} for the day
   3840      *              corresponding to the <code>dayOfPeriod</code> parameter.
   3841      *              1-based with 1=Sunday.
   3842      *
   3843      * @return      The week number (one-based), or zero if the day falls before
   3844      *              the first week because
   3845      *              {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
   3846      *              is more than one.
   3847      * @stable ICU 2.0
   3848      */
   3849     protected int weekNumber(int desiredDay, int dayOfPeriod, int dayOfWeek)
   3850     {
   3851         // Determine the day of the week of the first day of the period
   3852         // in question (either a year or a month).  Zero represents the
   3853         // first day of the week on this calendar.
   3854         int periodStartDayOfWeek = (dayOfWeek - getFirstDayOfWeek() - dayOfPeriod + 1) % 7;
   3855         if (periodStartDayOfWeek < 0) periodStartDayOfWeek += 7;
   3856 
   3857         // Compute the week number.  Initially, ignore the first week, which
   3858         // may be fractional (or may not be).  We add periodStartDayOfWeek in
   3859         // order to fill out the first week, if it is fractional.
   3860         int weekNo = (desiredDay + periodStartDayOfWeek - 1)/7;
   3861 
   3862         // If the first week is long enough, then count it.  If
   3863         // the minimal days in the first week is one, or if the period start
   3864         // is zero, we always increment weekNo.
   3865         if ((7 - periodStartDayOfWeek) >= getMinimalDaysInFirstWeek()) ++weekNo;
   3866 
   3867         return weekNo;
   3868     }
   3869 
   3870     /**
   3871      * Returns the week number of a day, within a period. This may be the week number in
   3872      * a year, or the week number in a month. Usually this will be a value >= 1, but if
   3873      * some initial days of the period are excluded from week 1, because
   3874      * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} is > 1,
   3875      * then the week number will be zero for those
   3876      * initial days. This method requires the day of week for the given date in order to
   3877      * determine the result.
   3878      * <p>
   3879      * <b>Subclassing:</b>
   3880      * <br>
   3881      * This method is intended for use by subclasses in implementing their
   3882      * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods.
   3883      * It is often useful in {@link #getActualMinimum getActualMinimum} and
   3884      * {@link #getActualMaximum getActualMaximum} as well.
   3885      * <p>
   3886      * @param dayOfPeriod   The {@link #DAY_OF_YEAR DAY_OF_YEAR} or
   3887      *                      {@link #DAY_OF_MONTH DAY_OF_MONTH} whose week number is desired.
   3888      *                      Should be 1 for the first day of the period.
   3889      *
   3890      * @param dayOfWeek     The {@link #DAY_OF_WEEK DAY_OF_WEEK} for the day
   3891      *                      corresponding to the <code>dayOfPeriod</code> parameter.
   3892      *                      1-based with 1=Sunday.
   3893      *
   3894      * @return      The week number (one-based), or zero if the day falls before
   3895      *              the first week because
   3896      *              {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
   3897      *              is more than one.
   3898      * @stable ICU 2.0
   3899      */
   3900     protected final int weekNumber(int dayOfPeriod, int dayOfWeek)
   3901     {
   3902         return weekNumber(dayOfPeriod, dayOfPeriod, dayOfWeek);
   3903     }
   3904 
   3905     //-------------------------------------------------------------------------
   3906     // Constants
   3907     //-------------------------------------------------------------------------
   3908 
   3909     private static final int FIELD_DIFF_MAX_INT = Integer.MAX_VALUE;    // 2147483647
   3910 
   3911     /**
   3912      * {@icu} Returns the difference between the given time and the time this
   3913      * calendar object is set to.  If this calendar is set
   3914      * <em>before</em> the given time, the returned value will be
   3915      * positive.  If this calendar is set <em>after</em> the given
   3916      * time, the returned value will be negative.  The
   3917      * <code>field</code> parameter specifies the units of the return
   3918      * value.  For example, if <code>fieldDifference(when,
   3919      * Calendar.MONTH)</code> returns 3, then this calendar is set to
   3920      * 3 months before <code>when</code>, and possibly some additional
   3921      * time less than one month.
   3922      *
   3923      * <p>As a side effect of this call, this calendar is advanced
   3924      * toward <code>when</code> by the given amount.  That is, calling
   3925      * this method has the side effect of calling <code>add(field,
   3926      * n)</code>, where <code>n</code> is the return value.
   3927      *
   3928      * <p>Usage: To use this method, call it first with the largest
   3929      * field of interest, then with progressively smaller fields.  For
   3930      * example:
   3931      *
   3932      * <pre>
   3933      * int y = cal.fieldDifference(when, Calendar.YEAR);
   3934      * int m = cal.fieldDifference(when, Calendar.MONTH);
   3935      * int d = cal.fieldDifference(when, Calendar.DATE);</pre>
   3936      *
   3937      * computes the difference between <code>cal</code> and
   3938      * <code>when</code> in years, months, and days.
   3939      *
   3940      * <p>Note: <code>fieldDifference()</code> is
   3941      * <em>asymmetrical</em>.  That is, in the following code:
   3942      *
   3943      * <pre>
   3944      * cal.setTime(date1);
   3945      * int m1 = cal.fieldDifference(date2, Calendar.MONTH);
   3946      * int d1 = cal.fieldDifference(date2, Calendar.DATE);
   3947      * cal.setTime(date2);
   3948      * int m2 = cal.fieldDifference(date1, Calendar.MONTH);
   3949      * int d2 = cal.fieldDifference(date1, Calendar.DATE);</pre>
   3950      *
   3951      * one might expect that <code>m1 == -m2 && d1 == -d2</code>.
   3952      * However, this is not generally the case, because of
   3953      * irregularities in the underlying calendar system (e.g., the
   3954      * Gregorian calendar has a varying number of days per month).
   3955      *
   3956      * @param when the date to compare this calendar's time to
   3957      * @param field the field in which to compute the result
   3958      * @return the difference, either positive or negative, between
   3959      * this calendar's time and <code>when</code>, in terms of
   3960      * <code>field</code>.
   3961      * @stable ICU 2.0
   3962      */
   3963     public int fieldDifference(Date when, int field) {
   3964         int min = 0;
   3965         long startMs = getTimeInMillis();
   3966         long targetMs = when.getTime();
   3967         // Always add from the start millis.  This accomodates
   3968         // operations like adding years from February 29, 2000 up to
   3969         // February 29, 2004.  If 1, 1, 1, 1 is added to the year
   3970         // field, the DOM gets pinned to 28 and stays there, giving an
   3971         // incorrect DOM difference of 1.  We have to add 1, reset, 2,
   3972         // reset, 3, reset, 4.
   3973         if (startMs < targetMs) {
   3974             int max = 1;
   3975             // Find a value that is too large
   3976             for (;;) {
   3977                 setTimeInMillis(startMs);
   3978                 add(field, max);
   3979                 long ms = getTimeInMillis();
   3980                 if (ms == targetMs) {
   3981                     return max;
   3982                 } else if (ms > targetMs) {
   3983                     break;
   3984                 } else if (max < FIELD_DIFF_MAX_INT) {
   3985                     min = max;
   3986                     max <<= 1;
   3987                     if (max < 0) {
   3988                         max = FIELD_DIFF_MAX_INT;
   3989                     }
   3990                 } else {
   3991                     // Field difference too large to fit into int
   3992                     throw new RuntimeException();
   3993                 }
   3994             }
   3995             // Do a binary search
   3996             while ((max - min) > 1) {
   3997                 int t = min + (max - min)/2; // make sure intermediate values don't exceed FIELD_DIFF_MAX_INT
   3998                 setTimeInMillis(startMs);
   3999                 add(field, t);
   4000                 long ms = getTimeInMillis();
   4001                 if (ms == targetMs) {
   4002                     return t;
   4003                 } else if (ms > targetMs) {
   4004                     max = t;
   4005                 } else {
   4006                     min = t;
   4007                 }
   4008             }
   4009         } else if (startMs > targetMs) {
   4010             //Eclipse stated the following is "dead code"
   4011             /*if (false) {
   4012                 // This works, and makes the code smaller, but costs
   4013                 // an extra object creation and an extra couple cycles
   4014                 // of calendar computation.
   4015                 setTimeInMillis(targetMs);
   4016                 min = -fieldDifference(new Date(startMs), field);
   4017             }*/
   4018             int max = -1;
   4019             // Find a value that is too small
   4020             for (;;) {
   4021                 setTimeInMillis(startMs);
   4022                 add(field, max);
   4023                 long ms = getTimeInMillis();
   4024                 if (ms == targetMs) {
   4025                     return max;
   4026                 } else if (ms < targetMs) {
   4027                     break;
   4028                 } else {
   4029                     min = max;
   4030                     max <<= 1;
   4031                     if (max == 0) {
   4032                         // Field difference too large to fit into int
   4033                         throw new RuntimeException();
   4034                     }
   4035                 }
   4036             }
   4037             // Do a binary search
   4038             while ((min - max) > 1) {
   4039                 int t = min + (max - min)/2; // make sure intermediate values don't exceed FIELD_DIFF_MAX_INT
   4040                 setTimeInMillis(startMs);
   4041                 add(field, t);
   4042                 long ms = getTimeInMillis();
   4043                 if (ms == targetMs) {
   4044                     return t;
   4045                 } else if (ms < targetMs) {
   4046                     max = t;
   4047                 } else {
   4048                     min = t;
   4049                 }
   4050             }
   4051         }
   4052         // Set calendar to end point
   4053         setTimeInMillis(startMs);
   4054         add(field, min);
   4055         return min;
   4056     }
   4057 
   4058     /**
   4059      * Sets the time zone with the given time zone value.
   4060      * @param value the given time zone.
   4061      * @stable ICU 2.0
   4062      */
   4063     public void setTimeZone(TimeZone value)
   4064     {
   4065         zone = value;
   4066         /* Recompute the fields from the time using the new zone.  This also
   4067          * works if isTimeSet is false (after a call to set()).  In that case
   4068          * the time will be computed from the fields using the new zone, then
   4069          * the fields will get recomputed from that.  Consider the sequence of
   4070          * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST).
   4071          * Is cal set to 1 o'clock EST or 1 o'clock PST?  Answer: PST.  More
   4072          * generally, a call to setTimeZone() affects calls to set() BEFORE AND
   4073          * AFTER it up to the next call to complete().
   4074          */
   4075         areFieldsSet = false;
   4076     }
   4077 
   4078     /**
   4079      * Returns the time zone.
   4080      * @return the time zone object associated with this calendar.
   4081      * @stable ICU 2.0
   4082      */
   4083     public TimeZone getTimeZone()
   4084     {
   4085         return zone;
   4086     }
   4087 
   4088     /**
   4089      * Specify whether or not date/time interpretation is to be lenient.  With
   4090      * lenient interpretation, a date such as "February 942, 1996" will be
   4091      * treated as being equivalent to the 941st day after February 1, 1996.
   4092      * With strict interpretation, such dates will cause an exception to be
   4093      * thrown.
   4094      *
   4095      * @see DateFormat#setLenient
   4096      * @stable ICU 2.0
   4097      */
   4098     public void setLenient(boolean lenient)
   4099     {
   4100         this.lenient = lenient;
   4101     }
   4102 
   4103     /**
   4104      * Tell whether date/time interpretation is to be lenient.
   4105      * @stable ICU 2.0
   4106      */
   4107     public boolean isLenient()
   4108     {
   4109         return lenient;
   4110     }
   4111 
   4112     /**
   4113      * {@icu}Sets the behavior for handling wall time repeating multiple times
   4114      * at negative time zone offset transitions. For example, 1:30 AM on
   4115      * November 6, 2011 in US Eastern time (Ameirca/New_York) occurs twice;
   4116      * 1:30 AM EDT, then 1:30 AM EST one hour later. When <code>WALLTIME_FIRST</code>
   4117      * is used, the wall time 1:30AM in this example will be interpreted as 1:30 AM EDT
   4118      * (first occurrence). When <code>WALLTIME_LAST</code> is used, it will be
   4119      * interpreted as 1:30 AM EST (last occurrence). The default value is
   4120      * <code>WALLTIME_LAST</code>.
   4121      *
   4122      * @param option the behavior for handling repeating wall time, either
   4123      * <code>WALLTIME_FIRST</code> or <code>WALLTIME_LAST</code>.
   4124      * @throws IllegalArgumentException when <code>option</code> is neither
   4125      * <code>WALLTIME_FIRST</code> nor <code>WALLTIME_LAST</code>.
   4126      *
   4127      * @see #getRepeatedWallTimeOption()
   4128      * @see #WALLTIME_FIRST
   4129      * @see #WALLTIME_LAST
   4130      *
   4131      * @stable ICU 49
   4132      */
   4133     public void setRepeatedWallTimeOption(int option) {
   4134         if (option != WALLTIME_LAST && option != WALLTIME_FIRST) {
   4135             throw new IllegalArgumentException("Illegal repeated wall time option - " + option);
   4136         }
   4137         repeatedWallTime = option;
   4138     }
   4139 
   4140     /**
   4141      * {@icu}Gets the behavior for handling wall time repeating multiple times
   4142      * at negative time zone offset transitions.
   4143      *
   4144      * @return the behavior for handling repeating wall time, either
   4145      * <code>WALLTIME_FIRST</code> or <code>WALLTIME_LAST</code>.
   4146      *
   4147      * @see #setRepeatedWallTimeOption(int)
   4148      * @see #WALLTIME_FIRST
   4149      * @see #WALLTIME_LAST
   4150      *
   4151      * @stable ICU 49
   4152      */
   4153     public int getRepeatedWallTimeOption() {
   4154         return repeatedWallTime;
   4155     }
   4156 
   4157     /**
   4158      * {@icu}Sets the behavior for handling skipped wall time at positive time zone offset
   4159      * transitions. For example, 2:30 AM on March 13, 2011 in US Eastern time (America/New_York)
   4160      * does not exist because the wall time jump from 1:59 AM EST to 3:00 AM EDT. When
   4161      * <code>WALLTIME_FIRST</code> is used, 2:30 AM is interpreted as 30 minutes before 3:00 AM
   4162      * EDT, therefore, it will be resolved as 1:30 AM EST. When <code>WALLTIME_LAST</code>
   4163      * is used, 2:30 AM is interpreted as 31 minutes after 1:59 AM EST, therefore, it will be
   4164      * resolved as 3:30 AM EDT. When <code>WALLTIME_NEXT_VALID</code> is used, 2:30 AM will
   4165      * be resolved as next valid wall time, that is 3:00 AM EDT. The default value is
   4166      * <code>WALLTIME_LAST</code>.
   4167      * <p>
   4168      * <b>Note:</b>This option is effective only when this calendar is {@link #isLenient() lenient}.
   4169      * When the calendar is strict, such non-existing wall time will cause an exception.
   4170      *
   4171      * @param option the behavior for handling skipped wall time at positive time zone
   4172      * offset transitions, one of <code>WALLTIME_FIRST</code>, <code>WALLTIME_LAST</code> and
   4173      * <code>WALLTIME_NEXT_VALID</code>.
   4174      * @throws IllegalArgumentException when <code>option</code> is not any of
   4175      * <code>WALLTIME_FIRST</code>, <code>WALLTIME_LAST</code> and <code>WALLTIME_NEXT_VALID</code>.
   4176      *
   4177      * @see #getSkippedWallTimeOption()
   4178      * @see #WALLTIME_FIRST
   4179      * @see #WALLTIME_LAST
   4180      * @see #WALLTIME_NEXT_VALID
   4181      *
   4182      * @stable ICU 49
   4183      */
   4184     public void setSkippedWallTimeOption(int option) {
   4185         if (option != WALLTIME_LAST && option != WALLTIME_FIRST && option != WALLTIME_NEXT_VALID) {
   4186             throw new IllegalArgumentException("Illegal skipped wall time option - " + option);
   4187         }
   4188         skippedWallTime = option;
   4189     }
   4190 
   4191     /**
   4192      * {@icu}Gets the behavior for handling skipped wall time at positive time zone offset
   4193      * transitions.
   4194      *
   4195      * @return the behavior for handling skipped wall time, one of
   4196      * <code>WALLTIME_FIRST</code>, <code>WALLTIME_LAST</code> and <code>WALLTIME_NEXT_VALID</code>.
   4197      *
   4198      * @see #setSkippedWallTimeOption(int)
   4199      * @see #WALLTIME_FIRST
   4200      * @see #WALLTIME_LAST
   4201      * @see #WALLTIME_NEXT_VALID
   4202      *
   4203      * @stable ICU 49
   4204      */
   4205     public int getSkippedWallTimeOption() {
   4206         return skippedWallTime;
   4207     }
   4208 
   4209     /**
   4210      * Sets what the first day of the week is,
   4211      * where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}.
   4212      * @param value the given first day of the week, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}.
   4213      * @stable ICU 2.0
   4214      */
   4215     public void setFirstDayOfWeek(int value)
   4216     {
   4217         if (firstDayOfWeek != value) {
   4218             if (value < SUNDAY || value > SATURDAY) {
   4219                 throw new IllegalArgumentException("Invalid day of week");
   4220             }
   4221             firstDayOfWeek = value;
   4222             areFieldsSet = false;
   4223         }
   4224     }
   4225 
   4226     /**
   4227      * Returns what the first day of the week is,
   4228      * where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}.
   4229      * e.g., Sunday in US, Monday in France
   4230      * @return the first day of the week, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}.
   4231      * @stable ICU 2.0
   4232      */
   4233     public int getFirstDayOfWeek()
   4234     {
   4235         return firstDayOfWeek;
   4236     }
   4237 
   4238     /**
   4239      * Sets what the minimal days required in the first week of the year are.
   4240      * For example, if the first week is defined as one that contains the first
   4241      * day of the first month of a year, call the method with value 1. If it
   4242      * must be a full week, use value 7.
   4243      * @param value the given minimal days required in the first week
   4244      * of the year.
   4245      * @stable ICU 2.0
   4246      */
   4247     public void setMinimalDaysInFirstWeek(int value)
   4248     {
   4249         // Values less than 1 have the same effect as 1; values greater
   4250         // than 7 have the same effect as 7. However, we normalize values
   4251         // so operator== and so forth work.
   4252         if (value < 1) {
   4253             value = 1;
   4254         } else if (value > 7) {
   4255             value = 7;
   4256         }
   4257         if (minimalDaysInFirstWeek != value) {
   4258             minimalDaysInFirstWeek = value;
   4259             areFieldsSet = false;
   4260         }
   4261     }
   4262 
   4263     /**
   4264      * Returns what the minimal days required in the first week of the year are.
   4265      * That is, if the first week is defined as one that contains the first day
   4266      * of the first month of a year, getMinimalDaysInFirstWeek returns 1. If
   4267      * the minimal days required must be a full week, getMinimalDaysInFirstWeek
   4268      * returns 7.
   4269      * @return the minimal days required in the first week of the year.
   4270      * @stable ICU 2.0
   4271      */
   4272     public int getMinimalDaysInFirstWeek()
   4273     {
   4274         return minimalDaysInFirstWeek;
   4275     }
   4276 
   4277     private static final int LIMITS[][] = {
   4278         //    Minimum  Greatest min      Least max   Greatest max
   4279         {/*                                                      */}, // ERA
   4280         {/*                                                      */}, // YEAR
   4281         {/*                                                      */}, // MONTH
   4282         {/*                                                      */}, // WEEK_OF_YEAR
   4283         {/*                                                      */}, // WEEK_OF_MONTH
   4284         {/*                                                      */}, // DAY_OF_MONTH
   4285         {/*                                                      */}, // DAY_OF_YEAR
   4286         {           1,            1,             7,             7  }, // DAY_OF_WEEK
   4287         {/*                                                      */}, // DAY_OF_WEEK_IN_MONTH
   4288         {           0,            0,             1,             1  }, // AM_PM
   4289         {           0,            0,            11,            11  }, // HOUR
   4290         {           0,            0,            23,            23  }, // HOUR_OF_DAY
   4291         {           0,            0,            59,            59  }, // MINUTE
   4292         {           0,            0,            59,            59  }, // SECOND
   4293         {           0,            0,           999,           999  }, // MILLISECOND
   4294         {-12*ONE_HOUR, -12*ONE_HOUR,   12*ONE_HOUR,   12*ONE_HOUR  }, // ZONE_OFFSET
   4295         {           0,            0,    1*ONE_HOUR,    1*ONE_HOUR  }, // DST_OFFSET
   4296         {/*                                                      */}, // YEAR_WOY
   4297         {           1,            1,             7,             7  }, // DOW_LOCAL
   4298         {/*                                                      */}, // EXTENDED_YEAR
   4299         { -0x7F000000,  -0x7F000000,    0x7F000000,    0x7F000000  }, // JULIAN_DAY
   4300         {           0,            0, 24*ONE_HOUR-1, 24*ONE_HOUR-1  }, // MILLISECONDS_IN_DAY
   4301         {           0,            0,             1,             1  }, // IS_LEAP_MONTH
   4302     };
   4303 
   4304     /**
   4305      * Subclass API for defining limits of different types.
   4306      * Subclasses must implement this method to return limits for the
   4307      * following fields:
   4308      *
   4309      * <pre>ERA
   4310      * YEAR
   4311      * MONTH
   4312      * WEEK_OF_YEAR
   4313      * WEEK_OF_MONTH
   4314      * DAY_OF_MONTH
   4315      * DAY_OF_YEAR
   4316      * DAY_OF_WEEK_IN_MONTH
   4317      * YEAR_WOY
   4318      * EXTENDED_YEAR</pre>
   4319      *
   4320      * @param field one of the above field numbers
   4321      * @param limitType one of <code>MINIMUM</code>, <code>GREATEST_MINIMUM</code>,
   4322      * <code>LEAST_MAXIMUM</code>, or <code>MAXIMUM</code>
   4323      * @stable ICU 2.0
   4324      */
   4325     abstract protected int handleGetLimit(int field, int limitType);
   4326 
   4327     /**
   4328      * Returns a limit for a field.
   4329      * @param field the field, from 0..</code>getFieldCount()-1</code>
   4330      * @param limitType the type specifier for the limit
   4331      * @see #MINIMUM
   4332      * @see #GREATEST_MINIMUM
   4333      * @see #LEAST_MAXIMUM
   4334      * @see #MAXIMUM
   4335      * @stable ICU 2.0
   4336      */
   4337     protected int getLimit(int field, int limitType) {
   4338         switch (field) {
   4339         case DAY_OF_WEEK:
   4340         case AM_PM:
   4341         case HOUR:
   4342         case HOUR_OF_DAY:
   4343         case MINUTE:
   4344         case SECOND:
   4345         case MILLISECOND:
   4346         case ZONE_OFFSET:
   4347         case DST_OFFSET:
   4348         case DOW_LOCAL:
   4349         case JULIAN_DAY:
   4350         case MILLISECONDS_IN_DAY:
   4351         case IS_LEAP_MONTH:
   4352             return LIMITS[field][limitType];
   4353 
   4354         case WEEK_OF_MONTH:
   4355         {
   4356             int limit;
   4357             if (limitType == MINIMUM) {
   4358                 limit = getMinimalDaysInFirstWeek() == 1 ? 1 : 0;
   4359             } else if (limitType == GREATEST_MINIMUM){
   4360                 limit = 1;
   4361             } else {
   4362                 int minDaysInFirst = getMinimalDaysInFirstWeek();
   4363                 int daysInMonth = handleGetLimit(DAY_OF_MONTH, limitType);
   4364                 if (limitType == LEAST_MAXIMUM) {
   4365                     limit = (daysInMonth + (7 - minDaysInFirst)) / 7;
   4366                 } else { // limitType == MAXIMUM
   4367                     limit = (daysInMonth + 6 + (7 - minDaysInFirst)) / 7;
   4368                 }
   4369             }
   4370             return limit;
   4371         }
   4372 
   4373         }
   4374         return handleGetLimit(field, limitType);
   4375     }
   4376 
   4377     /**
   4378      * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code>
   4379      * indicating the minimum value that a field can take (least minimum).
   4380      * @see #getLimit
   4381      * @see #handleGetLimit
   4382      * @stable ICU 2.0
   4383      */
   4384     protected static final int MINIMUM = 0;
   4385 
   4386     /**
   4387      * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code>
   4388      * indicating the greatest minimum value that a field can take.
   4389      * @see #getLimit
   4390      * @see #handleGetLimit
   4391      * @stable ICU 2.0
   4392      */
   4393     protected static final int GREATEST_MINIMUM = 1;
   4394 
   4395     /**
   4396      * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code>
   4397      * indicating the least maximum value that a field can take.
   4398      * @see #getLimit
   4399      * @see #handleGetLimit
   4400      * @stable ICU 2.0
   4401      */
   4402     protected static final int LEAST_MAXIMUM = 2;
   4403 
   4404     /**
   4405      * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code>
   4406      * indicating the maximum value that a field can take (greatest maximum).
   4407      * @see #getLimit
   4408      * @see #handleGetLimit
   4409      * @stable ICU 2.0
   4410      */
   4411     protected static final int MAXIMUM = 3;
   4412 
   4413     /**
   4414      * Returns the minimum value for the given time field.
   4415      * e.g., for Gregorian DAY_OF_MONTH, 1.
   4416      * @param field the given time field.
   4417      * @return the minimum value for the given time field.
   4418      * @stable ICU 2.0
   4419      */
   4420     public final int getMinimum(int field) {
   4421         return getLimit(field, MINIMUM);
   4422     }
   4423 
   4424     /**
   4425      * Returns the maximum value for the given time field.
   4426      * e.g. for Gregorian DAY_OF_MONTH, 31.
   4427      * @param field the given time field.
   4428      * @return the maximum value for the given time field.
   4429      * @stable ICU 2.0
   4430      */
   4431     public final int getMaximum(int field) {
   4432         return getLimit(field, MAXIMUM);
   4433     }
   4434 
   4435     /**
   4436      * Returns the highest minimum value for the given field if varies.
   4437      * Otherwise same as getMinimum(). For Gregorian, no difference.
   4438      * @param field the given time field.
   4439      * @return the highest minimum value for the given time field.
   4440      * @stable ICU 2.0
   4441      */
   4442     public final int getGreatestMinimum(int field) {
   4443         return getLimit(field, GREATEST_MINIMUM);
   4444     }
   4445 
   4446     /**
   4447      * Returns the lowest maximum value for the given field if varies.
   4448      * Otherwise same as getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28.
   4449      * @param field the given time field.
   4450      * @return the lowest maximum value for the given time field.
   4451      * @stable ICU 2.0
   4452      */
   4453     public final int getLeastMaximum(int field) {
   4454         return getLimit(field, LEAST_MAXIMUM);
   4455     }
   4456 
   4457     //-------------------------------------------------------------------------
   4458     // Weekend support -- determining which days of the week are the weekend
   4459     // in a given locale
   4460     //-------------------------------------------------------------------------
   4461 
   4462     /**
   4463      * {@icu} Returns whether the given day of the week is a weekday, a
   4464      * weekend day, or a day that transitions from one to the other, for the
   4465      * locale and calendar system associated with this Calendar (the locale's
   4466      * region is often the most determinant factor). If a transition occurs at
   4467      * midnight, then the days before and after the transition will have the
   4468      * type WEEKDAY or WEEKEND.  If a transition occurs at a time
   4469      * other than midnight, then the day of the transition will have
   4470      * the type WEEKEND_ONSET or WEEKEND_CEASE.  In this case, the
   4471      * method getWeekendTransition() will return the point of
   4472      * transition.
   4473      * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
   4474      * THURSDAY, FRIDAY, or SATURDAY
   4475      * @return either WEEKDAY, WEEKEND, WEEKEND_ONSET, or
   4476      * WEEKEND_CEASE
   4477      * @exception IllegalArgumentException if dayOfWeek is not
   4478      * between SUNDAY and SATURDAY, inclusive
   4479      * @see #WEEKDAY
   4480      * @see #WEEKEND
   4481      * @see #WEEKEND_ONSET
   4482      * @see #WEEKEND_CEASE
   4483      * @see #getWeekendTransition
   4484      * @see #isWeekend(Date)
   4485      * @see #isWeekend()
   4486      * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)}
   4487      */
   4488     @Deprecated
   4489     public int getDayOfWeekType(int dayOfWeek) {
   4490         if (dayOfWeek < SUNDAY || dayOfWeek > SATURDAY) {
   4491             throw new IllegalArgumentException("Invalid day of week");
   4492         }
   4493         if (weekendOnset == weekendCease) {
   4494             if (dayOfWeek != weekendOnset)
   4495                 return WEEKDAY;
   4496             return (weekendOnsetMillis == 0) ? WEEKEND : WEEKEND_ONSET;
   4497         }
   4498         if (weekendOnset < weekendCease) {
   4499             if (dayOfWeek < weekendOnset || dayOfWeek > weekendCease) {
   4500                 return WEEKDAY;
   4501             }
   4502         } else {
   4503             if (dayOfWeek > weekendCease && dayOfWeek < weekendOnset) {
   4504                 return WEEKDAY;
   4505             }
   4506         }
   4507         if (dayOfWeek == weekendOnset) {
   4508             return (weekendOnsetMillis == 0) ? WEEKEND : WEEKEND_ONSET;
   4509         }
   4510         if (dayOfWeek == weekendCease) {
   4511             return (weekendCeaseMillis >= 86400000) ? WEEKEND : WEEKEND_CEASE;
   4512         }
   4513         return WEEKEND;
   4514     }
   4515 
   4516     /**
   4517      * {@icu} Returns the time during the day at which the weekend begins or end in this
   4518      * calendar system.  If getDayOfWeekType(dayOfWeek) == WEEKEND_ONSET return the time
   4519      * at which the weekend begins.  If getDayOfWeekType(dayOfWeek) == WEEKEND_CEASE
   4520      * return the time at which the weekend ends.  If getDayOfWeekType(dayOfWeek) has some
   4521      * other value, then throw an exception.
   4522      * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
   4523      * THURSDAY, FRIDAY, or SATURDAY
   4524      * @return the milliseconds after midnight at which the
   4525      * weekend begins or ends
   4526      * @exception IllegalArgumentException if dayOfWeek is not
   4527      * WEEKEND_ONSET or WEEKEND_CEASE
   4528      * @see #getDayOfWeekType
   4529      * @see #isWeekend(Date)
   4530      * @see #isWeekend()
   4531      * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)}
   4532      */
   4533     @Deprecated
   4534     public int getWeekendTransition(int dayOfWeek) {
   4535         if (dayOfWeek == weekendOnset) {
   4536             return weekendOnsetMillis;
   4537         } else if (dayOfWeek == weekendCease) {
   4538             return weekendCeaseMillis;
   4539         }
   4540         throw new IllegalArgumentException("Not weekend transition day");
   4541     }
   4542 
   4543     /**
   4544      * {@icu} Returns true if the given date and time is in the weekend in this calendar
   4545      * system.  Equivalent to calling setTime() followed by isWeekend().  Note: This
   4546      * method changes the time this calendar is set to.
   4547      * @param date the date and time
   4548      * @return true if the given date and time is part of the
   4549      * weekend
   4550      * @see #getDayOfWeekType
   4551      * @see #getWeekendTransition
   4552      * @see #isWeekend()
   4553      * @stable ICU 2.0
   4554      */
   4555     public boolean isWeekend(Date date) {
   4556         setTime(date);
   4557         return isWeekend();
   4558     }
   4559 
   4560     /**
   4561      * {@icu} Returns true if this Calendar's current date and time is in the weekend in
   4562      * this calendar system.
   4563      * @return true if the given date and time is part of the
   4564      * weekend
   4565      * @see #getDayOfWeekType
   4566      * @see #getWeekendTransition
   4567      * @see #isWeekend(Date)
   4568      * @stable ICU 2.0
   4569      */
   4570     public boolean isWeekend() {
   4571         int dow =  get(DAY_OF_WEEK);
   4572         int dowt = getDayOfWeekType(dow);
   4573         switch (dowt) {
   4574         case WEEKDAY:
   4575             return false;
   4576         case WEEKEND:
   4577             return true;
   4578         default: // That is, WEEKEND_ONSET or WEEKEND_CEASE
   4579             // Use internalGet() because the above call to get() populated
   4580             // all fields.
   4581             // [Note: There should be a better way to get millis in day.
   4582             //  For ICU4J, submit request for a MILLIS_IN_DAY field
   4583             //  and a DAY_NUMBER field (could be Julian day #). - aliu]
   4584             int millisInDay = internalGet(MILLISECOND) + 1000 * (internalGet(SECOND) +
   4585                     60 * (internalGet(MINUTE) + 60 * internalGet(HOUR_OF_DAY)));
   4586             int transition = getWeekendTransition(dow);
   4587             return (dowt == WEEKEND_ONSET)
   4588                     ? (millisInDay >= transition)
   4589                             : (millisInDay <  transition);
   4590         }
   4591         // (We can never reach this point.)
   4592     }
   4593 
   4594     //-------------------------------------------------------------------------
   4595     // End of weekend support
   4596     //-------------------------------------------------------------------------
   4597 
   4598     /**
   4599      * Overrides Cloneable
   4600      * @stable ICU 2.0
   4601      */
   4602     public Object clone()
   4603     {
   4604         try {
   4605             Calendar other = (Calendar) super.clone();
   4606 
   4607             other.fields = new int[fields.length];
   4608             other.stamp = new int[fields.length];
   4609             System.arraycopy(this.fields, 0, other.fields, 0, fields.length);
   4610             System.arraycopy(this.stamp, 0, other.stamp, 0, fields.length);
   4611 
   4612             other.zone = (TimeZone) zone.clone();
   4613             return other;
   4614         }
   4615         catch (CloneNotSupportedException e) {
   4616             // this shouldn't happen, since we are Cloneable
   4617             throw new ICUCloneNotSupportedException(e);
   4618         }
   4619     }
   4620 
   4621     /**
   4622      * Returns a string representation of this calendar. This method
   4623      * is intended to be used only for debugging purposes, and the
   4624      * format of the returned string may vary between implementations.
   4625      * The returned string may be empty but may not be <code>null</code>.
   4626      *
   4627      * @return  a string representation of this calendar.
   4628      * @stable ICU 2.0
   4629      */
   4630     public String toString() {
   4631         StringBuilder buffer = new StringBuilder();
   4632         buffer.append(getClass().getName());
   4633         buffer.append("[time=");
   4634         buffer.append(isTimeSet ? String.valueOf(time) : "?");
   4635         buffer.append(",areFieldsSet=");
   4636         buffer.append(areFieldsSet);
   4637         buffer.append(",areAllFieldsSet=");
   4638         buffer.append(areAllFieldsSet);
   4639         buffer.append(",lenient=");
   4640         buffer.append(lenient);
   4641         buffer.append(",zone=");
   4642         buffer.append(zone);
   4643         buffer.append(",firstDayOfWeek=");
   4644         buffer.append(firstDayOfWeek);
   4645         buffer.append(",minimalDaysInFirstWeek=");
   4646         buffer.append(minimalDaysInFirstWeek);
   4647         buffer.append(",repeatedWallTime=");
   4648         buffer.append(repeatedWallTime);
   4649         buffer.append(",skippedWallTime=");
   4650         buffer.append(skippedWallTime);
   4651         for (int i=0; i<fields.length; ++i) {
   4652             buffer.append(',').append(fieldName(i)).append('=');
   4653             buffer.append(isSet(i) ? String.valueOf(fields[i]) : "?");
   4654         }
   4655         buffer.append(']');
   4656         return buffer.toString();
   4657     }
   4658 
   4659     /**
   4660      * Simple, immutable struct-like class for access to the CLDR weekend data.
   4661      *
   4662      * @draft ICU 54
   4663      * @provisional This is a draft API and might change in a future release of ICU.
   4664      */
   4665     public static final class WeekData {
   4666         /**
   4667          * the first day of the week, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}
   4668          *
   4669          * @draft ICU 54
   4670          * @provisional This is a draft API and might change in a future release of ICU.
   4671          */
   4672         public final int firstDayOfWeek;
   4673         /**
   4674          * the minimal number of days in the first week
   4675          *
   4676          * @draft ICU 54
   4677          * @provisional This is a draft API and might change in a future release of ICU.
   4678          */
   4679         public final int minimalDaysInFirstWeek;
   4680         /**
   4681          * the onset day, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}
   4682          *
   4683          * @draft ICU 54
   4684          * @provisional This is a draft API and might change in a future release of ICU.
   4685          */
   4686         public final int weekendOnset;
   4687         /**
   4688          * the onset time in millis during the onset day
   4689          *
   4690          * @draft ICU 54
   4691          * @provisional This is a draft API and might change in a future release of ICU.
   4692          */
   4693         public final int weekendOnsetMillis;
   4694         /**
   4695          * the cease day, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}
   4696          *
   4697          * @draft ICU 54
   4698          * @provisional This is a draft API and might change in a future release of ICU.
   4699          */
   4700         public final int weekendCease;
   4701         /**
   4702          * the cease time in millis during the cease day. Exclusive, so the max is 24:00:00.000.
   4703          * Note that this will format as 00:00 the next day.
   4704          *
   4705          * @draft ICU 54
   4706          * @provisional This is a draft API and might change in a future release of ICU.
   4707          */
   4708         public final int weekendCeaseMillis;
   4709 
   4710         /**
   4711          * Constructor
   4712          *
   4713          * @param fdow the first day of the week, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}
   4714          * @param mdifw the minimal number of days in the first week
   4715          * @param weekendOnset the onset day, where 1 = Sunday and 7 = Saturday
   4716          * @param weekendOnsetMillis the onset time in millis during the onset day
   4717          * @param weekendCease the cease day, where 1 = Sunday and 7 = Saturday
   4718          * @param weekendCeaseMillis the cease time in millis during the cease day.
   4719          *
   4720          * @draft ICU 54
   4721          * @provisional This is a draft API and might change in a future release of ICU.
   4722          */
   4723         public WeekData(int fdow, int mdifw,
   4724                 int weekendOnset, int weekendOnsetMillis,
   4725                 int weekendCease, int weekendCeaseMillis) {
   4726             this.firstDayOfWeek = fdow;
   4727             this.minimalDaysInFirstWeek = mdifw;
   4728             this.weekendOnset = weekendOnset;
   4729             this.weekendOnsetMillis = weekendOnsetMillis;
   4730             this.weekendCease = weekendCease;
   4731             this.weekendCeaseMillis = weekendCeaseMillis;
   4732         }
   4733 
   4734         /**
   4735          * {@inheritDoc}
   4736          *
   4737          * @draft ICU 54
   4738          * @provisional This is a draft API and might change in a future release of ICU.
   4739          */
   4740         @Override
   4741         public int hashCode() {
   4742             return ((((firstDayOfWeek * 37 + minimalDaysInFirstWeek) * 37 + weekendOnset) * 37
   4743                     + weekendOnsetMillis) * 37 + weekendCease) * 37 + weekendCeaseMillis;
   4744         }
   4745 
   4746         /**
   4747          * {@inheritDoc}
   4748          *
   4749          * @draft ICU 54
   4750          * @provisional This is a draft API and might change in a future release of ICU.
   4751          */
   4752         @Override
   4753         public boolean equals(Object other) {
   4754             if (this == other) {
   4755                 return true;
   4756             }
   4757             if (!(other instanceof WeekData)) {
   4758                 return false;
   4759             }
   4760             WeekData that = (WeekData) other;
   4761             return firstDayOfWeek == that.firstDayOfWeek
   4762                     && minimalDaysInFirstWeek == that.minimalDaysInFirstWeek
   4763                     && weekendOnset == that.weekendOnset
   4764                     && weekendOnsetMillis == that.weekendOnsetMillis
   4765                     && weekendCease == that.weekendCease
   4766                     && weekendCeaseMillis == that.weekendCeaseMillis;
   4767         }
   4768 
   4769         /**
   4770          * {@inheritDoc}
   4771          *
   4772          * @draft ICU 54
   4773          * @provisional This is a draft API and might change in a future release of ICU.
   4774          */
   4775         @Override
   4776         public String toString() {
   4777             return "{" + firstDayOfWeek
   4778                     + ", " + minimalDaysInFirstWeek
   4779                     + ", " + weekendOnset
   4780                     + ", " + weekendOnsetMillis
   4781                     + ", " + weekendCease
   4782                     + ", " + weekendCeaseMillis
   4783                     + "}";
   4784         }
   4785     }
   4786 
   4787     /**
   4788      * {@icu} Return simple, immutable struct-like class for access to the CLDR weekend data.
   4789      * @param region The input region. The results are undefined if the region code is not valid.
   4790      * @return the WeekData for the input region. It is never null.
   4791      *
   4792      * @draft ICU 54
   4793      * @provisional This is a draft API and might change in a future release of ICU.
   4794      */
   4795     public static WeekData getWeekDataForRegion(String region) {
   4796         return WEEK_DATA_CACHE.createInstance(region, region);
   4797     }
   4798 
   4799     /**
   4800      * {@icu} Return simple, immutable struct-like class for access to the weekend data in this calendar.
   4801      * @return the WeekData for this calendar.
   4802      *
   4803      * @draft ICU 54
   4804      * @provisional This is a draft API and might change in a future release of ICU.
   4805      */
   4806     public WeekData getWeekData() {
   4807         return new WeekData(firstDayOfWeek, minimalDaysInFirstWeek, weekendOnset, weekendOnsetMillis, weekendCease, weekendCeaseMillis);
   4808     }
   4809 
   4810     /**
   4811      * {@icu} Set data in this calendar based on the WeekData input.
   4812      * @param wdata The week data to use
   4813      * @return this, for chaining
   4814      *
   4815      * @draft ICU 54
   4816      * @provisional This is a draft API and might change in a future release of ICU.
   4817      */
   4818     public Calendar setWeekData(WeekData wdata) {
   4819         setFirstDayOfWeek(wdata.firstDayOfWeek);
   4820         setMinimalDaysInFirstWeek(wdata.minimalDaysInFirstWeek);
   4821 
   4822         weekendOnset       = wdata.weekendOnset;
   4823         weekendOnsetMillis = wdata.weekendOnsetMillis;
   4824         weekendCease       = wdata.weekendCease;
   4825         weekendCeaseMillis = wdata.weekendCeaseMillis;
   4826         return this;
   4827     }
   4828 
   4829     private static WeekData getWeekDataForRegionInternal(String region) {
   4830         if (region == null) {
   4831             region = "001";
   4832         }
   4833 
   4834         UResourceBundle rb = UResourceBundle.getBundleInstance(
   4835                 ICUResourceBundle.ICU_BASE_NAME,
   4836                 "supplementalData",
   4837                 ICUResourceBundle.ICU_DATA_CLASS_LOADER);
   4838         UResourceBundle weekDataInfo = rb.get("weekData");
   4839         UResourceBundle weekDataBundle = null;
   4840 
   4841         try {
   4842             weekDataBundle = weekDataInfo.get(region);
   4843         } catch (MissingResourceException mre) {
   4844             if (!region.equals("001")) {
   4845                 // use "001" as fallback
   4846                 weekDataBundle = weekDataInfo.get("001");
   4847             } else {
   4848                 throw mre;
   4849             }
   4850         }
   4851 
   4852         int[] wdi = weekDataBundle.getIntVector();
   4853         return new WeekData(wdi[0],wdi[1],wdi[2],wdi[3],wdi[4],wdi[5]);
   4854     }
   4855 
   4856     /*
   4857      * Cache to hold week data by region
   4858      */
   4859     private static class WeekDataCache extends SoftCache<String, WeekData, String> {
   4860 
   4861         /* (non-Javadoc)
   4862          * @see com.ibm.icu.impl.CacheBase#createInstance(java.lang.Object, java.lang.Object)
   4863          */
   4864         @Override
   4865         protected WeekData createInstance(String key, String data) {
   4866             return getWeekDataForRegionInternal(key);
   4867         }
   4868     }
   4869 
   4870     private static final WeekDataCache WEEK_DATA_CACHE = new WeekDataCache();
   4871 
   4872     /*
   4873      * Set this calendar to contain week and weekend data for the given region.
   4874      */
   4875     private void setWeekData(String region) {
   4876         if (region == null) {
   4877             region = "001";
   4878         }
   4879         WeekData wdata = WEEK_DATA_CACHE.getInstance(region, region);
   4880         setWeekData(wdata);
   4881     }
   4882 
   4883     /**
   4884      * Recompute the time and update the status fields isTimeSet
   4885      * and areFieldsSet.  Callers should check isTimeSet and only
   4886      * call this method if isTimeSet is false.
   4887      */
   4888     private void updateTime() {
   4889         computeTime();
   4890         // If we are lenient, we need to recompute the fields to normalize
   4891         // the values.  Also, if we haven't set all the fields yet (i.e.,
   4892         // in a newly-created object), we need to fill in the fields. [LIU]
   4893         if (isLenient() || !areAllFieldsSet) areFieldsSet = false;
   4894         isTimeSet = true;
   4895         areFieldsVirtuallySet = false;
   4896     }
   4897 
   4898     /**
   4899      * Save the state of this object to a stream (i.e., serialize it).
   4900      */
   4901     private void writeObject(ObjectOutputStream stream)
   4902             throws IOException
   4903             {
   4904         // Try to compute the time correctly, for the future (stream
   4905         // version 2) in which we don't write out fields[] or isSet[].
   4906         if (!isTimeSet) {
   4907             try {
   4908                 updateTime();
   4909             }
   4910             catch (IllegalArgumentException e) {}
   4911         }
   4912 
   4913         // Write out the 1.1 FCS object.
   4914         stream.defaultWriteObject();
   4915             }
   4916 
   4917     /**
   4918      * Reconstitute this object from a stream (i.e., deserialize it).
   4919      */
   4920     private void readObject(ObjectInputStream stream)
   4921             throws IOException, ClassNotFoundException {
   4922 
   4923         stream.defaultReadObject();
   4924 
   4925         initInternal();
   4926 
   4927         isTimeSet = true;
   4928         areFieldsSet = areAllFieldsSet = false;
   4929         areFieldsVirtuallySet = true; // cause fields to be recalculated if requested.
   4930         nextStamp = MINIMUM_USER_STAMP;
   4931     }
   4932 
   4933 
   4934     //----------------------------------------------------------------------
   4935     // Time -> Fields
   4936     //----------------------------------------------------------------------
   4937 
   4938     /**
   4939      * Converts the current millisecond time value <code>time</code> to
   4940      * field values in <code>fields[]</code>.  This synchronizes the time
   4941      * field values with a new time that is set for the calendar.  The time
   4942      * is <em>not</em> recomputed first; to recompute the time, then the
   4943      * fields, call the <code>complete</code> method.
   4944      * @see #complete
   4945      * @stable ICU 2.0
   4946      */
   4947     protected void computeFields() {
   4948         int offsets[] = new int[2];
   4949         getTimeZone().getOffset(time, false, offsets);
   4950         long localMillis = time + offsets[0] + offsets[1];
   4951 
   4952         // Mark fields as set.  Do this before calling handleComputeFields().
   4953         int mask = internalSetMask;
   4954         for (int i=0; i<fields.length; ++i) {
   4955             if ((mask & 1) == 0) {
   4956                 stamp[i] = INTERNALLY_SET;
   4957             } else {
   4958                 stamp[i] = UNSET;
   4959             }
   4960             mask >>= 1;
   4961         }
   4962 
   4963         // We used to check for and correct extreme millis values (near
   4964         // Long.MIN_VALUE or Long.MAX_VALUE) here.  Such values would cause
   4965         // overflows from positive to negative (or vice versa) and had to
   4966         // be manually tweaked.  We no longer need to do this because we
   4967         // have limited the range of supported dates to those that have a
   4968         // Julian day that fits into an int.  This allows us to implement a
   4969         // JULIAN_DAY field and also removes some inelegant code. - Liu
   4970         // 11/6/00
   4971 
   4972         long days = floorDivide(localMillis, ONE_DAY);
   4973 
   4974         fields[JULIAN_DAY] = (int) days + EPOCH_JULIAN_DAY;
   4975 
   4976         computeGregorianAndDOWFields(fields[JULIAN_DAY]);
   4977 
   4978         // Call framework method to have subclass compute its fields.
   4979         // These must include, at a minimum, MONTH, DAY_OF_MONTH,
   4980         // EXTENDED_YEAR, YEAR, DAY_OF_YEAR.  This method will call internalSet(),
   4981         // which will update stamp[].
   4982         handleComputeFields(fields[JULIAN_DAY]);
   4983 
   4984         // Compute week-related fields, based on the subclass-computed
   4985         // fields computed by handleComputeFields().
   4986         computeWeekFields();
   4987 
   4988         // Compute time-related fields.  These are indepent of the date and
   4989         // of the subclass algorithm.  They depend only on the local zone
   4990         // wall milliseconds in day.
   4991         int millisInDay = (int) (localMillis - (days * ONE_DAY));
   4992         fields[MILLISECONDS_IN_DAY] = millisInDay;
   4993         fields[MILLISECOND] = millisInDay % 1000;
   4994         millisInDay /= 1000;
   4995         fields[SECOND] = millisInDay % 60;
   4996         millisInDay /= 60;
   4997         fields[MINUTE] = millisInDay % 60;
   4998         millisInDay /= 60;
   4999         fields[HOUR_OF_DAY] = millisInDay;
   5000         fields[AM_PM] = millisInDay / 12; // Assume AM == 0
   5001         fields[HOUR] = millisInDay % 12;
   5002         fields[ZONE_OFFSET] = offsets[0];
   5003         fields[DST_OFFSET] = offsets[1];
   5004     }
   5005 
   5006     /**
   5007      * Compute the Gregorian calendar year, month, and day of month from
   5008      * the given Julian day.  These values are not stored in fields, but in
   5009      * member variables gregorianXxx.  Also compute the DAY_OF_WEEK and
   5010      * DOW_LOCAL fields.
   5011      */
   5012     private final void computeGregorianAndDOWFields(int julianDay) {
   5013         computeGregorianFields(julianDay);
   5014 
   5015         // Compute day of week: JD 0 = Monday
   5016         int dow = fields[DAY_OF_WEEK] = julianDayToDayOfWeek(julianDay);
   5017 
   5018         // Calculate 1-based localized day of week
   5019         int dowLocal = dow - getFirstDayOfWeek() + 1;
   5020         if (dowLocal < 1) {
   5021             dowLocal += 7;
   5022         }
   5023         fields[DOW_LOCAL] = dowLocal;
   5024     }
   5025 
   5026     /**
   5027      * Compute the Gregorian calendar year, month, and day of month from the
   5028      * Julian day.  These values are not stored in fields, but in member
   5029      * variables gregorianXxx.  They are used for time zone computations and by
   5030      * subclasses that are Gregorian derivatives.  Subclasses may call this
   5031      * method to perform a Gregorian calendar millis->fields computation.
   5032      * To perform a Gregorian calendar fields->millis computation, call
   5033      * computeGregorianMonthStart().
   5034      * @see #computeGregorianMonthStart
   5035      * @stable ICU 2.0
   5036      */
   5037     protected final void computeGregorianFields(int julianDay) {
   5038         int year, month, dayOfMonth, dayOfYear;
   5039 
   5040         // The Gregorian epoch day is zero for Monday January 1, year 1.
   5041         long gregorianEpochDay = julianDay - JAN_1_1_JULIAN_DAY;
   5042 
   5043         // Here we convert from the day number to the multiple radix
   5044         // representation.  We use 400-year, 100-year, and 4-year cycles.
   5045         // For example, the 4-year cycle has 4 years + 1 leap day; giving
   5046         // 1461 == 365*4 + 1 days.
   5047         int[] rem = new int[1];
   5048         int n400 = floorDivide(gregorianEpochDay, 146097, rem); // 400-year cycle length
   5049         int n100 = floorDivide(rem[0], 36524, rem); // 100-year cycle length
   5050         int n4 = floorDivide(rem[0], 1461, rem); // 4-year cycle length
   5051         int n1 = floorDivide(rem[0], 365, rem);
   5052         year = 400*n400 + 100*n100 + 4*n4 + n1;
   5053         dayOfYear = rem[0]; // zero-based day of year
   5054         if (n100 == 4 || n1 == 4) {
   5055             dayOfYear = 365; // Dec 31 at end of 4- or 400-yr cycle
   5056         } else {
   5057             ++year;
   5058         }
   5059 
   5060         boolean isLeap = ((year&0x3) == 0) && // equiv. to (year%4 == 0)
   5061                 (year%100 != 0 || year%400 == 0);
   5062 
   5063         int correction = 0;
   5064         int march1 = isLeap ? 60 : 59; // zero-based DOY for March 1
   5065         if (dayOfYear >= march1) correction = isLeap ? 1 : 2;
   5066         month = (12 * (dayOfYear + correction) + 6) / 367; // zero-based month
   5067         dayOfMonth = dayOfYear -
   5068                 GREGORIAN_MONTH_COUNT[month][isLeap?3:2] + 1; // one-based DOM
   5069 
   5070         gregorianYear = year;
   5071         gregorianMonth = month; // 0-based already
   5072         gregorianDayOfMonth = dayOfMonth; // 1-based already
   5073         gregorianDayOfYear = dayOfYear + 1; // Convert from 0-based to 1-based
   5074     }
   5075 
   5076     /**
   5077      * Compute the fields WEEK_OF_YEAR, YEAR_WOY, WEEK_OF_MONTH,
   5078      * DAY_OF_WEEK_IN_MONTH, and DOW_LOCAL from EXTENDED_YEAR, YEAR,
   5079      * DAY_OF_WEEK, and DAY_OF_YEAR.  The latter fields are computed by the
   5080      * subclass based on the calendar system.
   5081      *
   5082      * <p>The YEAR_WOY field is computed simplistically.  It is equal to YEAR
   5083      * most of the time, but at the year boundary it may be adjusted to YEAR-1
   5084      * or YEAR+1 to reflect the overlap of a week into an adjacent year.  In
   5085      * this case, a simple increment or decrement is performed on YEAR, even
   5086      * though this may yield an invalid YEAR value.  For instance, if the YEAR
   5087      * is part of a calendar system with an N-year cycle field CYCLE, then
   5088      * incrementing the YEAR may involve incrementing CYCLE and setting YEAR
   5089      * back to 0 or 1.  This is not handled by this code, and in fact cannot be
   5090      * simply handled without having subclasses define an entire parallel set of
   5091      * fields for fields larger than or equal to a year.  This additional
   5092      * complexity is not warranted, since the intention of the YEAR_WOY field is
   5093      * to support ISO 8601 notation, so it will typically be used with a
   5094      * proleptic Gregorian calendar, which has no field larger than a year.
   5095      */
   5096     private final void computeWeekFields() {
   5097         int eyear = fields[EXTENDED_YEAR];
   5098         int dayOfWeek = fields[DAY_OF_WEEK];
   5099         int dayOfYear = fields[DAY_OF_YEAR];
   5100 
   5101         // WEEK_OF_YEAR start
   5102         // Compute the week of the year.  For the Gregorian calendar, valid week
   5103         // numbers run from 1 to 52 or 53, depending on the year, the first day
   5104         // of the week, and the minimal days in the first week.  For other
   5105         // calendars, the valid range may be different -- it depends on the year
   5106         // length.  Days at the start of the year may fall into the last week of
   5107         // the previous year; days at the end of the year may fall into the
   5108         // first week of the next year.  ASSUME that the year length is less than
   5109         // 7000 days.
   5110         int yearOfWeekOfYear = eyear;
   5111         int relDow = (dayOfWeek + 7 - getFirstDayOfWeek()) % 7; // 0..6
   5112         int relDowJan1 = (dayOfWeek - dayOfYear + 7001 - getFirstDayOfWeek()) % 7; // 0..6
   5113         int woy = (dayOfYear - 1 + relDowJan1) / 7; // 0..53
   5114         if ((7 - relDowJan1) >= getMinimalDaysInFirstWeek()) {
   5115             ++woy;
   5116         }
   5117 
   5118         // Adjust for weeks at the year end that overlap into the previous or
   5119         // next calendar year.
   5120         if (woy == 0) {
   5121             // We are the last week of the previous year.
   5122             // Check to see if we are in the last week; if so, we need
   5123             // to handle the case in which we are the first week of the
   5124             // next year.
   5125 
   5126             int prevDoy = dayOfYear + handleGetYearLength(eyear - 1);
   5127             woy = weekNumber(prevDoy, dayOfWeek);
   5128             yearOfWeekOfYear--;
   5129         } else {
   5130             int lastDoy = handleGetYearLength(eyear);
   5131             // Fast check: For it to be week 1 of the next year, the DOY
   5132             // must be on or after L-5, where L is yearLength(), then it
   5133             // cannot possibly be week 1 of the next year:
   5134             //          L-5                  L
   5135             // doy: 359 360 361 362 363 364 365 001
   5136             // dow:      1   2   3   4   5   6   7
   5137             if (dayOfYear >= (lastDoy - 5)) {
   5138                 int lastRelDow = (relDow + lastDoy - dayOfYear) % 7;
   5139                 if (lastRelDow < 0) {
   5140                     lastRelDow += 7;
   5141                 }
   5142                 if (((6 - lastRelDow) >= getMinimalDaysInFirstWeek()) &&
   5143                         ((dayOfYear + 7 - relDow) > lastDoy)) {
   5144                     woy = 1;
   5145                     yearOfWeekOfYear++;
   5146                 }
   5147             }
   5148         }
   5149         fields[WEEK_OF_YEAR] = woy;
   5150         fields[YEAR_WOY] = yearOfWeekOfYear;
   5151         // WEEK_OF_YEAR end
   5152 
   5153         int dayOfMonth = fields[DAY_OF_MONTH];
   5154         fields[WEEK_OF_MONTH] = weekNumber(dayOfMonth, dayOfWeek);
   5155         fields[DAY_OF_WEEK_IN_MONTH] = (dayOfMonth-1) / 7 + 1;
   5156     }
   5157 
   5158     //----------------------------------------------------------------------
   5159     // Fields -> Time
   5160     //----------------------------------------------------------------------
   5161 
   5162     /**
   5163      * Value to OR against resolve table field values for remapping.
   5164      * @see #resolveFields
   5165      * @stable ICU 2.0
   5166      */
   5167     protected static final int RESOLVE_REMAP = 32;
   5168     // A power of 2 greater than or equal to MAX_FIELD_COUNT
   5169 
   5170     // Default table for day in year
   5171     static final int[][][] DATE_PRECEDENCE = {
   5172         {
   5173             { DAY_OF_MONTH },
   5174             { WEEK_OF_YEAR, DAY_OF_WEEK },
   5175             { WEEK_OF_MONTH, DAY_OF_WEEK },
   5176             { DAY_OF_WEEK_IN_MONTH, DAY_OF_WEEK },
   5177             { WEEK_OF_YEAR, DOW_LOCAL },
   5178             { WEEK_OF_MONTH, DOW_LOCAL },
   5179             { DAY_OF_WEEK_IN_MONTH, DOW_LOCAL },
   5180             { DAY_OF_YEAR },
   5181             { RESOLVE_REMAP | DAY_OF_MONTH, YEAR },  // if YEAR is set over YEAR_WOY use DAY_OF_MONTH
   5182             { RESOLVE_REMAP | WEEK_OF_YEAR, YEAR_WOY },  // if YEAR_WOY is set,  calc based on WEEK_OF_YEAR
   5183         },
   5184         {
   5185             { WEEK_OF_YEAR },
   5186             { WEEK_OF_MONTH },
   5187             { DAY_OF_WEEK_IN_MONTH },
   5188             { RESOLVE_REMAP | DAY_OF_WEEK_IN_MONTH, DAY_OF_WEEK },
   5189             { RESOLVE_REMAP | DAY_OF_WEEK_IN_MONTH, DOW_LOCAL },
   5190         },
   5191     };
   5192 
   5193     static final int[][][] DOW_PRECEDENCE = {
   5194         {
   5195             { DAY_OF_WEEK },
   5196             { DOW_LOCAL },
   5197         },
   5198     };
   5199 
   5200     /**
   5201      * Given a precedence table, return the newest field combination in
   5202      * the table, or -1 if none is found.
   5203      *
   5204      * <p>The precedence table is a 3-dimensional array of integers.  It
   5205      * may be thought of as an array of groups.  Each group is an array of
   5206      * lines.  Each line is an array of field numbers.  Within a line, if
   5207      * all fields are set, then the time stamp of the line is taken to be
   5208      * the stamp of the most recently set field.  If any field of a line is
   5209      * unset, then the line fails to match.  Within a group, the line with
   5210      * the newest time stamp is selected.  The first field of the line is
   5211      * returned to indicate which line matched.
   5212      *
   5213      * <p>In some cases, it may be desirable to map a line to field that
   5214      * whose stamp is NOT examined.  For example, if the best field is
   5215      * DAY_OF_WEEK then the DAY_OF_WEEK_IN_MONTH algorithm may be used.  In
   5216      * order to do this, insert the value <code>REMAP_RESOLVE | F</code> at
   5217      * the start of the line, where <code>F</code> is the desired return
   5218      * field value.  This field will NOT be examined; it only determines
   5219      * the return value if the other fields in the line are the newest.
   5220      *
   5221      * <p>If all lines of a group contain at least one unset field, then no
   5222      * line will match, and the group as a whole will fail to match.  In
   5223      * that case, the next group will be processed.  If all groups fail to
   5224      * match, then -1 is returned.
   5225      * @stable ICU 2.0
   5226      */
   5227     protected int resolveFields(int[][][] precedenceTable) {
   5228         int bestField = -1;
   5229         int tempBestField;
   5230         for (int g=0; g<precedenceTable.length && bestField < 0; ++g) {
   5231             int[][] group = precedenceTable[g];
   5232             int bestStamp = UNSET;
   5233             linesInGroup:
   5234                 for (int l=0; l<group.length; ++l) {
   5235                     int[] line= group[l];
   5236                     int lineStamp = UNSET;
   5237                     // Skip over first entry if it is negative
   5238                     for (int i=(line[0]>=RESOLVE_REMAP)?1:0; i<line.length; ++i) {
   5239                         int s = stamp[line[i]];
   5240                         // If any field is unset then don't use this line
   5241                         if (s == UNSET) {
   5242                             continue linesInGroup;
   5243                         } else {
   5244                             lineStamp = Math.max(lineStamp, s);
   5245                         }
   5246                     }
   5247                     // Record new maximum stamp & field no.
   5248                     if (lineStamp > bestStamp) {
   5249                         tempBestField = line[0]; // First field refers to entire line
   5250                         if (tempBestField >= RESOLVE_REMAP) {
   5251                             tempBestField &= (RESOLVE_REMAP-1);
   5252                             // This check is needed to resolve some issues with UCAL_YEAR precedence mapping
   5253                             if (tempBestField != DATE || (stamp[WEEK_OF_MONTH] < stamp[tempBestField])) {
   5254                                 bestField = tempBestField;
   5255                             }
   5256                         } else {
   5257                             bestField = tempBestField;
   5258                         }
   5259 
   5260                         if (bestField == tempBestField) {
   5261                             bestStamp = lineStamp;
   5262                         }
   5263                     }
   5264                 }
   5265         }
   5266         return (bestField>=RESOLVE_REMAP)?(bestField&(RESOLVE_REMAP-1)):bestField;
   5267     }
   5268 
   5269     /**
   5270      * Returns the newest stamp of a given range of fields.
   5271      * @stable ICU 2.0
   5272      */
   5273     protected int newestStamp(int first, int last, int bestStampSoFar) {
   5274         int bestStamp = bestStampSoFar;
   5275         for (int i=first; i<=last; ++i) {
   5276             if (stamp[i] > bestStamp) {
   5277                 bestStamp = stamp[i];
   5278             }
   5279         }
   5280         return bestStamp;
   5281     }
   5282 
   5283     /**
   5284      * Returns the timestamp of a field.
   5285      * @stable ICU 2.0
   5286      */
   5287     protected final int getStamp(int field) {
   5288         return stamp[field];
   5289     }
   5290 
   5291     /**
   5292      * Returns the field that is newer, either defaultField, or
   5293      * alternateField.  If neither is newer or neither is set, return defaultField.
   5294      * @stable ICU 2.0
   5295      */
   5296     protected int newerField(int defaultField, int alternateField) {
   5297         if (stamp[alternateField] > stamp[defaultField]) {
   5298             return alternateField;
   5299         }
   5300         return defaultField;
   5301     }
   5302 
   5303     /**
   5304      * Ensure that each field is within its valid range by calling {@link
   5305      * #validateField(int)} on each field that has been set.  This method
   5306      * should only be called if this calendar is not lenient.
   5307      * @see #isLenient
   5308      * @see #validateField(int)
   5309      * @stable ICU 2.0
   5310      */
   5311     protected void validateFields() {
   5312         for (int field = 0; field < fields.length; field++) {
   5313             if (stamp[field] >= MINIMUM_USER_STAMP) {
   5314                 validateField(field);
   5315             }
   5316         }
   5317     }
   5318 
   5319     /**
   5320      * Validate a single field of this calendar.  Subclasses should
   5321      * override this method to validate any calendar-specific fields.
   5322      * Generic fields can be handled by
   5323      * <code>Calendar.validateField()</code>.
   5324      * @see #validateField(int, int, int)
   5325      * @stable ICU 2.0
   5326      */
   5327     protected void validateField(int field) {
   5328         int y;
   5329         switch (field) {
   5330         case DAY_OF_MONTH:
   5331             y = handleGetExtendedYear();
   5332             validateField(field, 1, handleGetMonthLength(y, internalGet(MONTH)));
   5333             break;
   5334         case DAY_OF_YEAR:
   5335             y = handleGetExtendedYear();
   5336             validateField(field, 1, handleGetYearLength(y));
   5337             break;
   5338         case DAY_OF_WEEK_IN_MONTH:
   5339             if (internalGet(field) == 0) {
   5340                 throw new IllegalArgumentException("DAY_OF_WEEK_IN_MONTH cannot be zero");
   5341             }
   5342             validateField(field, getMinimum(field), getMaximum(field));
   5343             break;
   5344         default:
   5345             validateField(field, getMinimum(field), getMaximum(field));
   5346             break;
   5347         }
   5348     }
   5349 
   5350     /**
   5351      * Validate a single field of this calendar given its minimum and
   5352      * maximum allowed value.  If the field is out of range, throw a
   5353      * descriptive <code>IllegalArgumentException</code>.  Subclasses may
   5354      * use this method in their implementation of {@link
   5355      * #validateField(int)}.
   5356      * @stable ICU 2.0
   5357      */
   5358     protected final void validateField(int field, int min, int max) {
   5359         int value = fields[field];
   5360         if (value < min || value > max) {
   5361             throw new IllegalArgumentException(fieldName(field) +
   5362                     '=' + value + ", valid range=" +
   5363                     min + ".." + max);
   5364         }
   5365     }
   5366 
   5367     /**
   5368      * Converts the current field values in <code>fields[]</code> to the
   5369      * millisecond time value <code>time</code>.
   5370      * @stable ICU 2.0
   5371      */
   5372     protected void computeTime() {
   5373         if (!isLenient()) {
   5374             validateFields();
   5375         }
   5376 
   5377         // Compute the Julian day
   5378         int julianDay = computeJulianDay();
   5379 
   5380         long millis = julianDayToMillis(julianDay);
   5381 
   5382         int millisInDay;
   5383 
   5384         // We only use MILLISECONDS_IN_DAY if it has been set by the user.
   5385         // This makes it possible for the caller to set the calendar to a
   5386         // time and call clear(MONTH) to reset the MONTH to January.  This
   5387         // is legacy behavior.  Without this, clear(MONTH) has no effect,
   5388         // since the internally set JULIAN_DAY is used.
   5389         if (stamp[MILLISECONDS_IN_DAY] >= MINIMUM_USER_STAMP &&
   5390                 newestStamp(AM_PM, MILLISECOND, UNSET) <= stamp[MILLISECONDS_IN_DAY]) {
   5391             millisInDay = internalGet(MILLISECONDS_IN_DAY);
   5392         } else {
   5393             millisInDay = computeMillisInDay();
   5394         }
   5395 
   5396         if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP ||
   5397                 stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) {
   5398             time = millis + millisInDay - (internalGet(ZONE_OFFSET) + internalGet(DST_OFFSET));
   5399         } else {
   5400             // Compute the time zone offset and DST offset.  There are two potential
   5401             // ambiguities here.  We'll assume a 2:00 am (wall time) switchover time
   5402             // for discussion purposes here.
   5403             //
   5404             // 1. The positive offset change such as transition into DST.
   5405             //    Here, a designated time of 2:00 am - 2:59 am does not actually exist.
   5406             //    For this case, skippedWallTime option specifies the behavior.
   5407             //    For example, 2:30 am is interpreted as;
   5408             //      - WALLTIME_LAST(default): 3:30 am (DST) (interpreting 2:30 am as 31 minutes after 1:59 am (STD))
   5409             //      - WALLTIME_FIRST: 1:30 am (STD) (interpreting 2:30 am as 30 minutes before 3:00 am (DST))
   5410             //      - WALLTIME_NEXT_VALID: 3:00 am (DST) (next valid time after 2:30 am on a wall clock)
   5411             // 2. The negative offset change such as transition out of DST.
   5412             //    Here, a designated time of 1:00 am - 1:59 am can be in standard or DST.  Both are valid
   5413             //    representations (the rep jumps from 1:59:59 DST to 1:00:00 Std).
   5414             //    For this case, repeatedWallTime option specifies the behavior.
   5415             //    For example, 1:30 am is interpreted as;
   5416             //      - WALLTIME_LAST(default): 1:30 am (STD) - latter occurrence
   5417             //      - WALLTIME_FIRST: 1:30 am (DST) - former occurrence
   5418             //
   5419             // In addition to above, when calendar is strict (not default), wall time falls into
   5420             // the skipped time range will be processed as an error case.
   5421             //
   5422             // These special cases are mostly handled in #computeZoneOffset(long), except WALLTIME_NEXT_VALID
   5423             // at positive offset change. The protected method computeZoneOffset(long) is exposed to Calendar
   5424             // subclass implementations and marked as @stable. Strictly speaking, WALLTIME_NEXT_VALID
   5425             // should be also handled in the same place, but we cannot change the code flow without deprecating
   5426             // the protected method.
   5427             //
   5428             // We use the TimeZone object, unless the user has explicitly set the ZONE_OFFSET
   5429             // or DST_OFFSET fields; then we use those fields.
   5430 
   5431             if (!lenient || skippedWallTime == WALLTIME_NEXT_VALID) {
   5432                 // When strict, invalidate a wall time falls into a skipped wall time range.
   5433                 // When lenient and skipped wall time option is WALLTIME_NEXT_VALID,
   5434                 // the result time will be adjusted to the next valid time (on wall clock).
   5435                 int zoneOffset = computeZoneOffset(millis, millisInDay);
   5436                 long tmpTime = millis + millisInDay - zoneOffset;
   5437 
   5438                 int zoneOffset1 = zone.getOffset(tmpTime);
   5439 
   5440                 // zoneOffset != zoneOffset1 only when the given wall time fall into
   5441                 // a skipped wall time range caused by positive zone offset transition.
   5442                 if (zoneOffset != zoneOffset1) {
   5443                     if (!lenient) {
   5444                         throw new IllegalArgumentException("The specified wall time does not exist due to time zone offset transition.");
   5445                     }
   5446 
   5447                     assert skippedWallTime == WALLTIME_NEXT_VALID : skippedWallTime;
   5448                     // Adjust time to the next valid wall clock time.
   5449                     // At this point, tmpTime is on or after the zone offset transition causing
   5450                     // the skipped time range.
   5451                     Long immediatePrevTransition = getImmediatePreviousZoneTransition(tmpTime);
   5452                     if (immediatePrevTransition == null) {
   5453                         throw new RuntimeException("Could not locate a time zone transition before " + tmpTime);
   5454                     }
   5455                     time = immediatePrevTransition;
   5456                 } else {
   5457                     time = tmpTime;
   5458                 }
   5459             } else {
   5460                 time = millis + millisInDay - computeZoneOffset(millis, millisInDay);
   5461             }
   5462         }
   5463     }
   5464 
   5465     /**
   5466      * Find the previous zone transtion near the given time.
   5467      *
   5468      * @param base The base time, inclusive.
   5469      * @return The time of the previous transition, or null if not found.
   5470      */
   5471     private Long getImmediatePreviousZoneTransition(long base) {
   5472         Long transitionTime = null;
   5473 
   5474         if (zone instanceof BasicTimeZone) {
   5475             TimeZoneTransition transition = ((BasicTimeZone) zone).getPreviousTransition(base, true);
   5476             if (transition != null) {
   5477                 transitionTime = transition.getTime();
   5478             }
   5479         } else {
   5480             // Usually, it is enough to check past one hour because such transition is most
   5481             // likely +1 hour shift. However, there is an example jumped +24 hour in the tz database.
   5482             transitionTime = getPreviousZoneTransitionTime(zone, base, 2 * 60 * 60 * 1000); // check last 2 hours
   5483             if (transitionTime == null) {
   5484                 transitionTime = getPreviousZoneTransitionTime(zone, base, 30 * 60 * 60 * 1000); // try last 30 hours
   5485             }
   5486         }
   5487         return transitionTime;
   5488     }
   5489 
   5490     /**
   5491      * Find the previous zone transition within the specified duration.
   5492      * Note: This method is only used when TimeZone is NOT a BasicTimeZone.
   5493      * @param tz The time zone.
   5494      * @param base The base time, inclusive.
   5495      * @param duration The range of time evaluated.
   5496      * @return The time of the previous zone transition, or null if not available.
   5497      */
   5498     private static Long getPreviousZoneTransitionTime(TimeZone tz, long base, long duration) {
   5499         assert duration > 0;
   5500 
   5501         long upper = base;
   5502         long lower = base - duration - 1;
   5503         int offsetU = tz.getOffset(upper);
   5504         int offsetL = tz.getOffset(lower);
   5505         if (offsetU == offsetL) {
   5506             return null;
   5507         }
   5508         return findPreviousZoneTransitionTime(tz, offsetU, upper, lower);
   5509     }
   5510 
   5511     /**
   5512      * The time units used by {@link #findPreviousZoneTransitionTime(TimeZone, int, long, long)}
   5513      * for optimizing transition time binary search.
   5514      */
   5515     private static final int[] FIND_ZONE_TRANSITION_TIME_UNITS = {
   5516         60*60*1000, // 1 hour
   5517         30*60*1000, // 30 minutes
   5518         60*1000,    // 1 minute
   5519         1000,       // 1 second
   5520     };
   5521 
   5522     /**
   5523      * Implementing binary search for zone transtion detection, used by {@link #getPreviousZoneTransitionTime(TimeZone, long, long)}
   5524      * @param tz The time zone.
   5525      * @param upperOffset The zone offset at <code>upper</code>
   5526      * @param upper The upper bound, inclusive.
   5527      * @param lower The lower bound, exclusive.
   5528      * @return The time of the previous zone transition, or null if not available.
   5529      */
   5530     private static Long findPreviousZoneTransitionTime(TimeZone tz, int upperOffset, long upper, long lower) {
   5531         boolean onUnitTime = false;
   5532         long mid = 0;
   5533 
   5534         for (int unit : FIND_ZONE_TRANSITION_TIME_UNITS) {
   5535             long lunits = lower/unit;
   5536             long uunits = upper/unit;
   5537             if (uunits > lunits) {
   5538                 mid = ((lunits + uunits + 1) >>> 1) * unit;
   5539                 onUnitTime = true;
   5540                 break;
   5541             }
   5542         }
   5543 
   5544         int midOffset;
   5545         if (!onUnitTime) {
   5546             mid = (upper + lower) >>> 1;
   5547         }
   5548 
   5549         if (onUnitTime) {
   5550             if (mid != upper) {
   5551                 midOffset  = tz.getOffset(mid);
   5552                 if (midOffset != upperOffset) {
   5553                     return findPreviousZoneTransitionTime(tz, upperOffset, upper, mid);
   5554                 }
   5555                 upper = mid;
   5556             }
   5557             // check mid-1
   5558             mid--;
   5559         } else {
   5560             mid = (upper + lower) >>> 1;
   5561         }
   5562 
   5563         if (mid == lower) {
   5564             return Long.valueOf(upper);
   5565         }
   5566         midOffset = tz.getOffset(mid);
   5567         if (midOffset != upperOffset) {
   5568             if (onUnitTime) {
   5569                 return Long.valueOf(upper);
   5570             }
   5571             return findPreviousZoneTransitionTime(tz, upperOffset, upper, mid);
   5572         }
   5573         return findPreviousZoneTransitionTime(tz, upperOffset, mid, lower);
   5574     }
   5575 
   5576     /**
   5577      * Compute the milliseconds in the day from the fields.  This is a
   5578      * value from 0 to 23:59:59.999 inclusive, unless fields are out of
   5579      * range, in which case it can be an arbitrary value.  This value
   5580      * reflects local zone wall time.
   5581      * @stable ICU 2.0
   5582      */
   5583     protected int computeMillisInDay() {
   5584         // Do the time portion of the conversion.
   5585 
   5586         int millisInDay = 0;
   5587 
   5588         // Find the best set of fields specifying the time of day.  There
   5589         // are only two possibilities here; the HOUR_OF_DAY or the
   5590         // AM_PM and the HOUR.
   5591         int hourOfDayStamp = stamp[HOUR_OF_DAY];
   5592         int hourStamp = Math.max(stamp[HOUR], stamp[AM_PM]);
   5593         int bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp : hourOfDayStamp;
   5594 
   5595         // Hours
   5596         if (bestStamp != UNSET) {
   5597             if (bestStamp == hourOfDayStamp) {
   5598                 // Don't normalize here; let overflow bump into the next period.
   5599                 // This is consistent with how we handle other fields.
   5600                 millisInDay += internalGet(HOUR_OF_DAY);
   5601             } else {
   5602                 // Don't normalize here; let overflow bump into the next period.
   5603                 // This is consistent with how we handle other fields.
   5604                 millisInDay += internalGet(HOUR);
   5605                 millisInDay += 12 * internalGet(AM_PM); // Default works for unset AM_PM
   5606             }
   5607         }
   5608 
   5609         // We use the fact that unset == 0; we start with millisInDay
   5610         // == HOUR_OF_DAY.
   5611         millisInDay *= 60;
   5612         millisInDay += internalGet(MINUTE); // now have minutes
   5613         millisInDay *= 60;
   5614         millisInDay += internalGet(SECOND); // now have seconds
   5615         millisInDay *= 1000;
   5616         millisInDay += internalGet(MILLISECOND); // now have millis
   5617 
   5618         return millisInDay;
   5619     }
   5620 
   5621     /**
   5622      * This method can assume EXTENDED_YEAR has been set.
   5623      * @param millis milliseconds of the date fields (local midnight millis)
   5624      * @param millisInDay milliseconds of the time fields; may be out
   5625      * or range.
   5626      * @return total zone offset (raw + DST) for the given moment
   5627      * @stable ICU 2.0
   5628      */
   5629     protected int computeZoneOffset(long millis, int millisInDay) {
   5630         int[] offsets = new int[2];
   5631         long wall = millis + millisInDay;
   5632         if (zone instanceof BasicTimeZone) {
   5633             int duplicatedTimeOpt = (repeatedWallTime == WALLTIME_FIRST) ? BasicTimeZone.LOCAL_FORMER : BasicTimeZone.LOCAL_LATTER;
   5634             int nonExistingTimeOpt = (skippedWallTime == WALLTIME_FIRST) ? BasicTimeZone.LOCAL_LATTER : BasicTimeZone.LOCAL_FORMER;
   5635             ((BasicTimeZone)zone).getOffsetFromLocal(wall, nonExistingTimeOpt, duplicatedTimeOpt, offsets);
   5636         } else {
   5637             // By default, TimeZone#getOffset behaves WALLTIME_LAST for both.
   5638             zone.getOffset(wall, true, offsets);
   5639 
   5640             boolean sawRecentNegativeShift = false;
   5641             if (repeatedWallTime == WALLTIME_FIRST) {
   5642                 // Check if the given wall time falls into repeated time range
   5643                 long tgmt = wall - (offsets[0] + offsets[1]);
   5644 
   5645                 // Any negative zone transition within last 6 hours?
   5646                 // Note: The maximum historic negative zone transition is -3 hours in the tz database.
   5647                 // 6 hour window would be sufficient for this purpose.
   5648                 int offsetBefore6 = zone.getOffset(tgmt - 6*60*60*1000);
   5649                 int offsetDelta = (offsets[0] + offsets[1]) - offsetBefore6;
   5650 
   5651                 assert offsetDelta < -6*60*60*1000 : offsetDelta;
   5652                 if (offsetDelta < 0) {
   5653                     sawRecentNegativeShift = true;
   5654                     // Negative shift within last 6 hours. When WALLTIME_FIRST is used and the given wall time falls
   5655                     // into the repeated time range, use offsets before the transition.
   5656                     // Note: If it does not fall into the repeated time range, offsets remain unchanged below.
   5657                     zone.getOffset(wall + offsetDelta, true, offsets);
   5658                 }
   5659             }
   5660             if (!sawRecentNegativeShift && skippedWallTime == WALLTIME_FIRST) {
   5661                 // When skipped wall time option is WALLTIME_FIRST,
   5662                 // recalculate offsets from the resolved time (non-wall).
   5663                 // When the given wall time falls into skipped wall time,
   5664                 // the offsets will be based on the zone offsets AFTER
   5665                 // the transition (which means, earliest possibe interpretation).
   5666                 long tgmt = wall - (offsets[0] + offsets[1]);
   5667                 zone.getOffset(tgmt, false, offsets);
   5668             }
   5669         }
   5670         return offsets[0] + offsets[1];
   5671     }
   5672 
   5673     /**
   5674      * Compute the Julian day number as specified by this calendar's fields.
   5675      * @stable ICU 2.0
   5676      */
   5677     protected int computeJulianDay() {
   5678 
   5679         // We want to see if any of the date fields is newer than the
   5680         // JULIAN_DAY.  If not, then we use JULIAN_DAY.  If so, then we do
   5681         // the normal resolution.  We only use JULIAN_DAY if it has been
   5682         // set by the user.  This makes it possible for the caller to set
   5683         // the calendar to a time and call clear(MONTH) to reset the MONTH
   5684         // to January.  This is legacy behavior.  Without this,
   5685         // clear(MONTH) has no effect, since the internally set JULIAN_DAY
   5686         // is used.
   5687         if (stamp[JULIAN_DAY] >= MINIMUM_USER_STAMP) {
   5688             int bestStamp = newestStamp(ERA, DAY_OF_WEEK_IN_MONTH, UNSET);
   5689             bestStamp = newestStamp(YEAR_WOY, EXTENDED_YEAR, bestStamp);
   5690             if (bestStamp <= stamp[JULIAN_DAY]) {
   5691                 return internalGet(JULIAN_DAY);
   5692             }
   5693         }
   5694 
   5695         int bestField = resolveFields(getFieldResolutionTable());
   5696         if (bestField < 0) {
   5697             bestField = DAY_OF_MONTH;
   5698         }
   5699 
   5700         return handleComputeJulianDay(bestField);
   5701     }
   5702 
   5703     /**
   5704      * Returns the field resolution array for this calendar.  Calendars that
   5705      * define additional fields or change the semantics of existing fields
   5706      * should override this method to adjust the field resolution semantics
   5707      * accordingly.  Other subclasses should not override this method.
   5708      * @see #resolveFields
   5709      * @stable ICU 2.0
   5710      */
   5711     protected int[][][] getFieldResolutionTable() {
   5712         return DATE_PRECEDENCE;
   5713     }
   5714 
   5715     /**
   5716      * Returns the Julian day number of day before the first day of the
   5717      * given month in the given extended year.  Subclasses should override
   5718      * this method to implement their calendar system.
   5719      * @param eyear the extended year
   5720      * @param month the zero-based month, or 0 if useMonth is false
   5721      * @param useMonth if false, compute the day before the first day of
   5722      * the given year, otherwise, compute the day before the first day of
   5723      * the given month
   5724      * @return the Julian day number of the day before the first
   5725      * day of the given month and year
   5726      * @stable ICU 2.0
   5727      */
   5728     abstract protected int handleComputeMonthStart(int eyear, int month,
   5729             boolean useMonth);
   5730 
   5731     /**
   5732      * Returns the extended year defined by the current fields.  This will
   5733      * use the EXTENDED_YEAR field or the YEAR and supra-year fields (such
   5734      * as ERA) specific to the calendar system, depending on which set of
   5735      * fields is newer.
   5736      * @return the extended year
   5737      * @stable ICU 2.0
   5738      */
   5739     abstract protected int handleGetExtendedYear();
   5740 
   5741     // (The following method is not called because all existing subclasses
   5742     // override it.  2003-06-11 ICU 2.6 Alan)
   5743     ///CLOVER:OFF
   5744     /**
   5745      * Returns the number of days in the given month of the given extended
   5746      * year of this calendar system.  Subclasses should override this
   5747      * method if they can provide a more correct or more efficient
   5748      * implementation than the default implementation in Calendar.
   5749      * @stable ICU 2.0
   5750      */
   5751     protected int handleGetMonthLength(int extendedYear, int month) {
   5752         return handleComputeMonthStart(extendedYear, month+1, true) -
   5753                 handleComputeMonthStart(extendedYear, month, true);
   5754     }
   5755     ///CLOVER:ON
   5756 
   5757     /**
   5758      * Returns the number of days in the given extended year of this
   5759      * calendar system.  Subclasses should override this method if they can
   5760      * provide a more correct or more efficient implementation than the
   5761      * default implementation in Calendar.
   5762      * @stable ICU 2.0
   5763      */
   5764     protected int handleGetYearLength(int eyear) {
   5765         return handleComputeMonthStart(eyear+1, 0, false) -
   5766                 handleComputeMonthStart(eyear, 0, false);
   5767     }
   5768 
   5769     /**
   5770      * Subclasses that use additional fields beyond those defined in
   5771      * <code>Calendar</code> should override this method to return an
   5772      * <code>int[]</code> array of the appropriate length.  The length
   5773      * must be at least <code>BASE_FIELD_COUNT</code> and no more than
   5774      * <code>MAX_FIELD_COUNT</code>.
   5775      * @stable ICU 2.0
   5776      */
   5777     protected int[] handleCreateFields() {
   5778         return new int[BASE_FIELD_COUNT];
   5779     }
   5780 
   5781     /**
   5782      * Subclasses may override this.
   5783      * Called by handleComputeJulianDay.  Returns the default month (0-based) for the year,
   5784      * taking year and era into account.  Defaults to 0 (JANUARY) for Gregorian.
   5785      * @param extendedYear the extendedYear, as returned by handleGetExtendedYear
   5786      * @return the default month
   5787      * @draft ICU 3.6 (retain)
   5788      * @provisional This API might change or be removed in a future release.
   5789      * @see #MONTH
   5790      */
   5791     protected int getDefaultMonthInYear(int extendedYear) {
   5792         return Calendar.JANUARY;
   5793     }
   5794 
   5795     /**
   5796      * Subclasses may override this.
   5797      * Called by handleComputeJulianDay.  Returns the default day (1-based) for the month,
   5798      * taking currently-set year and era into account.  Defaults to 1 for Gregorian.
   5799      * @param extendedYear the extendedYear, as returned by handleGetExtendedYear
   5800      * @param month the month, as returned by getDefaultMonthInYear
   5801      * @return the default day of the month
   5802      * @draft ICU 3.6 (retain)
   5803      * @provisional This API might change or be removed in a future release.
   5804      * @see #DAY_OF_MONTH
   5805      */
   5806     protected int getDefaultDayInMonth(int extendedYear, int month) {
   5807         return 1;
   5808     }
   5809 
   5810 
   5811     /**
   5812      * Subclasses may override this.  This method calls
   5813      * handleGetMonthLength() to obtain the calendar-specific month
   5814      * length.
   5815      * @stable ICU 2.0
   5816      */
   5817     protected int handleComputeJulianDay(int bestField) {
   5818 
   5819         boolean useMonth = (bestField == DAY_OF_MONTH ||
   5820                 bestField == WEEK_OF_MONTH ||
   5821                 bestField == DAY_OF_WEEK_IN_MONTH);
   5822 
   5823         int year;
   5824 
   5825         if (bestField == WEEK_OF_YEAR) {
   5826             // Nota Bene!  It is critical that YEAR_WOY be used as the year here, if it is
   5827             // set.  Otherwise, when WOY is the best field, the year may be wrong at the
   5828             // extreme limits of the year.  If YEAR_WOY is not set then it will fall back.
   5829             // TODO: Should resolveField(YEAR_PRECEDENCE) be brought to bear?
   5830             year = internalGet(YEAR_WOY, handleGetExtendedYear());
   5831         } else {
   5832             year = handleGetExtendedYear();
   5833         }
   5834 
   5835         internalSet(EXTENDED_YEAR, year);
   5836 
   5837         int month = useMonth ? internalGet(MONTH, getDefaultMonthInYear(year)) : 0;
   5838 
   5839         // Get the Julian day of the day BEFORE the start of this year.
   5840         // If useMonth is true, get the day before the start of the month.
   5841         int julianDay = handleComputeMonthStart(year, month, useMonth);
   5842 
   5843         if (bestField == DAY_OF_MONTH) {
   5844             if(isSet(DAY_OF_MONTH)) {
   5845                 return julianDay + internalGet(DAY_OF_MONTH, getDefaultDayInMonth(year, month));
   5846             } else {
   5847                 return julianDay + getDefaultDayInMonth(year, month);
   5848             }
   5849         }
   5850 
   5851         if (bestField == DAY_OF_YEAR) {
   5852             return julianDay + internalGet(DAY_OF_YEAR);
   5853         }
   5854 
   5855         int firstDOW = getFirstDayOfWeek(); // Localized fdw
   5856 
   5857         // At this point julianDay is the 0-based day BEFORE the first day of
   5858         // January 1, year 1 of the given calendar.  If julianDay == 0, it
   5859         // specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian
   5860         // or Gregorian).
   5861 
   5862         // At this point we need to process the WEEK_OF_MONTH or
   5863         // WEEK_OF_YEAR, which are similar, or the DAY_OF_WEEK_IN_MONTH.
   5864         // First, perform initial shared computations.  These locate the
   5865         // first week of the period.
   5866 
   5867         // Get the 0-based localized DOW of day one of the month or year.
   5868         // Valid range 0..6.
   5869         int first = julianDayToDayOfWeek(julianDay + 1) - firstDOW;
   5870         if (first < 0) {
   5871             first += 7;
   5872         }
   5873 
   5874         // Get zero-based localized DOW, valid range 0..6.  This is the DOW
   5875         // we are looking for.
   5876         int dowLocal = 0;
   5877         switch (resolveFields(DOW_PRECEDENCE)) {
   5878         case DAY_OF_WEEK:
   5879             dowLocal = internalGet(DAY_OF_WEEK) - firstDOW;
   5880             break;
   5881         case DOW_LOCAL:
   5882             dowLocal = internalGet(DOW_LOCAL) - 1;
   5883             break;
   5884         }
   5885         dowLocal = dowLocal % 7;
   5886         if (dowLocal < 0) {
   5887             dowLocal += 7;
   5888         }
   5889 
   5890         // Find the first target DOW (dowLocal) in the month or year.
   5891         // Actually, it may be just before the first of the month or year.
   5892         // It will be an integer from -5..7.
   5893         int date = 1 - first + dowLocal;
   5894 
   5895         if (bestField == DAY_OF_WEEK_IN_MONTH) {
   5896 
   5897             // Adjust the target DOW to be in the month or year.
   5898             if (date < 1) {
   5899                 date += 7;
   5900             }
   5901 
   5902             // The only trickiness occurs if the day-of-week-in-month is
   5903             // negative.
   5904             int dim = internalGet(DAY_OF_WEEK_IN_MONTH, 1);
   5905             if (dim >= 0) {
   5906                 date += 7*(dim - 1);
   5907 
   5908             } else {
   5909                 // Move date to the last of this day-of-week in this month,
   5910                 // then back up as needed.  If dim==-1, we don't back up at
   5911                 // all.  If dim==-2, we back up once, etc.  Don't back up
   5912                 // past the first of the given day-of-week in this month.
   5913                 // Note that we handle -2, -3, etc. correctly, even though
   5914                 // values < -1 are technically disallowed.
   5915                 int m = internalGet(MONTH, JANUARY);
   5916                 int monthLength = handleGetMonthLength(year, m);
   5917                 date += ((monthLength - date) / 7 + dim + 1) * 7;
   5918             }
   5919         } else {
   5920             // assert(bestField == WEEK_OF_MONTH || bestField == WEEK_OF_YEAR)
   5921 
   5922             // Adjust for minimal days in first week
   5923             if ((7 - first) < getMinimalDaysInFirstWeek()) {
   5924                 date += 7;
   5925             }
   5926 
   5927             // Now adjust for the week number.
   5928             date += 7 * (internalGet(bestField) - 1);
   5929         }
   5930 
   5931         return julianDay + date;
   5932     }
   5933 
   5934     /**
   5935      * Compute the Julian day of a month of the Gregorian calendar.
   5936      * Subclasses may call this method to perform a Gregorian calendar
   5937      * fields->millis computation.  To perform a Gregorian calendar
   5938      * millis->fields computation, call computeGregorianFields().
   5939      * @param year extended Gregorian year
   5940      * @param month zero-based Gregorian month
   5941      * @return the Julian day number of the day before the first
   5942      * day of the given month in the given extended year
   5943      * @see #computeGregorianFields
   5944      * @stable ICU 2.0
   5945      */
   5946     protected int computeGregorianMonthStart(int year, int month) {
   5947 
   5948         // If the month is out of range, adjust it into range, and
   5949         // modify the extended year value accordingly.
   5950         if (month < 0 || month > 11) {
   5951             int[] rem = new int[1];
   5952             year += floorDivide(month, 12, rem);
   5953             month = rem[0];
   5954         }
   5955 
   5956         boolean isLeap = (year%4 == 0) && ((year%100 != 0) || (year%400 == 0));
   5957         int y = year - 1;
   5958         // This computation is actually ... + (JAN_1_1_JULIAN_DAY - 3) + 2.
   5959         // Add 2 because Gregorian calendar starts 2 days after Julian
   5960         // calendar.
   5961         int julianDay = 365*y + floorDivide(y, 4) - floorDivide(y, 100) +
   5962                 floorDivide(y, 400) + JAN_1_1_JULIAN_DAY - 1;
   5963 
   5964         // At this point julianDay indicates the day BEFORE the first day
   5965         // of January 1, <eyear> of the Gregorian calendar.
   5966         if (month != 0) {
   5967             julianDay += GREGORIAN_MONTH_COUNT[month][isLeap?3:2];
   5968         }
   5969 
   5970         return julianDay;
   5971     }
   5972 
   5973     //----------------------------------------------------------------------
   5974     // Subclass API
   5975     // For subclasses to override
   5976     //----------------------------------------------------------------------
   5977 
   5978     // (The following method is not called because all existing subclasses
   5979     // override it.  2003-06-11 ICU 2.6 Alan)
   5980     ///CLOVER:OFF
   5981     /**
   5982      * Subclasses may override this method to compute several fields
   5983      * specific to each calendar system.  These are:
   5984      *
   5985      * <ul><li>ERA
   5986      * <li>YEAR
   5987      * <li>MONTH
   5988      * <li>DAY_OF_MONTH
   5989      * <li>DAY_OF_YEAR
   5990      * <li>EXTENDED_YEAR</ul>
   5991      *
   5992      * Subclasses can refer to the DAY_OF_WEEK and DOW_LOCAL fields, which
   5993      * will be set when this method is called.  Subclasses can also call
   5994      * the getGregorianXxx() methods to obtain Gregorian calendar
   5995      * equivalents for the given Julian day.
   5996      *
   5997      * <p>In addition, subclasses should compute any subclass-specific
   5998      * fields, that is, fields from BASE_FIELD_COUNT to
   5999      * getFieldCount() - 1.
   6000      *
   6001      * <p>The default implementation in <code>Calendar</code> implements
   6002      * a pure proleptic Gregorian calendar.
   6003      * @stable ICU 2.0
   6004      */
   6005     protected void handleComputeFields(int julianDay) {
   6006         internalSet(MONTH, getGregorianMonth());
   6007         internalSet(DAY_OF_MONTH, getGregorianDayOfMonth());
   6008         internalSet(DAY_OF_YEAR, getGregorianDayOfYear());
   6009         int eyear = getGregorianYear();
   6010         internalSet(EXTENDED_YEAR, eyear);
   6011         int era = GregorianCalendar.AD;
   6012         if (eyear < 1) {
   6013             era = GregorianCalendar.BC;
   6014             eyear = 1 - eyear;
   6015         }
   6016         internalSet(ERA, era);
   6017         internalSet(YEAR, eyear);
   6018     }
   6019     ///CLOVER:ON
   6020 
   6021     //----------------------------------------------------------------------
   6022     // Subclass API
   6023     // For subclasses to call
   6024     //----------------------------------------------------------------------
   6025 
   6026     /**
   6027      * Returns the extended year on the Gregorian calendar as computed by
   6028      * <code>computeGregorianFields()</code>.
   6029      * @see #computeGregorianFields
   6030      * @stable ICU 2.0
   6031      */
   6032     protected final int getGregorianYear() {
   6033         return gregorianYear;
   6034     }
   6035 
   6036     /**
   6037      * Returns the month (0-based) on the Gregorian calendar as computed by
   6038      * <code>computeGregorianFields()</code>.
   6039      * @see #computeGregorianFields
   6040      * @stable ICU 2.0
   6041      */
   6042     protected final int getGregorianMonth() {
   6043         return gregorianMonth;
   6044     }
   6045 
   6046     /**
   6047      * Returns the day of year (1-based) on the Gregorian calendar as
   6048      * computed by <code>computeGregorianFields()</code>.
   6049      * @see #computeGregorianFields
   6050      * @stable ICU 2.0
   6051      */
   6052     protected final int getGregorianDayOfYear() {
   6053         return gregorianDayOfYear;
   6054     }
   6055 
   6056     /**
   6057      * Returns the day of month (1-based) on the Gregorian calendar as
   6058      * computed by <code>computeGregorianFields()</code>.
   6059      * @see #computeGregorianFields
   6060      * @stable ICU 2.0
   6061      */
   6062     protected final int getGregorianDayOfMonth() {
   6063         return gregorianDayOfMonth;
   6064     }
   6065 
   6066     /**
   6067      * {@icu} Returns the number of fields defined by this calendar.  Valid field
   6068      * arguments to <code>set()</code> and <code>get()</code> are
   6069      * <code>0..getFieldCount()-1</code>.
   6070      * @stable ICU 2.0
   6071      */
   6072     public final int getFieldCount() {
   6073         return fields.length;
   6074     }
   6075 
   6076     /**
   6077      * Set a field to a value.  Subclasses should use this method when
   6078      * computing fields.  It sets the time stamp in the
   6079      * <code>stamp[]</code> array to <code>INTERNALLY_SET</code>.  If a
   6080      * field that may not be set by subclasses is passed in, an
   6081      * <code>IllegalArgumentException</code> is thrown.  This prevents
   6082      * subclasses from modifying fields that are intended to be
   6083      * calendar-system invariant.
   6084      * @stable ICU 2.0
   6085      */
   6086     protected final void internalSet(int field, int value) {
   6087         if (((1 << field) & internalSetMask) == 0) {
   6088             throw new IllegalStateException("Subclass cannot set " +
   6089                     fieldName(field));
   6090         }
   6091         fields[field] = value;
   6092         stamp[field] = INTERNALLY_SET;
   6093     }
   6094 
   6095     private static final int[][] GREGORIAN_MONTH_COUNT = {
   6096         //len len2   st  st2
   6097         {  31,  31,   0,   0 }, // Jan
   6098         {  28,  29,  31,  31 }, // Feb
   6099         {  31,  31,  59,  60 }, // Mar
   6100         {  30,  30,  90,  91 }, // Apr
   6101         {  31,  31, 120, 121 }, // May
   6102         {  30,  30, 151, 152 }, // Jun
   6103         {  31,  31, 181, 182 }, // Jul
   6104         {  31,  31, 212, 213 }, // Aug
   6105         {  30,  30, 243, 244 }, // Sep
   6106         {  31,  31, 273, 274 }, // Oct
   6107         {  30,  30, 304, 305 }, // Nov
   6108         {  31,  31, 334, 335 }  // Dec
   6109         // len  length of month
   6110         // len2 length of month in a leap year
   6111         // st   days in year before start of month
   6112         // st2  days in year before month in leap year
   6113     };
   6114 
   6115     /**
   6116      * Determines if the given year is a leap year. Returns true if the
   6117      * given year is a leap year.
   6118      * @param year the given year.
   6119      * @return true if the given year is a leap year; false otherwise.
   6120      * @stable ICU 2.0
   6121      */
   6122     protected static final boolean isGregorianLeapYear(int year) {
   6123         return (year%4 == 0) && ((year%100 != 0) || (year%400 == 0));
   6124     }
   6125 
   6126     /**
   6127      * Returns the length of a month of the Gregorian calendar.
   6128      * @param y the extended year
   6129      * @param m the 0-based month number
   6130      * @return the number of days in the given month
   6131      * @stable ICU 2.0
   6132      */
   6133     protected static final int gregorianMonthLength(int y, int m) {
   6134         return GREGORIAN_MONTH_COUNT[m][isGregorianLeapYear(y)?1:0];
   6135     }
   6136 
   6137     /**
   6138      * Returns the length of a previous month of the Gregorian calendar.
   6139      * @param y the extended year
   6140      * @param m the 0-based month number
   6141      * @return the number of days in the month previous to the given month
   6142      * @stable ICU 2.0
   6143      */
   6144     protected static final int gregorianPreviousMonthLength(int y, int m) {
   6145         return (m > 0) ? gregorianMonthLength(y, m-1) : 31;
   6146     }
   6147 
   6148     /**
   6149      * Divide two long integers, returning the floor of the quotient.
   6150      * <p>
   6151      * Unlike the built-in division, this is mathematically well-behaved.
   6152      * E.g., <code>-1/4</code> => 0
   6153      * but <code>floorDivide(-1,4)</code> => -1.
   6154      * @param numerator the numerator
   6155      * @param denominator a divisor which must be > 0
   6156      * @return the floor of the quotient.
   6157      * @stable ICU 2.0
   6158      */
   6159     protected static final long floorDivide(long numerator, long denominator) {
   6160         // We do this computation in order to handle
   6161         // a numerator of Long.MIN_VALUE correctly
   6162         return (numerator >= 0) ?
   6163                 numerator / denominator :
   6164                     ((numerator + 1) / denominator) - 1;
   6165     }
   6166 
   6167     /**
   6168      * Divide two integers, returning the floor of the quotient.
   6169      * <p>
   6170      * Unlike the built-in division, this is mathematically well-behaved.
   6171      * E.g., <code>-1/4</code> => 0
   6172      * but <code>floorDivide(-1,4)</code> => -1.
   6173      * @param numerator the numerator
   6174      * @param denominator a divisor which must be > 0
   6175      * @return the floor of the quotient.
   6176      * @stable ICU 2.0
   6177      */
   6178     protected static final int floorDivide(int numerator, int denominator) {
   6179         // We do this computation in order to handle
   6180         // a numerator of Integer.MIN_VALUE correctly
   6181         return (numerator >= 0) ?
   6182                 numerator / denominator :
   6183                     ((numerator + 1) / denominator) - 1;
   6184     }
   6185 
   6186     /**
   6187      * Divide two integers, returning the floor of the quotient, and
   6188      * the modulus remainder.
   6189      * <p>
   6190      * Unlike the built-in division, this is mathematically well-behaved.
   6191      * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1,
   6192      * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 3.
   6193      * @param numerator the numerator
   6194      * @param denominator a divisor which must be > 0
   6195      * @param remainder an array of at least one element in which the value
   6196      * <code>numerator mod denominator</code> is returned. Unlike <code>numerator
   6197      * % denominator</code>, this will always be non-negative.
   6198      * @return the floor of the quotient.
   6199      * @stable ICU 2.0
   6200      */
   6201     protected static final int floorDivide(int numerator, int denominator, int[] remainder) {
   6202         if (numerator >= 0) {
   6203             remainder[0] = numerator % denominator;
   6204             return numerator / denominator;
   6205         }
   6206         int quotient = ((numerator + 1) / denominator) - 1;
   6207         remainder[0] = numerator - (quotient * denominator);
   6208         return quotient;
   6209     }
   6210 
   6211     /**
   6212      * Divide two integers, returning the floor of the quotient, and
   6213      * the modulus remainder.
   6214      * <p>
   6215      * Unlike the built-in division, this is mathematically well-behaved.
   6216      * E.g., <code>-1/4</code> => 0 and <code>-1%4</code> => -1,
   6217      * but <code>floorDivide(-1,4)</code> => -1 with <code>remainder[0]</code> => 3.
   6218      * @param numerator the numerator
   6219      * @param denominator a divisor which must be > 0
   6220      * @param remainder an array of at least one element in which the value
   6221      * <code>numerator mod denominator</code> is returned. Unlike <code>numerator
   6222      * % denominator</code>, this will always be non-negative.
   6223      * @return the floor of the quotient.
   6224      * @stable ICU 2.0
   6225      */
   6226     protected static final int floorDivide(long numerator, int denominator, int[] remainder) {
   6227         if (numerator >= 0) {
   6228             remainder[0] = (int)(numerator % denominator);
   6229             return (int)(numerator / denominator);
   6230         }
   6231         int quotient = (int)(((numerator + 1) / denominator) - 1);
   6232         remainder[0] = (int)(numerator - ((long)quotient * denominator));
   6233         return quotient;
   6234     }
   6235 
   6236     private static final String[] FIELD_NAME = {
   6237         "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH",
   6238         "DAY_OF_MONTH", "DAY_OF_YEAR", "DAY_OF_WEEK",
   6239         "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", "HOUR_OF_DAY",
   6240         "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET",
   6241         "DST_OFFSET", "YEAR_WOY", "DOW_LOCAL", "EXTENDED_YEAR",
   6242         "JULIAN_DAY", "MILLISECONDS_IN_DAY",
   6243     };
   6244 
   6245     /**
   6246      * Returns a string name for a field, for debugging and exceptions.
   6247      * @stable ICU 2.0
   6248      */
   6249     protected String fieldName(int field) {
   6250         try {
   6251             return FIELD_NAME[field];
   6252         } catch (ArrayIndexOutOfBoundsException e) {
   6253             return "Field " + field;
   6254         }
   6255     }
   6256 
   6257     /**
   6258      * Converts time as milliseconds to Julian day.
   6259      * @param millis the given milliseconds.
   6260      * @return the Julian day number.
   6261      * @stable ICU 2.0
   6262      */
   6263     protected static final int millisToJulianDay(long millis) {
   6264         return (int) (EPOCH_JULIAN_DAY + floorDivide(millis, ONE_DAY));
   6265     }
   6266 
   6267     /**
   6268      * Converts Julian day to time as milliseconds.
   6269      * @param julian the given Julian day number.
   6270      * @return time as milliseconds.
   6271      * @stable ICU 2.0
   6272      */
   6273     protected static final long julianDayToMillis(int julian) {
   6274         return (julian - EPOCH_JULIAN_DAY) * ONE_DAY;
   6275     }
   6276 
   6277     /**
   6278      * Returns the day of week, from SUNDAY to SATURDAY, given a Julian day.
   6279      * @stable ICU 2.0
   6280      */
   6281     protected static final int julianDayToDayOfWeek(int julian) {
   6282         // If julian is negative, then julian%7 will be negative, so we adjust
   6283         // accordingly.  Julian day 0 is Monday.
   6284         int dayOfWeek = (julian + MONDAY) % 7;
   6285         if (dayOfWeek < SUNDAY) {
   6286             dayOfWeek += 7;
   6287         }
   6288         return dayOfWeek;
   6289     }
   6290 
   6291     /**
   6292      * Returns the current milliseconds without recomputing.
   6293      * @stable ICU 2.0
   6294      */
   6295     protected final long internalGetTimeInMillis() {
   6296         return time;
   6297     }
   6298 
   6299     /**
   6300      * {@icu} Returns the calendar type name string for this Calendar object.
   6301      * The returned string is the legacy ICU calendar attribute value,
   6302      * for example, "gregorian" or "japanese".
   6303      *
   6304      * <p>See type="old type name" for the calendar attribute of locale IDs
   6305      * at http://www.unicode.org/reports/tr35/#Key_Type_Definitions
   6306      *
   6307      * @return legacy calendar type name string
   6308      * @stable ICU 3.8
   6309      */
   6310     public String getType() {
   6311         return "unknown";
   6312     }
   6313 
   6314     /**
   6315      * Returns if two digit representation of year in this calendar type
   6316      * customarily implies a default century (i.e. 03 -> 2003).
   6317      * The default implementation returns <code>true</code>. A subclass may
   6318      * return <code>false</code> if such practice is not applicable (for example,
   6319      * Chinese calendar and Japanese calendar).
   6320      *
   6321      * @return <code>true<code> if this calendar has a default century.
   6322      * @internal
   6323      * @deprecated This API is ICU internal only.
   6324      */
   6325     @Deprecated
   6326     public boolean haveDefaultCentury() {
   6327         return true;
   6328     }
   6329 
   6330     // -------- BEGIN ULocale boilerplate --------
   6331 
   6332     /**
   6333      * {@icu} Returns the locale that was used to create this object, or null.
   6334      * This may may differ from the locale requested at the time of
   6335      * this object's creation.  For example, if an object is created
   6336      * for locale <tt>en_US_CALIFORNIA</tt>, the actual data may be
   6337      * drawn from <tt>en</tt> (the <i>actual</i> locale), and
   6338      * <tt>en_US</tt> may be the most specific locale that exists (the
   6339      * <i>valid</i> locale).
   6340      *
   6341      * <p>Note: This method will be implemented in ICU 3.0; ICU 2.8
   6342      * contains a partial preview implementation.  The * <i>actual</i>
   6343      * locale is returned correctly, but the <i>valid</i> locale is
   6344      * not, in most cases.
   6345      * @param type type of information requested, either {@link
   6346      * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link
   6347      * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.
   6348      * @return the information specified by <i>type</i>, or null if
   6349      * this object was not constructed from locale data.
   6350      * @see com.ibm.icu.util.ULocale
   6351      * @see com.ibm.icu.util.ULocale#VALID_LOCALE
   6352      * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
   6353      * @draft ICU 2.8 (retain)
   6354      * @provisional This API might change or be removed in a future release.
   6355      */
   6356     public final ULocale getLocale(ULocale.Type type) {
   6357         return type == ULocale.ACTUAL_LOCALE ?
   6358                 this.actualLocale : this.validLocale;
   6359     }
   6360 
   6361     /**
   6362      * Set information about the locales that were used to create this
   6363      * object.  If the object was not constructed from locale data,
   6364      * both arguments should be set to null.  Otherwise, neither
   6365      * should be null.  The actual locale must be at the same level or
   6366      * less specific than the valid locale.  This method is intended
   6367      * for use by factories or other entities that create objects of
   6368      * this class.
   6369      * @param valid the most specific locale containing any resource
   6370      * data, or null
   6371      * @param actual the locale containing data used to construct this
   6372      * object, or null
   6373      * @see com.ibm.icu.util.ULocale
   6374      * @see com.ibm.icu.util.ULocale#VALID_LOCALE
   6375      * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
   6376      */
   6377     final void setLocale(ULocale valid, ULocale actual) {
   6378         // Change the following to an assertion later
   6379         if ((valid == null) != (actual == null)) {
   6380             ///CLOVER:OFF
   6381             throw new IllegalArgumentException();
   6382             ///CLOVER:ON
   6383         }
   6384         // Another check we could do is that the actual locale is at
   6385         // the same level or less specific than the valid locale.
   6386         this.validLocale = valid;
   6387         this.actualLocale = actual;
   6388     }
   6389 
   6390     /**
   6391      * The most specific locale containing any resource data, or null.
   6392      * @see com.ibm.icu.util.ULocale
   6393      */
   6394     private ULocale validLocale;
   6395 
   6396     /**
   6397      * The locale containing data used to construct this object, or
   6398      * null.
   6399      * @see com.ibm.icu.util.ULocale
   6400      */
   6401     private ULocale actualLocale;
   6402 
   6403     // -------- END ULocale boilerplate --------
   6404 }
   6405