// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
 *   Copyright (C) 1996-2016, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 */

package com.ibm.icu.util;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import java.util.MissingResourceException;

import com.ibm.icu.impl.CalType;
import com.ibm.icu.impl.CalendarUtil;
import com.ibm.icu.impl.ICUCache;
import com.ibm.icu.impl.ICUData;
import com.ibm.icu.impl.ICUResourceBundle;
import com.ibm.icu.impl.SimpleCache;
import com.ibm.icu.impl.SimpleFormatterImpl;
import com.ibm.icu.impl.SoftCache;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.DateFormatSymbols;
import com.ibm.icu.text.DateTimePatternGenerator;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.ULocale.Category;

/**
 * {@icuenhanced java.util.Calendar}.{@icu _usage_}
 *
 * <p><code>Calendar</code> is an abstract base class for converting between
 * a <code>Date</code> object and a set of integer fields such as
 * <code>YEAR</code>, <code>MONTH</code>, <code>DAY</code>, <code>HOUR</code>,
 * and so on. (A <code>Date</code> object represents a specific instant in
 * time with millisecond precision. See
 * {@link Date}
 * for information about the <code>Date</code> class.)
 *
 * <p>Subclasses of <code>Calendar</code> interpret a <code>Date</code>
 * according to the rules of a specific calendar system.  ICU4J contains
 * several subclasses implementing different international calendar systems.
 *
 * <p>
 * Like other locale-sensitive classes, <code>Calendar</code> provides a
 * class method, <code>getInstance</code>, for getting a generally useful
 * object of this type. <code>Calendar</code>'s <code>getInstance</code> method
 * returns a calendar of a type appropriate to the locale, whose
 * time fields have been initialized with the current date and time:
 * <blockquote>
 * <pre>Calendar rightNow = Calendar.getInstance()</pre>
 * </blockquote>
 *
 * <p>When a <code>ULocale</code> is used by <code>getInstance</code>, its
 * '<code>calendar</code>' tag and value are retrieved if present.  If a recognized
 * value is supplied, a calendar is provided and configured as appropriate.
 * Currently recognized tags are "buddhist", "chinese", "coptic", "ethiopic",
 * "gregorian", "hebrew", "islamic", "islamic-civil", "japanese", and "roc".  For
 * example: <blockquote>
 * <pre>Calendar cal = Calendar.getInstance(new ULocale("en_US@calendar=japanese"));</pre>
 * </blockquote> will return an instance of JapaneseCalendar (using en_US conventions for
 * minimum days in first week, start day of week, et cetera).
 *
 * <p>A <code>Calendar</code> object can produce all the time field values
 * needed to implement the date-time formatting for a particular language and
 * calendar style (for example, Japanese-Gregorian, Japanese-Traditional).
 * <code>Calendar</code> defines the range of values returned by certain fields,
 * as well as their meaning.  For example, the first month of the year has value
 * <code>MONTH</code> == <code>JANUARY</code> for all calendars.  Other values
 * are defined by the concrete subclass, such as <code>ERA</code> and
 * <code>YEAR</code>.  See individual field documentation and subclass
 * documentation for details.
 *
 * <p>When a <code>Calendar</code> is <em>lenient</em>, it accepts a wider range
 * of field values than it produces.  For example, a lenient
 * <code>GregorianCalendar</code> interprets <code>MONTH</code> ==
 * <code>JANUARY</code>, <code>DAY_OF_MONTH</code> == 32 as February 1.  A
 * non-lenient <code>GregorianCalendar</code> throws an exception when given
 * out-of-range field settings.  When calendars recompute field values for
 * return by <code>get()</code>, they normalize them.  For example, a
 * <code>GregorianCalendar</code> always produces <code>DAY_OF_MONTH</code>
 * values between 1 and the length of the month.
 *
 * <p><code>Calendar</code> defines a locale-specific seven day week using two
 * parameters: the first day of the week and the minimal days in first week
 * (from 1 to 7).  These numbers are taken from the locale resource data when a
 * <code>Calendar</code> is constructed.  They may also be specified explicitly
 * through the API.
 *
 * <p>When setting or getting the <code>WEEK_OF_MONTH</code> or
 * <code>WEEK_OF_YEAR</code> fields, <code>Calendar</code> must determine the
 * first week of the month or year as a reference point.  The first week of a
 * month or year is defined as the earliest seven day period beginning on
 * <code>getFirstDayOfWeek()</code> and containing at least
 * <code>getMinimalDaysInFirstWeek()</code> days of that month or year.  Weeks
 * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow
 * it.  Note that the normalized numbering returned by <code>get()</code> may be
 * different.  For example, a specific <code>Calendar</code> subclass may
 * designate the week before week 1 of a year as week <em>n</em> of the previous
 * year.
 *
 * <p> When computing a <code>Date</code> from time fields, some special
 * circumstances may arise: there may be insufficient information to compute the
 * <code>Date</code> (such as only year and month but no day in the month),
 * there may be inconsistent information (such as "Tuesday, July 15, 1996" --
 * July 15, 1996 is actually a Monday), or the input time might be ambiguous
 * because of time zone transition.
 *
 * <p><strong>Insufficient information.</strong> The calendar will use default
 * information to specify the missing fields. This may vary by calendar; for
 * the Gregorian calendar, the default for a field is the same as that of the
 * start of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc.
 *
 * <p><strong>Inconsistent information.</strong> If fields conflict, the calendar
 * will give preference to fields set more recently. For example, when
 * determining the day, the calendar will look for one of the following
 * combinations of fields.  The most recent combination, as determined by the
 * most recently set single field, will be used.
 *
 * <blockquote>
 * <pre>
 * MONTH + DAY_OF_MONTH
 * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
 * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
 * DAY_OF_YEAR
 * DAY_OF_WEEK + WEEK_OF_YEAR</pre>
 * </blockquote>
 *
 * For the time of day:
 *
 * <blockquote>
 * <pre>
 * HOUR_OF_DAY
 * AM_PM + HOUR</pre>
 * </blockquote>
 *
 * <p><strong>Ambiguous Wall Clock Time.</strong> When time offset from UTC has
 * changed, it produces an ambiguous time slot around the transition. For example,
 * many US locations observe daylight saving time. On the date switching to daylight
 * saving time in US, wall clock time jumps from 12:59 AM (standard) to 2:00 AM
 * (daylight). Therefore, wall clock time from 1:00 AM to 1:59 AM do not exist on
 * the date. When the input wall time fall into this missing time slot, the ICU
 * Calendar resolves the time using the UTC offset before the transition by default.
 * In this example, 1:30 AM is interpreted as 1:30 AM standard time (non-exist),
 * so the final result will be 2:30 AM daylight time.
 *
 * <p>On the date switching back to standard time, wall clock time is moved back one
 * hour at 2:00 AM. So wall clock time from 1:00 AM to 1:59 AM occur twice. In this
 * case, the ICU Calendar resolves the time using the UTC offset after the transition
 * by default. For example, 1:30 AM on the date is resolved as 1:30 AM standard time.
 *
 * <p>Ambiguous wall clock time resolution behaviors can be customized by Calendar APIs
 * {@link #setRepeatedWallTimeOption(int)} and {@link #setSkippedWallTimeOption(int)}.
 * These methods are available in ICU 49 or later versions.
 *
 * <p><strong>Note:</strong> for some non-Gregorian calendars, different
 * fields may be necessary for complete disambiguation. For example, a full
 * specification of the historial Arabic astronomical calendar requires year,
 * month, day-of-month <em>and</em> day-of-week in some cases.
 *
 * <p><strong>Note:</strong> There are certain possible ambiguities in
 * interpretation of certain singular times, which are resolved in the
 * following ways:
 * <ol>
 *     <li> 24:00:00 "belongs" to the following day. That is,
 *          23:59 on Dec 31, 1969 &lt; 24:00 on Jan 1, 1970 &lt; 24:01:00 on Jan 1, 1970
 *
 *     <li> Although historically not precise, midnight also belongs to "am",
 *          and noon belongs to "pm", so on the same day,
 *          12:00 am (midnight) &lt; 12:01 am, and 12:00 pm (noon) &lt; 12:01 pm
 * </ol>
 *
 * <p>The date or time format strings are not part of the definition of a
 * calendar, as those must be modifiable or overridable by the user at
 * runtime. Use {@link DateFormat}
 * to format dates.
 *
 * <p><strong>Field manipulation methods</strong></p>
 *
 * <p><code>Calendar</code> fields can be changed using three methods:
 * <code>set()</code>, <code>add()</code>, and <code>roll()</code>.</p>
 *
 * <p><strong><code>set(f, value)</code></strong> changes field
 * <code>f</code> to <code>value</code>.  In addition, it sets an
 * internal member variable to indicate that field <code>f</code> has
 * been changed. Although field <code>f</code> is changed immediately,
 * the calendar's milliseconds is not recomputed until the next call to
 * <code>get()</code>, <code>getTime()</code>, or
 * <code>getTimeInMillis()</code> is made. Thus, multiple calls to
 * <code>set()</code> do not trigger multiple, unnecessary
 * computations. As a result of changing a field using
 * <code>set()</code>, other fields may also change, depending on the
 * field, the field value, and the calendar system. In addition,
 * <code>get(f)</code> will not necessarily return <code>value</code>
 * after the fields have been recomputed. The specifics are determined by
 * the concrete calendar class.</p>
 *
 * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
 * originally set to August 31, 1999. Calling <code>set(Calendar.MONTH,
 * Calendar.SEPTEMBER)</code> sets the calendar to September 31,
 * 1999. This is a temporary internal representation that resolves to
 * October 1, 1999 if <code>getTime()</code>is then called. However, a
 * call to <code>set(Calendar.DAY_OF_MONTH, 30)</code> before the call to
 * <code>getTime()</code> sets the calendar to September 30, 1999, since
 * no recomputation occurs after <code>set()</code> itself.</p>
 *
 * <p><strong><code>add(f, delta)</code></strong> adds <code>delta</code>
 * to field <code>f</code>.  This is equivalent to calling <code>set(f,
 * get(f) + delta)</code> with two adjustments:</p>
 *
 * <blockquote>
 *   <p><strong>Add rule 1</strong>. The value of field <code>f</code>
 *   after the call minus the value of field <code>f</code> before the
 *   call is <code>delta</code>, modulo any overflow that has occurred in
 *   field <code>f</code>. Overflow occurs when a field value exceeds its
 *   range and, as a result, the next larger field is incremented or
 *   decremented and the field value is adjusted back into its range.</p>
 *
 *   <p><strong>Add rule 2</strong>. If a smaller field is expected to be
 *   invariant, but &nbsp; it is impossible for it to be equal to its
 *   prior value because of changes in its minimum or maximum after field
 *   <code>f</code> is changed, then its value is adjusted to be as close
 *   as possible to its expected value. A smaller field represents a
 *   smaller unit of time. <code>HOUR</code> is a smaller field than
 *   <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields
 *   that are not expected to be invariant. The calendar system
 *   determines what fields are expected to be invariant.</p>
 * </blockquote>
 *
 * <p>In addition, unlike <code>set()</code>, <code>add()</code> forces
 * an immediate recomputation of the calendar's milliseconds and all
 * fields.</p>
 *
 * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
 * originally set to August 31, 1999. Calling <code>add(Calendar.MONTH,
 * 13)</code> sets the calendar to September 30, 2000. <strong>Add rule
 * 1</strong> sets the <code>MONTH</code> field to September, since
 * adding 13 months to August gives September of the next year. Since
 * <code>DAY_OF_MONTH</code> cannot be 31 in September in a
 * <code>GregorianCalendar</code>, <strong>add rule 2</strong> sets the
 * <code>DAY_OF_MONTH</code> to 30, the closest possible value. Although
 * it is a smaller field, <code>DAY_OF_WEEK</code> is not adjusted by
 * rule 2, since it is expected to change when the month changes in a
 * <code>GregorianCalendar</code>.</p>
 *
 * <p><strong><code>roll(f, delta)</code></strong> adds
 * <code>delta</code> to field <code>f</code> without changing larger
 * fields. This is equivalent to calling <code>add(f, delta)</code> with
 * the following adjustment:</p>
 *
 * <blockquote>
 *   <p><strong>Roll rule</strong>. Larger fields are unchanged after the
 *   call. A larger field represents a larger unit of
 *   time. <code>DAY_OF_MONTH</code> is a larger field than
 *   <code>HOUR</code>.</p>
 * </blockquote>
 *
 * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
 * originally set to August 31, 1999. Calling <code>roll(Calendar.MONTH,
 * 8)</code> sets the calendar to April 30, <strong>1999</strong>.  Add
 * rule 1 sets the <code>MONTH</code> field to April. Using a
 * <code>GregorianCalendar</code>, the <code>DAY_OF_MONTH</code> cannot
 * be 31 in the month April. Add rule 2 sets it to the closest possible
 * value, 30. Finally, the <strong>roll rule</strong> maintains the
 * <code>YEAR</code> field value of 1999.</p>
 *
 * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
 * originally set to Sunday June 6, 1999. Calling
 * <code>roll(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to
 * Tuesday June 1, 1999, whereas calling
 * <code>add(Calendar.WEEK_OF_MONTH, -1)</code> sets the calendar to
 * Sunday May 30, 1999. This is because the roll rule imposes an
 * additional constraint: The <code>MONTH</code> must not change when the
 * <code>WEEK_OF_MONTH</code> is rolled. Taken together with add rule 1,
 * the resultant date must be between Tuesday June 1 and Saturday June
 * 5. According to add rule 2, the <code>DAY_OF_WEEK</code>, an invariant
 * when changing the <code>WEEK_OF_MONTH</code>, is set to Tuesday, the
 * closest possible value to Sunday (where Sunday is the first day of the
 * week).</p>
 *
 * <p><strong>Usage model</strong>. To motivate the behavior of
 * <code>add()</code> and <code>roll()</code>, consider a user interface
 * component with increment and decrement buttons for the month, day, and
 * year, and an underlying <code>GregorianCalendar</code>. If the
 * interface reads January 31, 1999 and the user presses the month
 * increment button, what should it read? If the underlying
 * implementation uses <code>set()</code>, it might read March 3, 1999. A
 * better result would be February 28, 1999. Furthermore, if the user
 * presses the month increment button again, it should read March 31,
 * 1999, not March 28, 1999. By saving the original date and using either
 * <code>add()</code> or <code>roll()</code>, depending on whether larger
 * fields should be affected, the user interface can behave as most users
 * will intuitively expect.</p>
 *
 * <p><b>Note:</b> You should always use {@link #roll roll} and {@link #add add} rather
 * than attempting to perform arithmetic operations directly on the fields
 * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
 * to have fields with non-linear behavior, for example missing months
 * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
 * methods will take this into account, while simple arithmetic manipulations
 * may give invalid results.
 *
 * <p><big><big><b>Calendar Architecture in ICU4J</b></big></big></p>
 *
 * <p>Recently the implementation of <code>Calendar</code> has changed
 * significantly in order to better support subclassing. The original
 * <code>Calendar</code> class was designed to support subclassing, but
 * it had only one implemented subclass, <code>GregorianCalendar</code>.
 * With the implementation of several new calendar subclasses, including
 * the <code>BuddhistCalendar</code>, <code>ChineseCalendar</code>,
 * <code>HebrewCalendar</code>, <code>IslamicCalendar</code>, and
 * <code>JapaneseCalendar</code>, the subclassing API has been reworked
 * thoroughly. This section details the new subclassing API and other
 * ways in which <code>com.ibm.icu.util.Calendar</code> differs from
 * <code>java.util.Calendar</code>.
 * </p>
 *
 * <p><big><b>Changes</b></big></p>
 *
 * <p>Overview of changes between the classic <code>Calendar</code>
 * architecture and the new architecture.
 *
 * <ul>
 *
 *   <li>The <code>fields[]</code> array is <code>private</code> now
 *     instead of <code>protected</code>.  Subclasses must access it
 *     using the methods {@link #internalSet} and
 *     {@link #internalGet}.  <b>Motivation:</b> Subclasses should
 *     not directly access data members.</li>
 *
 *   <li>The <code>time</code> long word is <code>private</code> now
 *     instead of <code>protected</code>.  Subclasses may access it using
 *     the method {@link #internalGetTimeInMillis}, which does not
 *     provoke an update. <b>Motivation:</b> Subclasses should not
 *     directly access data members.</li>
 *
 *   <li>The scope of responsibility of subclasses has been drastically
 *     reduced. As much functionality as possible is implemented in the
 *     <code>Calendar</code> base class. As a result, it is much easier
 *     to subclass <code>Calendar</code>. <b>Motivation:</b> Subclasses
 *     should not have to reimplement common code. Certain behaviors are
 *     common across calendar systems: The definition and behavior of
 *     week-related fields and time fields, the arithmetic
 *     ({@link #add(int, int) add} and {@link #roll(int, int) roll}) behavior of many
 *     fields, and the field validation system.</li>
 *
 *   <li>The subclassing API has been completely redesigned.</li>
 *
 *   <li>The <code>Calendar</code> base class contains some Gregorian
 *     calendar algorithmic support that subclasses can use (specifically
 *     in {@link #handleComputeFields}).  Subclasses can use the
 *     methods <code>getGregorianXxx()</code> to obtain precomputed
 *     values. <b>Motivation:</b> This is required by all
 *     <code>Calendar</code> subclasses in order to implement consistent
 *     time zone behavior, and Gregorian-derived systems can use the
 *     already computed data.</li>
 *
 *   <li>The <code>FIELD_COUNT</code> constant has been removed. Use
 *     {@link #getFieldCount}.  In addition, framework API has been
 *     added to allow subclasses to define additional fields.
 *     <b>Motivation: </b>The number of fields is not constant across
 *     calendar systems.</li>
 *
 *   <li>The range of handled dates has been narrowed from +/-
 *     ~300,000,000 years to +/- ~5,000,000 years. In practical terms
 *     this should not affect clients. However, it does mean that client
 *     code cannot be guaranteed well-behaved results with dates such as
 *     <code>Date(Long.MIN_VALUE)</code> or
 *     <code>Date(Long.MAX_VALUE)</code>. Instead, the
 *     <code>Calendar</code> protected constants should be used.
 *     <b>Motivation:</b> With
 *     the addition of the {@link #JULIAN_DAY} field, Julian day
 *     numbers must be restricted to a 32-bit <code>int</code>.  This
 *     restricts the overall supported range. Furthermore, restricting
 *     the supported range simplifies the computations by removing
 *     special case code that was used to accommodate arithmetic overflow
 *     at millis near <code>Long.MIN_VALUE</code> and
 *     <code>Long.MAX_VALUE</code>.</li>
 *
 *   <li>New fields are implemented: {@link #JULIAN_DAY} defines
 *     single-field specification of the
 *     date. {@link #MILLISECONDS_IN_DAY} defines a single-field
 *     specification of the wall time. {@link #DOW_LOCAL} and
 *     {@link #YEAR_WOY} implement localized day-of-week and
 *     week-of-year behavior.</li>
 *
 *   <li>Subclasses can access protected millisecond constants
 *   defined in <code>Calendar</code>.</li>
 *
 *   <li>New API has been added to support calendar-specific subclasses
 *     of <code>DateFormat</code>.</li>
 *
 *   <li>Several subclasses have been implemented, representing
 *     various international calendar systems.</li>
 *
 * </ul>
 *
 * <p><big><b>Subclass API</b></big></p>
 *
 * <p>The original <code>Calendar</code> API was based on the experience
 * of implementing a only a single subclass,
 * <code>GregorianCalendar</code>. As a result, all of the subclassing
 * kinks had not been worked out. The new subclassing API has been
 * refined based on several implemented subclasses. This includes methods
 * that must be overridden and methods for subclasses to call. Subclasses
 * no longer have direct access to <code>fields</code> and
 * <code>stamp</code>. Instead, they have new API to access
 * these. Subclasses are able to allocate the <code>fields</code> array
 * through a protected framework method; this allows subclasses to
 * specify additional fields. </p>
 *
 * <p>More functionality has been moved into the base class. The base
 * class now contains much of the computational machinery to support the
 * Gregorian calendar. This is based on two things: (1) Many calendars
 * are based on the Gregorian calendar (such as the Buddhist and Japanese
 * imperial calendars). (2) <em>All</em> calendars require basic
 * Gregorian support in order to handle timezone computations. </p>
 *
 * <p>Common computations have been moved into
 * <code>Calendar</code>. Subclasses no longer compute the week related
 * fields and the time related fields. These are commonly handled for all
 * calendars by the base class. </p>
 *
 * <p><b>Subclass computation of time <tt>=&gt;</tt> fields</b>
 *
 * <p>The {@link #ERA}, {@link #YEAR},
 * {@link #EXTENDED_YEAR}, {@link #MONTH},
 * {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields are
 * computed by the subclass, based on the Julian day. All other fields
 * are computed by <code>Calendar</code>.
 *
 * <ul>
 *
 *   <li>Subclasses should implement {@link #handleComputeFields}
 *     to compute the {@link #ERA}, {@link #YEAR},
 *     {@link #EXTENDED_YEAR}, {@link #MONTH},
 *     {@link #DAY_OF_MONTH}, and {@link #DAY_OF_YEAR} fields,
 *     based on the value of the {@link #JULIAN_DAY} field. If there
 *     are calendar-specific fields not defined by <code>Calendar</code>,
 *     they must also be computed. These are the only fields that the
 *     subclass should compute. All other fields are computed by the base
 *     class, so time and week fields behave in a consistent way across
 *     all calendars. The default version of this method in
 *     <code>Calendar</code> implements a proleptic Gregorian
 *     calendar. Within this method, subclasses may call
 *     <code>getGregorianXxx()</code> to obtain the Gregorian calendar
 *     month, day of month, and extended year for the given date.</li>
 *
 * </ul>
 *
 * <p><b>Subclass computation of fields <tt>=&gt;</tt> time</b>
 *
 * <p>The interpretation of most field values is handled entirely by
 * <code>Calendar</code>. <code>Calendar</code> determines which fields
 * are set, which are not, which are set more recently, and so on. In
 * addition, <code>Calendar</code> handles the computation of the time
 * from the time fields and handles the week-related fields. The only
 * thing the subclass must do is determine the extended year, based on
 * the year fields, and then, given an extended year and a month, it must
 * return a Julian day number.
 *
 * <ul>
 *
 *   <li>Subclasses should implement {@link #handleGetExtendedYear}
 *     to return the extended year for this calendar system, based on the
 *     {@link #YEAR}, {@link #EXTENDED_YEAR}, and any fields that
 *     the calendar system uses that are larger than a year, such as
 *     {@link #ERA}.</li>
 *
 *   <li>Subclasses should implement {@link #handleComputeMonthStart}
 *     to return the Julian day number
 *     associated with a month and extended year. This is the Julian day
 *     number of the day before the first day of the month. The month
 *     number is zero-based. This computation should not depend on any
 *     field values.</li>
 *
 * </ul>
 *
 * <p><b>Other methods</b>
 *
 * <ul>
 *
 *   <li>Subclasses should implement {@link #handleGetMonthLength}
 *     to return the number of days in a
 *     given month of a given extended year. The month number, as always,
 *     is zero-based.</li>
 *
 *   <li>Subclasses should implement {@link #handleGetYearLength}
 *     to return the number of days in the given
 *     extended year. This method is used by
 *     <tt>computeWeekFields</tt> to compute the
 *     {@link #WEEK_OF_YEAR} and {@link #YEAR_WOY} fields.</li>
 *
 *   <li>Subclasses should implement {@link #handleGetLimit}
 *     to return the protected values of a field, depending on the value of
 *     <code>limitType</code>. This method only needs to handle the
 *     fields {@link #ERA}, {@link #YEAR}, {@link #MONTH},
 *     {@link #WEEK_OF_YEAR}, {@link #WEEK_OF_MONTH},
 *     {@link #DAY_OF_MONTH}, {@link #DAY_OF_YEAR},
 *     {@link #DAY_OF_WEEK_IN_MONTH}, {@link #YEAR_WOY}, and
 *     {@link #EXTENDED_YEAR}.  Other fields are invariant (with
 *     respect to calendar system) and are handled by the base
 *     class.</li>
 *
 *   <li>Optionally, subclasses may override {@link #validateField}
 *     to check any subclass-specific fields. If the
 *     field's value is out of range, the method should throw an
 *     <code>IllegalArgumentException</code>. The method may call
 *     <code>super.validateField(field)</code> to handle fields in a
 *     generic way, that is, to compare them to the range
 *     <code>getMinimum(field)</code>..<code>getMaximum(field)</code>.</li>
 *
 *   <li>Optionally, subclasses may override
 *     {@link #handleCreateFields} to create an <code>int[]</code>
 *     array large enough to hold the calendar's fields. This is only
 *     necessary if the calendar defines additional fields beyond those
 *     defined by <code>Calendar</code>. The length of the result must be
 *     be between the base and maximum field counts.</li>
 *
 *   <li>Optionally, subclasses may override
 *     {@link #handleGetDateFormat} to create a
 *     <code>DateFormat</code> appropriate to this calendar. This is only
 *     required if a calendar subclass redefines the use of a field (for
 *     example, changes the {@link #ERA} field from a symbolic field
 *     to a numeric one) or defines an additional field.</li>
 *
 *   <li>Optionally, subclasses may override {@link #roll roll} and
 *     {@link #add add} to handle fields that are discontinuous. For
 *     example, in the Hebrew calendar the month &quot;Adar I&quot; only
 *     occurs in leap years; in other years the calendar jumps from
 *     Shevat (month #4) to Adar (month #6). The {@link
 *     HebrewCalendar#add HebrewCalendar.add} and {@link
 *     HebrewCalendar#roll HebrewCalendar.roll} methods take this into
 *     account, so that adding 1 month to Shevat gives the proper result
 *     (Adar) in a non-leap year. The protected utility method {@link
 *     #pinField pinField} is often useful when implementing these two
 *     methods. </li>
 *
 * </ul>
 *
 * <p><big><b>Normalized behavior</b></big>
 *
 * <p>The behavior of certain fields has been made consistent across all
 * calendar systems and implemented in <code>Calendar</code>.
 *
 * <ul>
 *
 *   <li>Time is normalized. Even though some calendar systems transition
 *     between days at sunset or at other times, all ICU4J calendars
 *     transition between days at <em>local zone midnight</em>.  This
 *     allows ICU4J to centralize the time computations in
 *     <code>Calendar</code> and to maintain basic correspondences
 *     between calendar systems. Affected fields: {@link #AM_PM},
 *     {@link #HOUR}, {@link #HOUR_OF_DAY}, {@link #MINUTE},
 *     {@link #SECOND}, {@link #MILLISECOND},
 *     {@link #ZONE_OFFSET}, and {@link #DST_OFFSET}.</li>
 *
 *   <li>DST behavior is normalized. Daylight savings time behavior is
 *     computed the same for all calendar systems, and depends on the
 *     value of several <code>GregorianCalendar</code> fields: the
 *     {@link #YEAR}, {@link #MONTH}, and
 *     {@link #DAY_OF_MONTH}. As a result, <code>Calendar</code>
 *     always computes these fields, even for non-Gregorian calendar
 *     systems. These fields are available to subclasses.</li>
 *
 *   <li>Weeks are normalized. Although locales define the week
 *     differently, in terms of the day on which it starts, and the
 *     designation of week number one of a month or year, they all use a
 *     common mechanism. Furthermore, the day of the week has a simple
 *     and consistent definition throughout history. For example,
 *     although the Gregorian calendar introduced a discontinuity when
 *     first instituted, the day of week was not disrupted. For this
 *     reason, the fields {@link #DAY_OF_WEEK}, <code>WEEK_OF_YEAR,
 *     WEEK_OF_MONTH</code>, {@link #DAY_OF_WEEK_IN_MONTH},
 *     {@link #DOW_LOCAL}, {@link #YEAR_WOY} are all computed in
 *     a consistent way in the base class, based on the
 *     {@link #EXTENDED_YEAR}, {@link #DAY_OF_YEAR},
 *     {@link #MONTH}, and {@link #DAY_OF_MONTH}, which are
 *     computed by the subclass.</li>
 *
 * </ul>
 *
 * <p><big><b>Supported range</b></big>
 *
 * <p>The allowable range of <code>Calendar</code> has been
 * narrowed. <code>GregorianCalendar</code> used to attempt to support
 * the range of dates with millisecond values from
 * <code>Long.MIN_VALUE</code> to <code>Long.MAX_VALUE</code>. This
 * introduced awkward constructions (hacks) which slowed down
 * performance. It also introduced non-uniform behavior at the
 * boundaries. The new <code>Calendar</code> protocol specifies the
 * maximum range of supportable dates as those having Julian day numbers
 * of <code>-0x7F000000</code> to <code>+0x7F000000</code>. This
 * corresponds to years from ~5,800,000 BCE to ~5,800,000 CE. Programmers
 * should use the protected constants in <code>Calendar</code> to
 * specify an extremely early or extremely late date.</p>
 *
 * <p><big><b>General notes</b></big>
 *
 * <ul>
 *
 *   <li>Calendars implementations are <em>proleptic</em>. For example,
 *     even though the Gregorian calendar was not instituted until the
 *     16th century, the <code>GregorianCalendar</code> class supports
 *     dates before the historical onset of the calendar by extending the
 *     calendar system backward in time. Similarly, the
 *     <code>HebrewCalendar</code> extends backward before the start of
 *     its epoch into zero and negative years. Subclasses do not throw
 *     exceptions because a date precedes the historical start of a
 *     calendar system. Instead, they implement
 *     {@link #handleGetLimit} to return appropriate limits on
 *     {@link #YEAR}, {@link #ERA}, etc. fields. Then, if the
 *     calendar is set to not be lenient, out-of-range field values will
 *     trigger an exception.</li>
 *
 *   <li>Calendar system subclasses compute a <em>extended
 *     year</em>. This differs from the {@link #YEAR} field in that
 *     it ranges over all integer values, including zero and negative
 *     values, and it encapsulates the information of the
 *     {@link #YEAR} field and all larger fields.  Thus, for the
 *     Gregorian calendar, the {@link #EXTENDED_YEAR} is computed as
 *     <code>ERA==AD ? YEAR : 1-YEAR</code>. Another example is the Mayan
 *     long count, which has years (<code>KUN</code>) and nested cycles
 *     of years (<code>KATUN</code> and <code>BAKTUN</code>). The Mayan
 *     {@link #EXTENDED_YEAR} is computed as <code>TUN + 20 * (KATUN
 *     + 20 * BAKTUN)</code>. The <code>Calendar</code> base class uses
 *     the {@link #EXTENDED_YEAR} field to compute the week-related
 *     fields.</li>
 *
 * </ul>
 *
 * @see          Date
 * @see          GregorianCalendar
 * @see          TimeZone
 * @see          DateFormat
 * @author Mark Davis, Deborah Goldsmith, Chen-Lieh Huang, Alan Liu, Laura Werner
 * @stable ICU 2.0
 */
public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {

    // Data flow in Calendar
    // ---------------------

    // The current time is represented in two ways by Calendar: as UTC
    // milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local
    // fields such as MONTH, HOUR, AM_PM, etc.  It is possible to compute the
    // millis from the fields, and vice versa.  The data needed to do this
    // conversion is encapsulated by a TimeZone object owned by the Calendar.
    // The data provided by the TimeZone object may also be overridden if the
    // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
    // keeps track of what information was most recently set by the caller, and
    // uses that to compute any other information as needed.

    // If the user sets the fields using set(), the data flow is as follows.
    // This is implemented by the Calendar subclass's computeTime() method.
    // During this process, certain fields may be ignored.  The disambiguation
    // algorithm for resolving which fields to pay attention to is described
    // above.

    //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
    //           |
    //           | Using Calendar-specific algorithm
    //           V
    //   local standard millis
    //           |
    //           | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
    //           V
    //   UTC millis (in time data member)

    // If the user sets the UTC millis using setTime(), the data flow is as
    // follows.  This is implemented by the Calendar subclass's computeFields()
    // method.

    //   UTC millis (in time data member)
    //           |
    //           | Using TimeZone getOffset()
    //           V
    //   local standard millis
    //           |
    //           | Using Calendar-specific algorithm
    //           V
    //   local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)

    // In general, a round trip from fields, through local and UTC millis, and
    // back out to fields is made when necessary.  This is implemented by the
    // complete() method.  Resolving a partial set of fields into a UTC millis
    // value allows all remaining fields to be generated from that value.  If
    // the Calendar is lenient, the fields are also renormalized to standard
    // ranges when they are regenerated.

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific
     * value; see subclass documentation.
     * @see GregorianCalendar#AD
     * @see GregorianCalendar#BC
     * @stable ICU 2.0
     */
    public final static int ERA = 0;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * year. This is a calendar-specific value; see subclass documentation.
     * @stable ICU 2.0
     */
    public final static int YEAR = 1;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * month. This is a calendar-specific value. The first month of the year is
     * <code>JANUARY</code>; the last depends on the number of months in a year.
     * @see #JANUARY
     * @see #FEBRUARY
     * @see #MARCH
     * @see #APRIL
     * @see #MAY
     * @see #JUNE
     * @see #JULY
     * @see #AUGUST
     * @see #SEPTEMBER
     * @see #OCTOBER
     * @see #NOVEMBER
     * @see #DECEMBER
     * @see #UNDECIMBER
     * @stable ICU 2.0
     */
    public final static int MONTH = 2;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * week number within the current year.  The first week of the year, as
     * defined by {@link #getFirstDayOfWeek()} and
     * {@link #getMinimalDaysInFirstWeek()}, has value 1.  Subclasses define
     * the value of {@link #WEEK_OF_YEAR} for days before the first week of
     * the year.
     * @see #getFirstDayOfWeek
     * @see #getMinimalDaysInFirstWeek
     * @stable ICU 2.0
     */
    public final static int WEEK_OF_YEAR = 3;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * week number within the current month.  The first week of the month, as
     * defined by {@link #getFirstDayOfWeek()} and
     * {@link #getMinimalDaysInFirstWeek()}, has value 1.  Subclasses define
     * the value of {@link #WEEK_OF_MONTH} for days before the first week of
     * the month.
     * @see #getFirstDayOfWeek
     * @see #getMinimalDaysInFirstWeek
     * @stable ICU 2.0
     */
    public final static int WEEK_OF_MONTH = 4;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * day of the month. This is a synonym for {@link #DAY_OF_MONTH}.
     * The first day of the month has value 1.
     * @see #DAY_OF_MONTH
     * @stable ICU 2.0
     */
    public final static int DATE = 5;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * day of the month. This is a synonym for {@link #DATE}.
     * The first day of the month has value 1.
     * @see #DATE
     * @stable ICU 2.0
     */
    public final static int DAY_OF_MONTH = 5;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the day
     * number within the current year.  The first day of the year has value 1.
     * @stable ICU 2.0
     */
    public final static int DAY_OF_YEAR = 6;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the day
     * of the week.  This field takes values {@link #SUNDAY},
     * {@link #MONDAY}, {@link #TUESDAY}, {@link #WEDNESDAY},
     * {@link #THURSDAY}, {@link #FRIDAY}, and {@link #SATURDAY}.
     * @see #SUNDAY
     * @see #MONDAY
     * @see #TUESDAY
     * @see #WEDNESDAY
     * @see #THURSDAY
     * @see #FRIDAY
     * @see #SATURDAY
     * @stable ICU 2.0
     */
    public final static int DAY_OF_WEEK = 7;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * ordinal number of the day of the week within the current month. Together
     * with the {@link #DAY_OF_WEEK} field, this uniquely specifies a day
     * within a month.  Unlike {@link #WEEK_OF_MONTH} and
     * {@link #WEEK_OF_YEAR}, this field's value does <em>not</em> depend on
     * {@link #getFirstDayOfWeek()} or
     * {@link #getMinimalDaysInFirstWeek()}.  <code>DAY_OF_MONTH 1</code>
     * through <code>7</code> always correspond to <code>DAY_OF_WEEK_IN_MONTH
     * 1</code>; <code>8</code> through <code>15</code> correspond to
     * <code>DAY_OF_WEEK_IN_MONTH 2</code>, and so on.
     * <code>DAY_OF_WEEK_IN_MONTH 0</code> indicates the week before
     * <code>DAY_OF_WEEK_IN_MONTH 1</code>.  Negative values count back from the
     * end of the month, so the last Sunday of a month is specified as
     * <code>DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1</code>.  Because
     * negative values count backward they will usually be aligned differently
     * within the month than positive values.  For example, if a month has 31
     * days, <code>DAY_OF_WEEK_IN_MONTH -1</code> will overlap
     * <code>DAY_OF_WEEK_IN_MONTH 5</code> and the end of <code>4</code>.
     * @see #DAY_OF_WEEK
     * @see #WEEK_OF_MONTH
     * @stable ICU 2.0
     */
    public final static int DAY_OF_WEEK_IN_MONTH = 8;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating
     * whether the <code>HOUR</code> is before or after noon.
     * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>.
     * @see #AM
     * @see #PM
     * @see #HOUR
     * @stable ICU 2.0
     */
    public final static int AM_PM = 9;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * hour of the morning or afternoon. <code>HOUR</code> is used for the 12-hour
     * clock.
     * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10.
     * @see #AM_PM
     * @see #HOUR_OF_DAY
     * @stable ICU 2.0
     */
    public final static int HOUR = 10;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock.
     * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22.
     * @see #HOUR
     * @stable ICU 2.0
     */
    public final static int HOUR_OF_DAY = 11;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * minute within the hour.
     * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4.
     * @stable ICU 2.0
     */
    public final static int MINUTE = 12;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * second within the minute.
     * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15.
     * @stable ICU 2.0
     */
    public final static int SECOND = 13;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * millisecond within the second.
     * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250.
     * @stable ICU 2.0
     */
    public final static int MILLISECOND = 14;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * raw offset from GMT in milliseconds.
     * @stable ICU 2.0
     */
    public final static int ZONE_OFFSET = 15;

    /**
     * Field number for <code>get</code> and <code>set</code> indicating the
     * daylight savings offset in milliseconds.
     * @stable ICU 2.0
     */
    public final static int DST_OFFSET = 16;

    /**
     * {@icu} Field number for <code>get()</code> and <code>set()</code>
     * indicating the extended year corresponding to the
     * {@link #WEEK_OF_YEAR} field.  This may be one greater or less
     * than the value of {@link #EXTENDED_YEAR}.
     * @stable ICU 2.0
     */
    public static final int YEAR_WOY = 17;

    /**
     * {@icu} Field number for <code>get()</code> and <code>set()</code>
     * indicating the localized day of week.  This will be a value from 1
     * to 7 inclusive, with 1 being the localized first day of the week.
     * @stable ICU 2.0
     */
    public static final int DOW_LOCAL = 18;

    /**
     * {@icu} Field number for <code>get()</code> and <code>set()</code>
     * indicating the extended year.  This is a single number designating
     * the year of this calendar system, encompassing all supra-year
     * fields.  For example, for the Julian calendar system, year numbers
     * are positive, with an era of BCE or CE.  An extended year value for
     * the Julian calendar system assigns positive values to CE years and
     * negative values to BCE years, with 1 BCE being year 0.
     * @stable ICU 2.0
     */
    public static final int EXTENDED_YEAR = 19;

    /**
     * {@icu} Field number for <code>get()</code> and <code>set()</code>
     * indicating the modified Julian day number.  This is different from
     * the conventional Julian day number in two regards.  First, it
     * demarcates days at local zone midnight, rather than noon GMT.
     * Second, it is a local number; that is, it depends on the local time
     * zone.  It can be thought of as a single number that encompasses all
     * the date-related fields.
     * @stable ICU 2.0
     */
    public static final int JULIAN_DAY = 20;

    /**
     * {@icu} Field number for <code>get()</code> and <code>set()</code>
     * indicating the milliseconds in the day.  This ranges from 0 to
     * 23:59:59.999 (regardless of DST).  This field behaves
     * <em>exactly</em> like a composite of all time-related fields, not
     * including the zone fields.  As such, it also reflects
     * discontinuities of those fields on DST transition days.  On a day of
     * DST onset, it will jump forward.  On a day of DST cessation, it will
     * jump backward.  This reflects the fact that is must be combined with
     * the DST_OFFSET field to obtain a unique local time value.
     * @stable ICU 2.0
     */
    public static final int MILLISECONDS_IN_DAY = 21;

    /**
     * {@icu} Field indicating whether or not the current month is a leap month.
     * Should have a value of 0 for non-leap months, and 1 for leap months.
     * @stable ICU 4.4
     */
    public static final int IS_LEAP_MONTH = 22;

    /**
     * The number of fields defined by this class.  Subclasses may define
     * addition fields starting with this number.
     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
     */
    @Deprecated
    protected static final int BASE_FIELD_COUNT = 23;

    /**
     * The maximum number of fields possible.  Subclasses must not define
     * more total fields than this number.
     * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
     */
    @Deprecated
    protected static final int MAX_FIELD_COUNT = 32;

    /**
     * Value of the <code>DAY_OF_WEEK</code> field indicating
     * Sunday.
     * @stable ICU 2.0
     */
    public final static int SUNDAY = 1;

    /**
     * Value of the <code>DAY_OF_WEEK</code> field indicating
     * Monday.
     * @stable ICU 2.0
     */
    public final static int MONDAY = 2;

    /**
     * Value of the <code>DAY_OF_WEEK</code> field indicating
     * Tuesday.
     * @stable ICU 2.0
     */
    public final static int TUESDAY = 3;

    /**
     * Value of the <code>DAY_OF_WEEK</code> field indicating
     * Wednesday.
     * @stable ICU 2.0
     */
    public final static int WEDNESDAY = 4;

    /**
     * Value of the <code>DAY_OF_WEEK</code> field indicating
     * Thursday.
     * @stable ICU 2.0
     */
    public final static int THURSDAY = 5;

    /**
     * Value of the <code>DAY_OF_WEEK</code> field indicating
     * Friday.
     * @stable ICU 2.0
     */
    public final static int FRIDAY = 6;

    /**
     * Value of the <code>DAY_OF_WEEK</code> field indicating
     * Saturday.
     * @stable ICU 2.0
     */
    public final static int SATURDAY = 7;

    /**
     * Value of the <code>MONTH</code> field indicating the
     * first month of the year.
     * @stable ICU 2.0
     */
    public final static int JANUARY = 0;

    /**
     * Value of the <code>MONTH</code> field indicating the
     * second month of the year.
     * @stable ICU 2.0
     */
    public final static int FEBRUARY = 1;

    /**
     * Value of the <code>MONTH</code> field indicating the
     * third month of the year.
     * @stable ICU 2.0
     */
    public final static int MARCH = 2;

    /**
     * Value of the <code>MONTH</code> field indicating the
     * fourth month of the year.
     * @stable ICU 2.0
     */
    public final static int APRIL = 3;

    /**
     * Value of the <code>MONTH</code> field indicating the
     * fifth month of the year.
     * @stable ICU 2.0
     */
    public final static int MAY = 4;

    /**
     * Value of the <code>MONTH</code> field indicating the
     * sixth month of the year.
     * @stable ICU 2.0
     */
    public final static int JUNE = 5;

    /**
     * Value of the <code>MONTH</code> field indicating the
     * seventh month of the year.
     * @stable ICU 2.0
     */
    public final static int JULY = 6;

    /**
     * Value of the <code>MONTH</code> field indicating the
     * eighth month of the year.
     * @stable ICU 2.0
     */
    public final static int AUGUST = 7;

    /**
     * Value of the <code>MONTH</code> field indicating the
     * ninth month of the year.
     * @stable ICU 2.0
     */
    public final static int SEPTEMBER = 8;

    /**
     * Value of the <code>MONTH</code> field indicating the
     * tenth month of the year.
     * @stable ICU 2.0
     */
    public final static int OCTOBER = 9;

    /**
     * Value of the <code>MONTH</code> field indicating the
     * eleventh month of the year.
     * @stable ICU 2.0
     */
    public final static int NOVEMBER = 10;

    /**
     * Value of the <code>MONTH</code> field indicating the
     * twelfth month of the year.
     * @stable ICU 2.0
     */
    public final static int DECEMBER = 11;

    /**
     * Value of the <code>MONTH</code> field indicating the
     * thirteenth month of the year. Although {@link GregorianCalendar}
     * does not use this value, lunar calendars do.
     * @stable ICU 2.0
     */
    public final static int UNDECIMBER = 12;

    /**
     * Value of the <code>AM_PM</code> field indicating the
     * period of the day from midnight to just before noon.
     * @stable ICU 2.0
     */
    public final static int AM = 0;

    /**
     * Value of the <code>AM_PM</code> field indicating the
     * period of the day from noon to just before midnight.
     * @stable ICU 2.0
     */
    public final static int PM = 1;

    /**
     * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
     * weekday.
     * @see #WEEKEND
     * @see #WEEKEND_ONSET
     * @see #WEEKEND_CEASE
     * @see #getDayOfWeekType
     * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)}
     */
    @Deprecated
    public static final int WEEKDAY = 0;

    /**
     * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
     * weekend day.
     * @see #WEEKDAY
     * @see #WEEKEND_ONSET
     * @see #WEEKEND_CEASE
     * @see #getDayOfWeekType
     * @deprecated  ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)}
     */
    @Deprecated
    public static final int WEEKEND = 1;

    /**
     * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
     * day that starts as a weekday and transitions to the weekend.
     * Call getWeekendTransition() to get the point of transition.
     * @see #WEEKDAY
     * @see #WEEKEND
     * @see #WEEKEND_CEASE
     * @see #getDayOfWeekType
     * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)}
     */
    @Deprecated
    public static final int WEEKEND_ONSET = 2;

    /**
     * {@icu} Value returned by getDayOfWeekType(int dayOfWeek) to indicate a
     * day that starts as the weekend and transitions to a weekday.
     * Call getWeekendTransition() to get the point of transition.
     * @see #WEEKDAY
     * @see #WEEKEND
     * @see #WEEKEND_ONSET
     * @see #getDayOfWeekType
     * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)}
     */
    @Deprecated
    public static final int WEEKEND_CEASE = 3;

    /**
     * {@icu}Option used by {@link #setRepeatedWallTimeOption(int)} and
     * {@link #setSkippedWallTimeOption(int)} specifying an ambiguous wall time
     * to be interpreted as the latest.
     * @see #setRepeatedWallTimeOption(int)
     * @see #getRepeatedWallTimeOption()
     * @see #setSkippedWallTimeOption(int)
     * @see #getSkippedWallTimeOption()
     * @stable ICU 49
     */
    public static final int WALLTIME_LAST = 0;

    /**
     * {@icu}Option used by {@link #setRepeatedWallTimeOption(int)} and
     * {@link #setSkippedWallTimeOption(int)} specifying an ambiguous wall time
     * to be interpreted as the earliest.
     * @see #setRepeatedWallTimeOption(int)
     * @see #getRepeatedWallTimeOption()
     * @see #setSkippedWallTimeOption(int)
     * @see #getSkippedWallTimeOption()
     * @stable ICU 49
     */
    public static final int WALLTIME_FIRST = 1;

    /**
     * {@icu}Option used by {@link #setSkippedWallTimeOption(int)} specifying an
     * ambiguous wall time to be interpreted as the next valid wall time.
     * @see #setSkippedWallTimeOption(int)
     * @see #getSkippedWallTimeOption()
     * @stable ICU 49
     */
    public static final int WALLTIME_NEXT_VALID = 2;

    /**
     * The number of milliseconds in one second.
     * @stable ICU 2.0
     */
    protected static final int  ONE_SECOND = 1000;

    /**
     * The number of milliseconds in one minute.
     * @stable ICU 2.0
     */
    protected static final int  ONE_MINUTE = 60*ONE_SECOND;

    /**
     * The number of milliseconds in one hour.
     * @stable ICU 2.0
     */
    protected static final int  ONE_HOUR   = 60*ONE_MINUTE;

    /**
     * The number of milliseconds in one day.  Although ONE_DAY and
     * ONE_WEEK can fit into ints, they must be longs in order to prevent
     * arithmetic overflow when performing (bug 4173516).
     * @stable ICU 2.0
     */
    protected static final long ONE_DAY    = 24*ONE_HOUR;

    /**
     * The number of milliseconds in one week.  Although ONE_DAY and
     * ONE_WEEK can fit into ints, they must be longs in order to prevent
     * arithmetic overflow when performing (bug 4173516).
     * @stable ICU 2.0
     */
    protected static final long ONE_WEEK   = 7*ONE_DAY;

    /**
     * The Julian day of the Gregorian epoch, that is, January 1, 1 on the
     * Gregorian calendar.
     * @stable ICU 2.0
     */
    protected static final int JAN_1_1_JULIAN_DAY = 1721426;

    /**
     * The Julian day of the epoch, that is, January 1, 1970 on the
     * Gregorian calendar.
     * @stable ICU 2.0
     */
    protected static final int EPOCH_JULIAN_DAY   = 2440588;

    /**
     * The minimum supported Julian day.  This value is equivalent to
     * {@link #MIN_MILLIS} and {@link #MIN_DATE}.
     * @see #JULIAN_DAY
     * @stable ICU 2.0
     */
    protected static final int MIN_JULIAN = -0x7F000000;

    /**
     * The minimum supported epoch milliseconds.  This value is equivalent
     * to {@link #MIN_JULIAN} and {@link #MIN_DATE}.
     * @stable ICU 2.0
     */
    protected static final long MIN_MILLIS = -184303902528000000L;

    // Get around bug in jikes 1.12 for now.  Later, use:
    //protected static final long MIN_MILLIS = (MIN_JULIAN - EPOCH_JULIAN_DAY) * ONE_DAY;

    /**
     * The minimum supported <code>Date</code>.  This value is equivalent
     * to {@link #MIN_JULIAN} and {@link #MIN_MILLIS}.
     * @stable ICU 2.0
     */
    protected static final Date MIN_DATE = new Date(MIN_MILLIS);

    /**
     * The maximum supported Julian day.  This value is equivalent to
     * {@link #MAX_MILLIS} and {@link #MAX_DATE}.
     * @see #JULIAN_DAY
     * @stable ICU 2.0
     */
    protected static final int MAX_JULIAN = +0x7F000000;

    /**
     * The maximum supported epoch milliseconds.  This value is equivalent
     * to {@link #MAX_JULIAN} and {@link #MAX_DATE}.
     * @stable ICU 2.0
     */
    protected static final long MAX_MILLIS = (MAX_JULIAN - EPOCH_JULIAN_DAY) * ONE_DAY;

    /**
     * The maximum supported <code>Date</code>.  This value is equivalent
     * to {@link #MAX_JULIAN} and {@link #MAX_MILLIS}.
     * @stable ICU 2.0
     */
    protected static final Date MAX_DATE = new Date(MAX_MILLIS);

    /**
     * The maximum supported hours for millisecond calculations
     */
    private static final int MAX_HOURS = 548;

    // Internal notes:
    // Calendar contains two kinds of time representations: current "time" in
    // milliseconds, and a set of time "fields" representing the current time.
    // The two representations are usually in sync, but can get out of sync
    // as follows.
    // 1. Initially, no fields are set, and the time is invalid.
    // 2. If the time is set, all fields are computed and in sync.
    // 3. If a single field is set, the time is invalid.
    // Recomputation of the time and fields happens when the object needs
    // to return a result to the user, or use a result for a computation.

    /**
     * The field values for the currently set time for this calendar.
     * This is an array of at least {@link #BASE_FIELD_COUNT} integers.
     * @see #handleCreateFields
     * @serial
     */
    private transient int           fields[];

    /**
     * Pseudo-time-stamps which specify when each field was set. There
     * are two special values, UNSET and INTERNALLY_SET. Values from
     * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values.
     */
    private transient int           stamp[];

    /**
     * The currently set time for this calendar, expressed in milliseconds after
     * January 1, 1970, 0:00:00 GMT.
     * @serial
     */
    private long          time;

    /**
     * True if then the value of <code>time</code> is valid.
     * The time is made invalid by a change to an item of <code>field[]</code>.
     * @see #time
     * @serial
     */
    private transient boolean       isTimeSet;

    /**
     * True if <code>fields[]</code> are in sync with the currently set time.
     * If false, then the next attempt to get the value of a field will
     * force a recomputation of all fields from the current value of
     * <code>time</code>.
     * @serial
     */
    private transient boolean       areFieldsSet;

    /**
     * True if all fields have been set.  This is only false in a few
     * situations: In a newly created, partially constructed object.  After
     * a call to clear().  In an object just read from a stream using
     * readObject().  Once computeFields() has been called this is set to
     * true and stays true until one of the above situations recurs.
     * @serial
     */
    private transient boolean       areAllFieldsSet;

    /**
     * True if all fields have been virtually set, but have not yet been
     * computed.  This occurs only in setTimeInMillis(), or after readObject().
     * A calendar set to this state will compute all fields from the time if it
     * becomes necessary, but otherwise will delay such computation.
     */
    private transient boolean areFieldsVirtuallySet;

    /**
     * True if this calendar allows out-of-range field values during computation
     * of <code>time</code> from <code>fields[]</code>.
     * @see #setLenient
     * @serial
     */
    private boolean         lenient = true;

    /**
     * The {@link TimeZone} used by this calendar. {@link Calendar}
     * uses the time zone data to translate between local and GMT time.
     * @serial
     */
    private TimeZone        zone;

    /**
     * The first day of the week, with possible values {@link #SUNDAY},
     * {@link #MONDAY}, etc.  This is a locale-dependent value.
     * @serial
     */
    private int             firstDayOfWeek;

    /**
     * The number of days required for the first week in a month or year,
     * with possible values from 1 to 7.  This is a locale-dependent value.
     * @serial
     */
    private int             minimalDaysInFirstWeek;

    /**
     * First day of the weekend in this calendar's locale.  Must be in
     * the range SUNDAY...SATURDAY (1..7).  The weekend starts at
     * weekendOnsetMillis milliseconds after midnight on that day of
     * the week.  This value is taken from locale resource data.
     */
    private int weekendOnset;

    /**
     * Milliseconds after midnight at which the weekend starts on the
     * day of the week weekendOnset.  Times that are greater than or
     * equal to weekendOnsetMillis are considered part of the weekend.
     * Must be in the range 0..24*60*60*1000-1.  This value is taken
     * from locale resource data.
     */
    private int weekendOnsetMillis;

    /**
     * Day of the week when the weekend stops in this calendar's
     * locale.  Must be in the range SUNDAY...SATURDAY (1..7).  The
     * weekend stops at weekendCeaseMillis milliseconds after midnight
     * on that day of the week.  This value is taken from locale
     * resource data.
     */
    private int weekendCease;

    /**
     * Milliseconds after midnight at which the weekend stops on the
     * day of the week weekendCease.  Times that are greater than or
     * equal to weekendCeaseMillis are considered not to be the
     * weekend.  Must be in the range 0..24*60*60*1000-1.  This value
     * is taken from locale resource data.
     */
    private int weekendCeaseMillis;

    /**
     * Option used when the specified wall time occurs multiple times.
     */
    private int repeatedWallTime = WALLTIME_LAST;

    /**
     * Option used when the specified wall time does not exist.
     */
    private int skippedWallTime = WALLTIME_LAST;

    /**
     * Value of the time stamp <code>stamp[]</code> indicating that
     * a field has not been set since the last call to <code>clear()</code>.
     * @see #INTERNALLY_SET
     * @see #MINIMUM_USER_STAMP
     * @stable ICU 2.0
     */
    protected static final int UNSET = 0;

    /**
     * Value of the time stamp <code>stamp[]</code> indicating that a field
     * has been set via computations from the time or from other fields.
     * @see #UNSET
     * @see #MINIMUM_USER_STAMP
     * @stable ICU 2.0
     */
    protected static final int INTERNALLY_SET = 1;

    /**
     * If the time stamp <code>stamp[]</code> has a value greater than or
     * equal to <code>MINIMUM_USER_SET</code> then it has been set by the
     * user via a call to <code>set()</code>.
     * @see #UNSET
     * @see #INTERNALLY_SET
     * @stable ICU 2.0
     */
    protected static final int MINIMUM_USER_STAMP = 2;

    /**
     * The next available value for <code>stamp[]</code>, an internal array.
     * @serial
     */
    private transient int             nextStamp = MINIMUM_USER_STAMP;

    /* Max value for stamp allowable before recalcution */
    private static int STAMP_MAX = 10000;

    // the internal serial version which says which version was written
    // - 0 (default) for version up to JDK 1.1.5
    // - 1 for version from JDK 1.1.6, which writes a correct 'time' value
    //     as well as compatible values for other fields.  This is a
    //     transitional format.
    // - 2 (not implemented yet) a future version, in which fields[],
    //     areFieldsSet, and isTimeSet become transient, and isSet[] is
    //     removed. In JDK 1.1.6 we write a format compatible with version 2.
    // static final int        currentSerialVersion = 1;

    /**
     * The version of the serialized data on the stream.  Possible values:
     * <dl>
     * <dt><b>0</b> or not present on stream</dt>
     * <dd>
     * JDK 1.1.5 or earlier.
     * </dd>
     * <dt><b>1</b></dt>
     * <dd>
     * JDK 1.1.6 or later.  Writes a correct 'time' value
     * as well as compatible values for other fields.  This is a
     * transitional format.
     * </dd>
     * </dl>
     * When streaming out this class, the most recent format
     * and the highest allowable <code>serialVersionOnStream</code>
     * is written.
     * @serial
     * @since JDK1.1.6
     */
    // private int             serialVersionOnStream = currentSerialVersion;

    // Proclaim serialization compatibility with JDK 1.1
    // static final long       serialVersionUID = -1807547505821590642L;

    // haven't been compatible for awhile, no longer try
    // jdk1.4.2 serialver
    private static final long serialVersionUID = 6222646104888790989L;

    /**
     * Bitmask for internalSet() defining which fields may legally be set
     * by subclasses.  Any attempt to set a field not in this bitmask
     * results in an exception, because such fields must be set by the base
     * class.
     */
    private transient int internalSetMask;

    /**
     * The Gregorian year, as computed by computeGregorianFields() and
     * returned by getGregorianYear().
     */
    private transient int gregorianYear;

    /**
     * The Gregorian month, as computed by computeGregorianFields() and
     * returned by getGregorianMonth().
     */
    private transient int gregorianMonth;

    /**
     * The Gregorian day of the year, as computed by
     * computeGregorianFields() and returned by getGregorianDayOfYear().
     */
    private transient int gregorianDayOfYear;

    /**
     * The Gregorian day of the month, as computed by
     * computeGregorianFields() and returned by getGregorianDayOfMonth().
     */
    private transient int gregorianDayOfMonth;

    /**
     * Constructs a Calendar with the default time zone
     * and the default <code>FORMAT</code> locale.
     * @see     TimeZone#getDefault
     * @see Category#FORMAT
     * @stable ICU 2.0
     */
    protected Calendar()
    {
        this(TimeZone.getDefault(), ULocale.getDefault(Category.FORMAT));
    }

    /**
     * Constructs a calendar with the specified time zone and locale.
     * @param zone the time zone to use
     * @param aLocale the locale for the week data
     * @stable ICU 2.0
     */
    protected Calendar(TimeZone zone, Locale aLocale)
    {
        this(zone, ULocale.forLocale(aLocale));
    }

    /**
     * Constructs a calendar with the specified time zone and locale.
     * @param zone the time zone to use
     * @param locale the ulocale for the week data
     * @stable ICU 3.2
     */
    protected Calendar(TimeZone zone, ULocale locale)
    {
        this.zone = zone;

        // week data
        setWeekData(getRegionForCalendar(locale));

        // set valid/actual locale
        setCalendarLocale(locale);

        initInternal();
    }

    /*
     * Set valid/actual locale to this calendar during initialization.
     *
     * Valid or actual locale does not make much sense for Calendar
     * object. An instance of Calendar is initialized by week data
     * determine by region and calendar type (either region or keyword).
     * Language is not really used for calendar creation.
     */
    private void setCalendarLocale(ULocale locale) {
        ULocale calLocale = locale;

        if (locale.getVariant().length() != 0 || locale.getKeywords() != null) {
            // Construct a ULocale, without variant and keywords (except calendar).
            StringBuilder buf = new StringBuilder();

            buf.append(locale.getLanguage());

            String script = locale.getScript();
            if (script.length() > 0) {
                buf.append("_").append(script);
            }

            String region = locale.getCountry();
            if (region.length() > 0) {
                buf.append("_").append(region);
            }

            String calType = locale.getKeywordValue("calendar");
            if (calType != null) {
                buf.append("@calendar=").append(calType);
            }

            calLocale = new ULocale(buf.toString());
        }

        setLocale(calLocale, calLocale);
    }

    private void recalculateStamp() {
        int index;
        int currentValue;
        int j, i;

        nextStamp = 1;

        for (j = 0; j < stamp.length; j++) {
            currentValue = STAMP_MAX;
            index = -1;

            for (i = 0; i < stamp.length; i++) {
                if (stamp[i] > nextStamp && stamp[i] < currentValue) {
                    currentValue = stamp[i];
                    index = i;
                }
            }

            if (index >= 0) {
                stamp[index] = ++nextStamp;
            } else {
                break;
            }
        }
        nextStamp++;
    }

    private void initInternal()
    {
        // Allocate fields through the framework method.  Subclasses
        // may override this to define additional fields.
        fields = handleCreateFields();
        ///CLOVER:OFF
        // todo: fix, difficult to test without subclassing
        if (fields == null || fields.length < BASE_FIELD_COUNT ||
                fields.length > MAX_FIELD_COUNT) {
            throw new IllegalStateException("Invalid fields[]");
        }
        ///CLOVER:ON
        stamp = new int[fields.length];
        int mask = (1 << ERA) |
                (1 << YEAR) |
                (1 << MONTH) |
                (1 << DAY_OF_MONTH) |
                (1 << DAY_OF_YEAR) |
                (1 << EXTENDED_YEAR) |
                (1 << IS_LEAP_MONTH);
        for (int i=BASE_FIELD_COUNT; i<fields.length; ++i) {
            mask |= (1 << i);
        }
        internalSetMask = mask;
    }

    /**
     * Returns a calendar using the default time zone and locale.
     * @return a Calendar.
     * @stable ICU 2.0
     */
    public static Calendar getInstance()
    {
        return getInstanceInternal(null, null);
    }

    /**
     * Returns a calendar using the specified time zone and default locale.
     * @param zone the time zone to use
     * @return a Calendar.
     * @stable ICU 2.0
     */
    public static Calendar getInstance(TimeZone zone)
    {
        return getInstanceInternal(zone, null);
    }

    /**
     * Returns a calendar using the default time zone and specified locale.
     * @param aLocale the locale for the week data
     * @return a Calendar.
     * @stable ICU 2.0
     */
    public static Calendar getInstance(Locale aLocale)
    {
        return getInstanceInternal(null, ULocale.forLocale(aLocale));
    }

    /**
     * Returns a calendar using the default time zone and specified locale.
     * @param locale the ulocale for the week data
     * @return a Calendar.
     * @stable ICU 3.2
     */
    public static Calendar getInstance(ULocale locale)
    {
        return getInstanceInternal(null, locale);
    }

    /**
     * Returns a calendar with the specified time zone and locale.
     * @param zone the time zone to use
     * @param aLocale the locale for the week data
     * @return a Calendar.
     * @stable ICU 2.0
     */
    public static Calendar getInstance(TimeZone zone, Locale aLocale) {
        return getInstanceInternal(zone, ULocale.forLocale(aLocale));
    }

    /**
     * Returns a calendar with the specified time zone and locale.
     * @param zone the time zone to use
     * @param locale the ulocale for the week data
     * @return a Calendar.
     * @stable ICU 3.2
     */
    public static Calendar getInstance(TimeZone zone, ULocale locale) {
        return getInstanceInternal(zone, locale);
    }

    /*
     * All getInstance implementations call this private method to create a new
     * Calendar instance.
     */
    private static Calendar getInstanceInternal(TimeZone tz, ULocale locale) {
        if (locale == null) {
            locale = ULocale.getDefault(Category.FORMAT);
        }
        if (tz == null) {
            tz = TimeZone.forULocaleOrDefault(locale);
        }

        Calendar cal = createInstance(locale);
        cal.setTimeZone(tz);
        cal.setTimeInMillis(System.currentTimeMillis());
        return cal;
    }

    private static String getRegionForCalendar(ULocale loc) {
        String region = ULocale.getRegionForSupplementalData(loc, true);
        if (region.length() == 0) {
            region = "001";
        }
        return region;
    }

    private static CalType getCalendarTypeForLocale(ULocale l) {
        String s = CalendarUtil.getCalendarType(l);
        if (s != null) {
            s = s.toLowerCase(Locale.ENGLISH);
            for (CalType type : CalType.values()) {
                if (s.equals(type.getId())) {
                    return type;
                }
            }
        }
        return CalType.UNKNOWN;
    }

    private static Calendar createInstance(ULocale locale) {
        Calendar cal = null;
        TimeZone zone = TimeZone.forULocaleOrDefault(locale);
        CalType calType = getCalendarTypeForLocale(locale);
        if (calType == CalType.UNKNOWN) {
            // fallback to Gregorian
            calType = CalType.GREGORIAN;
        }

        switch (calType) {
        case GREGORIAN:
            cal = new GregorianCalendar(zone, locale);
            break;
        case ISO8601:
            // Only differs week numbering rule from Gregorian
            cal = new GregorianCalendar(zone, locale);
            cal.setFirstDayOfWeek(MONDAY);
            cal.setMinimalDaysInFirstWeek(4);
            break;

        case BUDDHIST:
            cal = new BuddhistCalendar(zone, locale);
            break;
        case CHINESE:
            cal = new ChineseCalendar(zone, locale);
            break;
        case COPTIC:
            cal = new CopticCalendar(zone, locale);
            break;
        case DANGI:
            cal = new DangiCalendar(zone, locale);
            break;
        case ETHIOPIC:
            cal = new EthiopicCalendar(zone, locale);
            break;
        case ETHIOPIC_AMETE_ALEM:
            cal = new EthiopicCalendar(zone, locale);
            ((EthiopicCalendar)cal).setAmeteAlemEra(true);
            break;
        case HEBREW:
            cal = new HebrewCalendar(zone, locale);
            break;
        case INDIAN:
            cal = new IndianCalendar(zone, locale);
            break;
        case ISLAMIC_CIVIL:
        case ISLAMIC_UMALQURA :
        case ISLAMIC_TBLA:
        case ISLAMIC_RGSA:
        case ISLAMIC:
            cal = new IslamicCalendar(zone, locale);
            break;
        case JAPANESE:
            cal = new JapaneseCalendar(zone, locale);
            break;
        case PERSIAN:
            cal = new PersianCalendar(zone, locale);
            break;
        case ROC:
            cal = new TaiwanCalendar(zone, locale);
            break;

        default:
            // we must not get here, because unknown type is mapped to
            // Gregorian at the beginning of this method.
            throw new IllegalArgumentException("Unknown calendar type");
        }

        return cal;
    }

    /**
     * Returns the list of locales for which Calendars are installed.
     * @return the list of locales for which Calendars are installed.
     * @stable ICU 2.0
     */
    public static Locale[] getAvailableLocales()
    {
        // TODO
        return ICUResourceBundle.getAvailableLocales();
    }

    /**
     * {@icu} Returns the list of locales for which Calendars are installed.
     * @return the list of locales for which Calendars are installed.
     * @draft ICU 3.2 (retain)
     * @provisional This API might change or be removed in a future release.
     */
    public static ULocale[] getAvailableULocales()
    {
        // TODO
        return ICUResourceBundle.getAvailableULocales();
    }

    /**
     * {@icu} Given a key and a locale, returns an array of string values in a preferred
     * order that would make a difference. These are all and only those values where
     * the open (creation) of the service with the locale formed from the input locale
     * plus input keyword and that value has different behavior than creation with the
     * input locale alone.
     * @param key           one of the keys supported by this service.  For now, only
     *                      "calendar" is supported.
     * @param locale        the locale
     * @param commonlyUsed  if set to true it will return only commonly used values
     *                      with the given locale in preferred order.  Otherwise,
     *                      it will return all the available values for the locale.
     * @return an array of string values for the given key and the locale.
     * @stable ICU 4.2
     */
    public static final String[] getKeywordValuesForLocale(String key, ULocale locale,
            boolean commonlyUsed) {
        // Resolve region
        String prefRegion = ULocale.getRegionForSupplementalData(locale, true);

        // Read preferred calendar values from supplementalData calendarPreferences
        ArrayList<String> values = new ArrayList<>();

        UResourceBundle rb = UResourceBundle.getBundleInstance(
                ICUData.ICU_BASE_NAME,
                "supplementalData",
                ICUResourceBundle.ICU_DATA_CLASS_LOADER);
        UResourceBundle calPref = rb.get("calendarPreferenceData");
        UResourceBundle order = null;
        try {
            order = calPref.get(prefRegion);
        } catch (MissingResourceException mre) {
            // use "001" as fallback
            order = calPref.get("001");
        }

        String[] caltypes = order.getStringArray();
        if (commonlyUsed) {
            // we have all commonly used calendar for the target region
            return caltypes;
        }

        // if not commonlyUsed, add all preferred calendars in the order
        for (int i = 0; i < caltypes.length; i++) {
            values.add(caltypes[i]);
        }
        // then, add other available calendars
        for (CalType t : CalType.values()) {
            if (!values.contains(t.getId())) {
                values.add(t.getId());
            }
        }
        return values.toArray(new String[values.size()]);
    }

    /**
     * Returns this Calendar's current time.
     * @return the current time.
     * @stable ICU 2.0
     */
    public final Date getTime() {
        return new Date( getTimeInMillis() );
    }

    /**
     * Sets this Calendar's current time with the given Date.
     *
     * <p>Note: Calling <code>setTime</code> with
     * <code>Date(Long.MAX_VALUE)</code> or <code>Date(Long.MIN_VALUE)</code>
     * may yield incorrect field values from {@link #get(int)}.
     * @param date the given Date.
     * @stable ICU 2.0
     */
    public final void setTime(Date date) {
        setTimeInMillis( date.getTime() );
    }

    /**
     * Returns this Calendar's current time as a long.
     * @return the current time as UTC milliseconds from the epoch.
     * @stable ICU 2.0
     */
    public long getTimeInMillis() {
        if (!isTimeSet) updateTime();
        return time;
    }

    /**
     * Sets this Calendar's current time from the given long value.
     * An IllegalIcuArgumentException is thrown when millis is outside the range permitted
     * by a Calendar object when in strict mode.
     * When in lenient mode the out of range values are pinned to their respective min/max.
     * @param millis the new time in UTC milliseconds from the epoch.
     * @stable ICU 2.0
     */
    public void setTimeInMillis( long millis ) {
        if (millis > MAX_MILLIS) {
            if(isLenient()) {
                millis = MAX_MILLIS;
            } else {
                throw new IllegalArgumentException("millis value greater than upper bounds for a Calendar : " + millis);
            }
        } else if (millis < MIN_MILLIS) {
            if(isLenient()) {
                millis = MIN_MILLIS;
            } else {
                throw new IllegalArgumentException("millis value less than lower bounds for a Calendar : " + millis);
            }
        }
        time = millis;
        areFieldsSet = areAllFieldsSet = false;
        isTimeSet = areFieldsVirtuallySet = true;

        for (int i=0; i<fields.length; ++i) {
            fields[i] = stamp[i] = 0; // UNSET == 0
        }

    }

    /**
     * Returns the value for a given time field.
     * @param field the given time field.
     * @return the value for the given time field.
     * @stable ICU 2.0
     */
    public final int get(int field)
    {
        complete();
        return fields[field];
    }

    /**
     * Returns the value for a given time field.  This is an internal method
     * for subclasses that does <em>not</em> trigger any calculations.
     * @param field the given time field.
     * @return the value for the given time field.
     * @stable ICU 2.0
     */
    protected final int internalGet(int field)
    {
        return fields[field];
    }

    /**
     * Returns the value for a given time field, or return the given default
     * value if the field is not set.  This is an internal method for
     * subclasses that does <em>not</em> trigger any calculations.
     * @param field the given time field.
     * @param defaultValue value to return if field is not set
     * @return the value for the given time field of defaultValue if the
     * field is unset
     * @stable ICU 2.0
     */
    protected final int internalGet(int field, int defaultValue) {
        return (stamp[field] > UNSET) ? fields[field] : defaultValue;
    }

    /**
     * Sets the time field with the given value.
     * @param field the given time field.
     * @param value the value to be set for the given time field.
     * @stable ICU 2.0
     */
    public final void set(int field, int value)
    {
        if (areFieldsVirtuallySet) {
            computeFields();
        }
        fields[field] = value;
        /* Ensure that the fNextStamp value doesn't go pass max value for 32 bit integer */
        if (nextStamp == STAMP_MAX) {
            recalculateStamp();
        }
        stamp[field] = nextStamp++;
        isTimeSet = areFieldsSet = areFieldsVirtuallySet = false;
    }

    /**
     * Sets the values for the fields year, month, and date.
     * Previous values of other fields are retained.  If this is not desired,
     * call {@link #clear()} first.
     * @param year the value used to set the YEAR time field.
     * @param month the value used to set the MONTH time field.
     * Month value is 0-based. e.g., 0 for January.
     * @param date the value used to set the DATE time field.
     * @stable ICU 2.0
     */
    public final void set(int year, int month, int date)
    {
        set(YEAR, year);
        set(MONTH, month);
        set(DATE, date);
    }

    /**
     * Sets the values for the fields year, month, date, hour, and minute.
     * Previous values of other fields are retained.  If this is not desired,
     * call {@link #clear()} first.
     * @param year the value used to set the YEAR time field.
     * @param month the value used to set the MONTH time field.
     * Month value is 0-based. e.g., 0 for January.
     * @param date the value used to set the DATE time field.
     * @param hour the value used to set the HOUR_OF_DAY time field.
     * @param minute the value used to set the MINUTE time field.
     * @stable ICU 2.0
     */
    public final void set(int year, int month, int date, int hour, int minute)
    {
        set(YEAR, year);
        set(MONTH, month);
        set(DATE, date);
        set(HOUR_OF_DAY, hour);
        set(MINUTE, minute);
    }

    /**
     * Sets the values for the fields year, month, date, hour, minute, and second.
     * Previous values of other fields are retained.  If this is not desired,
     * call {@link #clear} first.
     * @param year the value used to set the YEAR time field.
     * @param month the value used to set the MONTH time field.
     * Month value is 0-based. e.g., 0 for January.
     * @param date the value used to set the DATE time field.
     * @param hour the value used to set the HOUR_OF_DAY time field.
     * @param minute the value used to set the MINUTE time field.
     * @param second the value used to set the SECOND time field.
     * @stable ICU 2.0
     */
    public final void set(int year, int month, int date, int hour, int minute,
            int second)
    {
        set(YEAR, year);
        set(MONTH, month);
        set(DATE, date);
        set(HOUR_OF_DAY, hour);
        set(MINUTE, minute);
        set(SECOND, second);
    }

    // -------------------------------------
    // For now the full getRelatedYear implementation is here;
    // per #10752 move the non-default implementation to subclasses
    // (default implementation will do no year adjustment)

    /**
     * utility function for getRelatedYear
     */
    private static int gregoYearFromIslamicStart(int year) {
        // ad hoc conversion, improve under #10752
        // rough est for now, ok for grego 1846-2138,
        // otherwise occasionally wrong (for 3% of years)
        int cycle, offset, shift = 0;
        if (year >= 1397) {
            cycle = (year - 1397) / 67;
            offset = (year - 1397) % 67;
            shift = 2*cycle + ((offset >= 33)? 1: 0);
        } else {
            cycle = (year - 1396) / 67 - 1;
            offset = -(year - 1396) % 67;
            shift = 2*cycle + ((offset <= 33)? 1: 0);
        }
        return year + 579 - shift;
    }

    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public final int getRelatedYear() {
        int year = get(EXTENDED_YEAR);
        CalType type = CalType.GREGORIAN;
        String typeString = getType();
        for (CalType testType : CalType.values()) {
            if (typeString.equals(testType.getId())) {
                type = testType;
                break;
            }
        }
        switch (type) {
            case PERSIAN:
                year += 622; break;
            case HEBREW:
                year -= 3760; break;
            case CHINESE:
                year -= 2637; break;
            case INDIAN:
                year += 79; break;
            case COPTIC:
                year += 284; break;
            case ETHIOPIC:
                year += 8; break;
            case ETHIOPIC_AMETE_ALEM:
                year -=5492; break;
            case DANGI:
                year -= 2333; break;
            case ISLAMIC_CIVIL:
            case ISLAMIC:
            case ISLAMIC_UMALQURA:
            case ISLAMIC_TBLA:
            case ISLAMIC_RGSA:
                year = gregoYearFromIslamicStart(year); break;
            // case GREGORIAN:
            // case JAPANESE:
            // case BUDDHIST:
            // case ROC:
            // case ISO8601:
            default:
                // do nothing, EXTENDED_YEAR same as Gregorian
                break;
        }
        return year;
    }

    // -------------------------------------
    // For now the full setRelatedYear implementation is here;
    // per #10752 move the non-default implementation to subclasses
    // (default implementation will do no year adjustment)

    /**
     * utility function for setRelatedYear
     */
    private static int firstIslamicStartYearFromGrego(int year) {
        // ad hoc conversion, improve under #10752
        // rough est for now, ok for grego 1846-2138,
        // otherwise occasionally wrong (for 3% of years)
        int cycle, offset, shift = 0;
        if (year >= 1977) {
            cycle = (year - 1977) / 65;
            offset = (year - 1977) % 65;
            shift = 2*cycle + ((offset >= 32)? 1: 0);
        } else {
            cycle = (year - 1976) / 65 - 1;
            offset = -(year - 1976) % 65;
            shift = 2*cycle + ((offset <= 32)? 1: 0);
        }
        return year - 579 + shift;
    }

    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public final void setRelatedYear(int year) {
        CalType type = CalType.GREGORIAN;
        String typeString = getType();
        for (CalType testType : CalType.values()) {
            if (typeString.equals(testType.getId())) {
                type = testType;
                break;
            }
        }
        switch (type) {
            case PERSIAN:
                year -= 622; break;
            case HEBREW:
                year += 3760; break;
            case CHINESE:
                year += 2637; break;
            case INDIAN:
                year -= 79; break;
            case COPTIC:
                year -= 284; break;
            case ETHIOPIC:
                year -= 8; break;
            case ETHIOPIC_AMETE_ALEM:
                year +=5492; break;
            case DANGI:
                year += 2333; break;
            case ISLAMIC_CIVIL:
            case ISLAMIC:
            case ISLAMIC_UMALQURA:
            case ISLAMIC_TBLA:
            case ISLAMIC_RGSA:
                year = firstIslamicStartYearFromGrego(year); break;
            // case GREGORIAN:
            // case JAPANESE:
            // case BUDDHIST:
            // case ROC:
            // case ISO8601:
            default:
                // do nothing, EXTENDED_YEAR same as Gregorian
                break;
        }
        set(EXTENDED_YEAR, year);
    }

    /**
     * Clears the values of all the time fields.
     * @stable ICU 2.0
     */
    public final void clear()
    {
        for (int i=0; i<fields.length; ++i) {
            fields[i] = stamp[i] = 0; // UNSET == 0
        }
        isTimeSet = areFieldsSet = areAllFieldsSet = areFieldsVirtuallySet = false;
    }

    /**
     * Clears the value in the given time field.
     * @param field the time field to be cleared.
     * @stable ICU 2.0
     */
    public final void clear(int field)
    {
        if (areFieldsVirtuallySet) {
            computeFields();
        }
        fields[field] = 0;
        stamp[field] = UNSET;
        isTimeSet = areFieldsSet = areAllFieldsSet = areFieldsVirtuallySet = false;
    }

    /**
     * Determines if the given time field has a value set.
     * @return true if the given time field has a value set; false otherwise.
     * @stable ICU 2.0
     */
    public final boolean isSet(int field)
    {
        return areFieldsVirtuallySet || (stamp[field] != UNSET);
    }

    /**
     * Fills in any unset fields in the time field list.
     * @stable ICU 2.0
     */
    protected void complete()
    {
        if (!isTimeSet) updateTime();
        if (!areFieldsSet) {
            computeFields(); // fills in unset fields
            areFieldsSet = true;
            areAllFieldsSet = true;
        }
    }

    /**
     * Compares this calendar to the specified object.
     * The result is <code>true</code> if and only if the argument is
     * not <code>null</code> and is a <code>Calendar</code> object that
     * represents the same calendar as this object.
     * @param obj the object to compare with.
     * @return <code>true</code> if the objects are the same;
     * <code>false</code> otherwise.
     * @stable ICU 2.0
     */
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (this == obj) {
            return true;
        }
        if (this.getClass() != obj.getClass()) {
            return false;
        }

        Calendar that = (Calendar) obj;

        return isEquivalentTo(that) &&
                getTimeInMillis() == that.getTime().getTime();
    }

    /**
     * {@icu} Returns true if the given Calendar object is equivalent to this
     * one.  An equivalent Calendar will behave exactly as this one
     * does, but it may be set to a different time.  By contrast, for
     * the equals() method to return true, the other Calendar must
     * be set to the same time.
     *
     * @param other the Calendar to be compared with this Calendar
     * @stable ICU 2.4
     */
    public boolean isEquivalentTo(Calendar other) {
        return this.getClass() == other.getClass() &&
                isLenient() == other.isLenient() &&
                getFirstDayOfWeek() == other.getFirstDayOfWeek() &&
                getMinimalDaysInFirstWeek() == other.getMinimalDaysInFirstWeek() &&
                getTimeZone().equals(other.getTimeZone()) &&
                getRepeatedWallTimeOption() == other.getRepeatedWallTimeOption() &&
                getSkippedWallTimeOption() == other.getSkippedWallTimeOption();
    }

    /**
     * Returns a hash code for this calendar.
     * @return a hash code value for this object.
     * @stable ICU 2.0
     */
    @Override
    public int hashCode() {
        /* Don't include the time because (a) we don't want the hash value to
         * move around just because a calendar is set to different times, and
         * (b) we don't want to trigger a time computation just to get a hash.
         * Note that it is not necessary for unequal objects to always have
         * unequal hashes, but equal objects must have equal hashes.  */
        return (lenient ? 1 : 0)
                | (firstDayOfWeek << 1)
                | (minimalDaysInFirstWeek << 4)
                | (repeatedWallTime << 7)
                | (skippedWallTime << 9)
                | (zone.hashCode() << 11);
    }

    /**
     * Returns the difference in milliseconds between the moment this
     * calendar is set to and the moment the given calendar or Date object
     * is set to.
     */
    private long compare(Object that) {
        long thatMs;
        if (that instanceof Calendar) {
            thatMs = ((Calendar)that).getTimeInMillis();
        } else if (that instanceof Date) {
            thatMs = ((Date)that).getTime();
        } else {
            throw new IllegalArgumentException(that + "is not a Calendar or Date");
        }
        return getTimeInMillis() - thatMs;
    }

    /**
     * Compares the time field records.
     * Equivalent to comparing result of conversion to UTC.
     * @param when the Calendar to be compared with this Calendar.
     * @return true if the current time of this Calendar is before
     * the time of Calendar when; false otherwise.
     * @stable ICU 2.0
     */
    public boolean before(Object when) {
        return compare(when) < 0;
    }

    /**
     * Compares the time field records.
     * Equivalent to comparing result of conversion to UTC.
     * @param when the Calendar to be compared with this Calendar.
     * @return true if the current time of this Calendar is after
     * the time of Calendar when; false otherwise.
     * @stable ICU 2.0
     */
    public boolean after(Object when) {
        return compare(when) > 0;
    }

    /**
     * Returns the maximum value that this field could have, given the
     * current date.  For example, with the Gregorian date February 3, 1997
     * and the {@link #DAY_OF_MONTH DAY_OF_MONTH} field, the actual maximum
     * is 28; for February 3, 1996 it is 29.
     *
     * <p>The actual maximum computation ignores smaller fields and the
     * current value of like-sized fields.  For example, the actual maximum
     * of the DAY_OF_YEAR or MONTH depends only on the year and supra-year
     * fields.  The actual maximum of the DAY_OF_MONTH depends, in
     * addition, on the MONTH field and any other fields at that
     * granularity (such as IS_LEAP_MONTH).  The
     * DAY_OF_WEEK_IN_MONTH field does not depend on the current
     * DAY_OF_WEEK; it returns the maximum for any day of week in the
     * current month.  Likewise for the WEEK_OF_MONTH and WEEK_OF_YEAR
     * fields.
     *
     * @param field the field whose maximum is desired
     * @return the maximum of the given field for the current date of this calendar
     * @see #getMaximum
     * @see #getLeastMaximum
     * @stable ICU 2.0
     */
    public int getActualMaximum(int field) {
        int result;

        switch (field) {
        case DAY_OF_MONTH:
        {
            Calendar cal = (Calendar) clone();
            cal.setLenient(true);
            cal.prepareGetActual(field, false);
            result = handleGetMonthLength(cal.get(EXTENDED_YEAR), cal.get(MONTH));
        }
        break;

        case DAY_OF_YEAR:
        {
            Calendar cal = (Calendar) clone();
            cal.setLenient(true);
            cal.prepareGetActual(field, false);
            result = handleGetYearLength(cal.get(EXTENDED_YEAR));
        }
        break;

        case ERA:
        case DAY_OF_WEEK:
        case AM_PM:
        case HOUR:
        case HOUR_OF_DAY:
        case MINUTE:
        case SECOND:
        case MILLISECOND:
        case ZONE_OFFSET:
        case DST_OFFSET:
        case DOW_LOCAL:
        case JULIAN_DAY:
        case MILLISECONDS_IN_DAY:
            // These fields all have fixed minima/maxima
            result = getMaximum(field);
            break;

        default:
            // For all other fields, do it the hard way....
            result = getActualHelper(field, getLeastMaximum(field), getMaximum(field));
            break;
        }
        return result;
    }

    /**
     * Returns the minimum value that this field could have, given the current date.
     * For most fields, this is the same as {@link #getMinimum getMinimum}
     * and {@link #getGreatestMinimum getGreatestMinimum}.  However, some fields,
     * especially those related to week number, are more complicated.
     * <p>
     * For example, assume {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
     * returns 4 and {@link #getFirstDayOfWeek getFirstDayOfWeek} returns SUNDAY.
     * If the first day of the month is Sunday, Monday, Tuesday, or Wednesday
     * there will be four or more days in the first week, so it will be week number 1,
     * and <code>getActualMinimum(WEEK_OF_MONTH)</code> will return 1.  However,
     * if the first of the month is a Thursday, Friday, or Saturday, there are
     * <em>not</em> four days in that week, so it is week number 0, and
     * <code>getActualMinimum(WEEK_OF_MONTH)</code> will return 0.
     * <p>
     * @param field the field whose actual minimum value is desired.
     * @return the minimum of the given field for the current date of this calendar
     *
     * @see #getMinimum
     * @see #getGreatestMinimum
     * @stable ICU 2.0
     */
    public int getActualMinimum(int field) {
        int result;

        switch (field) {
        case DAY_OF_WEEK:
        case AM_PM:
        case HOUR:
        case HOUR_OF_DAY:
        case MINUTE:
        case SECOND:
        case MILLISECOND:
        case ZONE_OFFSET:
        case DST_OFFSET:
        case DOW_LOCAL:
        case JULIAN_DAY:
        case MILLISECONDS_IN_DAY:
            // These fields all have fixed minima/maxima
            result = getMinimum(field);
            break;

        default:
            // For all other fields, do it the hard way....
            result = getActualHelper(field, getGreatestMinimum(field), getMinimum(field));
            break;
        }
        return result;
    }

    /**
     * Prepare this calendar for computing the actual minimum or maximum.
     * This method modifies this calendar's fields; it is called on a
     * temporary calendar.
     *
     * <p>Rationale: The semantics of getActualXxx() is to return the
     * maximum or minimum value that the given field can take, taking into
     * account other relevant fields.  In general these other fields are
     * larger fields.  For example, when computing the actual maximum
     * DAY_OF_MONTH, the current value of DAY_OF_MONTH itself is ignored,
     * as is the value of any field smaller.
     *
     * <p>The time fields all have fixed minima and maxima, so we don't
     * need to worry about them.  This also lets us set the
     * MILLISECONDS_IN_DAY to zero to erase any effects the time fields
     * might have when computing date fields.
     *
     * <p>DAY_OF_WEEK is adjusted specially for the WEEK_OF_MONTH and
     * WEEK_OF_YEAR fields to ensure that they are computed correctly.
     * @stable ICU 2.0
     */
    protected void prepareGetActual(int field, boolean isMinimum) {
        set(MILLISECONDS_IN_DAY, 0);

        switch (field) {
        case YEAR:
        case EXTENDED_YEAR:
            set(DAY_OF_YEAR, getGreatestMinimum(DAY_OF_YEAR));
            break;

        case YEAR_WOY:
            set(WEEK_OF_YEAR, getGreatestMinimum(WEEK_OF_YEAR));
            break;

        case MONTH:
            set(DAY_OF_MONTH, getGreatestMinimum(DAY_OF_MONTH));
            break;

        case DAY_OF_WEEK_IN_MONTH:
            // For dowim, the maximum occurs for the DOW of the first of the
            // month.
            set(DAY_OF_MONTH, 1);
            set(DAY_OF_WEEK, get(DAY_OF_WEEK)); // Make this user set
            break;

        case WEEK_OF_MONTH:
        case WEEK_OF_YEAR:
            // If we're counting weeks, set the day of the week to either the
            // first or last localized DOW.  We know the last week of a month
            // or year will contain the first day of the week, and that the
            // first week will contain the last DOW.
        {
            int dow = firstDayOfWeek;
            if (isMinimum) {
                dow = (dow + 6) % 7; // set to last DOW
                if (dow < SUNDAY) {
                    dow += 7;
                }
            }
            set(DAY_OF_WEEK, dow);
        }
        break;
        }

        // Do this last to give it the newest time stamp
        set(field, getGreatestMinimum(field));
    }

    private int getActualHelper(int field, int startValue, int endValue) {

        if (startValue == endValue) {
            // if we know that the maximum value is always the same, just return it
            return startValue;
        }

        final int delta = (endValue > startValue) ? 1 : -1;

        // clone the calendar so we don't mess with the real one, and set it to
        // accept anything for the field values
        Calendar work = (Calendar) clone();

        // need to resolve time here, otherwise, fields set for actual limit
        // may cause conflict with fields previously set (but not yet resolved).
        work.complete();

        work.setLenient(true);
        work.prepareGetActual(field, delta < 0);

        // now try each value from the start to the end one by one until
        // we get a value that normalizes to another value.  The last value that
        // normalizes to itself is the actual maximum for the current date

        work.set(field, startValue);
        // prepareGetActual sets the first day of week in the same week with
        // the first day of a month.  Unlike WEEK_OF_YEAR, week number for the
        // which week contains days from both previous and current month is
        // not unique.  For example, last several days in the previous month
        // is week 5, and the rest of week is week 1.
        if (work.get(field) != startValue
                && field != WEEK_OF_MONTH && delta > 0) {
            return startValue;
        }
        int result = startValue;
        do {
            startValue += delta;
            work.add(field, delta);
            if (work.get(field) != startValue) {
                break;
            }
            result = startValue;
        } while (startValue != endValue);

        return result;
    }

    /**
     * Rolls (up/down) a single unit of time on the given field.  If the
     * field is rolled past its maximum allowable value, it will "wrap" back
     * to its minimum and continue rolling. For
     * example, to roll the current date up by one day, you can call:
     * <p>
     * <code>roll({@link #DATE}, true)</code>
     * <p>
     * When rolling on the {@link #YEAR} field, it will roll the year
     * value in the range between 1 and the value returned by calling
     * {@link #getMaximum getMaximum}({@link #YEAR}).
     * <p>
     * When rolling on certain fields, the values of other fields may conflict and
     * need to be changed.  For example, when rolling the <code>MONTH</code> field
     * for the Gregorian date 1/31/96 upward, the <code>DAY_OF_MONTH</code> field
     * must be adjusted so that the result is 2/29/96 rather than the invalid
     * 2/31/96.
     * <p>
     * Rolling up always means rolling forward in time (unless
     * the limit of the field is reached, in which case it may pin or wrap), so for the
     * Gregorian calendar, starting with 100 BC and rolling the year up results in 99 BC.
     * When eras have a definite beginning and end (as in the Chinese calendar, or as in
     * most eras in the Japanese calendar) then rolling the year past either limit of the
     * era will cause the year to wrap around. When eras only have a limit at one end,
     * then attempting to roll the year past that limit will result in pinning the year
     * at that limit. Note that for most calendars in which era 0 years move forward in
     * time (such as Buddhist, Hebrew, or Islamic), it is possible for add or roll to
     * result in negative years for era 0 (that is the only way to represent years before
     * the calendar epoch in such calendars).
     * <p>
     * <b>Note:</b> Calling <tt>roll(field, true)</tt> N times is <em>not</em>
     * necessarily equivalent to calling <tt>roll(field, N)</tt>.  For example,
     * imagine that you start with the date Gregorian date January 31, 1995.  If you call
     * <tt>roll(Calendar.MONTH, 2)</tt>, the result will be March 31, 1995.
     * But if you call <tt>roll(Calendar.MONTH, true)</tt>, the result will be
     * February 28, 1995.  Calling it one more time will give March 28, 1995, which
     * is usually not the desired result.
     * <p>
     * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
     * than attempting to perform arithmetic operations directly on the fields
     * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
     * to have fields with non-linear behavior, for example missing months
     * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
     * methods will take this into account, while simple arithmetic manipulations
     * may give invalid results.
     * <p>
     * @param field the calendar field to roll.
     *
     * @param up    indicates if the value of the specified time field is to be
     *              rolled up or rolled down. Use <code>true</code> if rolling up,
     *              <code>false</code> otherwise.
     *
     * @exception   IllegalArgumentException if the field is invalid or refers
     *              to a field that cannot be handled by this method.
     * @see #roll(int, int)
     * @see #add
     * @stable ICU 2.0
     */
    public final void roll(int field, boolean up)
    {
        roll(field, up ? +1 : -1);
    }

    /**
     * Rolls (up/down) a specified amount time on the given field.  For
     * example, to roll the current date up by three days, you can call
     * <code>roll(Calendar.DATE, 3)</code>.  If the
     * field is rolled past its maximum allowable value, it will "wrap" back
     * to its minimum and continue rolling.
     * For example, calling <code>roll(Calendar.DATE, 10)</code>
     * on a Gregorian calendar set to 4/25/96 will result in the date 4/5/96.
     * <p>
     * When rolling on certain fields, the values of other fields may conflict and
     * need to be changed.  For example, when rolling the {@link #MONTH MONTH} field
     * for the Gregorian date 1/31/96 by +1, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
     * must be adjusted so that the result is 2/29/96 rather than the invalid
     * 2/31/96.
     * <p>
     * Rolling by a positive value always means rolling forward in time (unless
     * the limit of the field is reached, in which case it may pin or wrap), so for the
     * Gregorian calendar, starting with 100 BC and rolling the year by + 1 results in 99 BC.
     * When eras have a definite beginning and end (as in the Chinese calendar, or as in
     * most eras in the Japanese calendar) then rolling the year past either limit of the
     * era will cause the year to wrap around. When eras only have a limit at one end,
     * then attempting to roll the year past that limit will result in pinning the year
     * at that limit. Note that for most calendars in which era 0 years move forward in
     * time (such as Buddhist, Hebrew, or Islamic), it is possible for add or roll to
     * result in negative years for era 0 (that is the only way to represent years before
     * the calendar epoch in such calendars).
     * <p>
     * {@icunote} the ICU implementation of this method is able to roll
     * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
     * and {@link #ZONE_OFFSET ZONE_OFFSET}.  Subclasses may, of course, add support for
     * additional fields in their overrides of <code>roll</code>.
     * <p>
     * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
     * than attempting to perform arithmetic operations directly on the fields
     * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
     * to have fields with non-linear behavior, for example missing months
     * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
     * methods will take this into account, while simple arithmetic manipulations
     * may give invalid results.
     * <p>
     * <b>Subclassing:</b><br>
     * This implementation of <code>roll</code> assumes that the behavior of the
     * field is continuous between its minimum and maximum, which are found by
     * calling {@link #getActualMinimum getActualMinimum} and {@link #getActualMaximum getActualMaximum}.
     * For most such fields, simple addition, subtraction, and modulus operations
     * are sufficient to perform the roll.  For week-related fields,
     * the results of {@link #getFirstDayOfWeek getFirstDayOfWeek} and
     * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} are also necessary.
     * Subclasses can override these two methods if their values differ from the defaults.
     * <p>
     * Subclasses that have fields for which the assumption of continuity breaks
     * down must overide <code>roll</code> to handle those fields specially.
     * For example, in the Hebrew calendar the month "Adar I"
     * only occurs in leap years; in other years the calendar jumps from
     * Shevat (month #4) to Adar (month #6).  The
     * {@link HebrewCalendar#roll HebrewCalendar.roll} method takes this into account,
     * so that rolling the month of Shevat by one gives the proper result (Adar) in a
     * non-leap year.
     * <p>
     * @param field     the calendar field to roll.
     * @param amount    the amount by which the field should be rolled.
     *
     * @exception   IllegalArgumentException if the field is invalid or refers
     *              to a field that cannot be handled by this method.
     * @see #roll(int, boolean)
     * @see #add
     * @stable ICU 2.0
     */
    public void roll(int field, int amount) {

        if (amount == 0) {
            return; // Nothing to do
        }

        complete();

        switch (field) {
        case DAY_OF_MONTH:
        case AM_PM:
        case MINUTE:
        case SECOND:
        case MILLISECOND:
        case MILLISECONDS_IN_DAY:
        case ERA:
            // These are the standard roll instructions.  These work for all
            // simple cases, that is, cases in which the limits are fixed, such
            // as the hour, the day of the month, and the era.
        {
            int min = getActualMinimum(field);
            int max = getActualMaximum(field);
            int gap = max - min + 1;

            int value = internalGet(field) + amount;
            value = (value - min) % gap;
            if (value < 0) {
                value += gap;
            }
            value += min;

            set(field, value);
            return;
        }

        case HOUR:
        case HOUR_OF_DAY:
            // Rolling the hour is difficult on the ONSET and CEASE days of
            // daylight savings.  For example, if the change occurs at
            // 2 AM, we have the following progression:
            // ONSET: 12 Std -> 1 Std -> 3 Dst -> 4 Dst
            // CEASE: 12 Dst -> 1 Dst -> 1 Std -> 2 Std
            // To get around this problem we don't use fields; we manipulate
            // the time in millis directly.
        {
            // Assume min == 0 in calculations below
            long start = getTimeInMillis();
            int oldHour = internalGet(field);
            int max = getMaximum(field);
            int newHour = (oldHour + amount) % (max + 1);
            if (newHour < 0) {
                newHour += max + 1;
            }
            setTimeInMillis(start + ONE_HOUR * ((long)newHour - oldHour));
            return;
        }

        case MONTH:
            // Rolling the month involves both pinning the final value
            // and adjusting the DAY_OF_MONTH if necessary.  We only adjust the
            // DAY_OF_MONTH if, after updating the MONTH field, it is illegal.
            // E.g., <jan31>.roll(MONTH, 1) -> <feb28> or <feb29>.
        {
            int max = getActualMaximum(MONTH);
            int mon = (internalGet(MONTH) + amount) % (max+1);

            if (mon < 0) {
                mon += (max + 1);
            }
            set(MONTH, mon);

            // Keep the day of month in range.  We don't want to spill over
            // into the next month; e.g., we don't want jan31 + 1 mo -> feb31 ->
            // mar3.
            pinField(DAY_OF_MONTH);
            return;
        }

        case YEAR:
        case YEAR_WOY:
            // * If era==0 and years go backwards in time, change sign of amount.
            // * Until we have new API per #9393, we temporarily hardcode knowledge of
            //   which calendars have era 0 years that go backwards.
        {
            boolean era0WithYearsThatGoBackwards = false;
            int era = get(ERA);
            if (era == 0) {
                String calType = getType();
                if (calType.equals("gregorian") || calType.equals("roc") || calType.equals("coptic")) {
                    amount = -amount;
                    era0WithYearsThatGoBackwards = true;
                }
            }
            int newYear = internalGet(field) + amount;
            if (era > 0 || newYear >= 1) {
                int maxYear = getActualMaximum(field);
                if (maxYear < 32768) {
                    // this era has real bounds, roll should wrap years
                    if (newYear < 1) {
                        newYear = maxYear - ((-newYear) % maxYear);
                    } else if (newYear > maxYear) {
                        newYear = ((newYear - 1) % maxYear) + 1;
                    }
                    // else era is unbounded, just pin low year instead of wrapping
                } else if (newYear < 1) {
                    newYear = 1;
                }
                // else we are in era 0 with newYear < 1;
                // calendars with years that go backwards must pin the year value at 0,
                // other calendars can have years < 0 in era 0
            } else if (era0WithYearsThatGoBackwards) {
                newYear = 1;
            }
            set(field, newYear);
            pinField(MONTH);
            pinField(DAY_OF_MONTH);
            return;
        }
        case EXTENDED_YEAR:
            // Rolling the year can involve pinning the DAY_OF_MONTH.
            set(field, internalGet(field) + amount);
            pinField(MONTH);
            pinField(DAY_OF_MONTH);
            return;

        case WEEK_OF_MONTH:
        {
            // This is tricky, because during the roll we may have to shift
            // to a different day of the week.  For example:

            //    s  m  t  w  r  f  s
            //          1  2  3  4  5
            //    6  7  8  9 10 11 12

            // When rolling from the 6th or 7th back one week, we go to the
            // 1st (assuming that the first partial week counts).  The same
            // thing happens at the end of the month.

            // The other tricky thing is that we have to figure out whether
            // the first partial week actually counts or not, based on the
            // minimal first days in the week.  And we have to use the
            // correct first day of the week to delineate the week
            // boundaries.

            // Here's our algorithm.  First, we find the real boundaries of
            // the month.  Then we discard the first partial week if it
            // doesn't count in this locale.  Then we fill in the ends with
            // phantom days, so that the first partial week and the last
            // partial week are full weeks.  We then have a nice square
            // block of weeks.  We do the usual rolling within this block,
            // as is done elsewhere in this method.  If we wind up on one of
            // the phantom days that we added, we recognize this and pin to
            // the first or the last day of the month.  Easy, eh?

            // Normalize the DAY_OF_WEEK so that 0 is the first day of the week
            // in this locale.  We have dow in 0..6.
            int dow = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek();
            if (dow < 0) dow += 7;

            // Find the day of the week (normalized for locale) for the first
            // of the month.
            int fdm = (dow - internalGet(DAY_OF_MONTH) + 1) % 7;
            if (fdm < 0) fdm += 7;

            // Get the first day of the first full week of the month,
            // including phantom days, if any.  Figure out if the first week
            // counts or not; if it counts, then fill in phantom days.  If
            // not, advance to the first real full week (skip the partial week).
            int start;
            if ((7 - fdm) < getMinimalDaysInFirstWeek())
                start = 8 - fdm; // Skip the first partial week
            else
                start = 1 - fdm; // This may be zero or negative

            // Get the day of the week (normalized for locale) for the last
            // day of the month.
            int monthLen = getActualMaximum(DAY_OF_MONTH);
            int ldm = (monthLen - internalGet(DAY_OF_MONTH) + dow) % 7;
            // We know monthLen >= DAY_OF_MONTH so we skip the += 7 step here.

            // Get the limit day for the blocked-off rectangular month; that
            // is, the day which is one past the last day of the month,
            // after the month has already been filled in with phantom days
            // to fill out the last week.  This day has a normalized DOW of 0.
            int limit = monthLen + 7 - ldm;

            // Now roll between start and (limit - 1).
            int gap = limit - start;
            int day_of_month = (internalGet(DAY_OF_MONTH) + amount*7 -
                    start) % gap;
            if (day_of_month < 0) day_of_month += gap;
            day_of_month += start;

            // Finally, pin to the real start and end of the month.
            if (day_of_month < 1) day_of_month = 1;
            if (day_of_month > monthLen) day_of_month = monthLen;

            // Set the DAY_OF_MONTH.  We rely on the fact that this field
            // takes precedence over everything else (since all other fields
            // are also set at this point).  If this fact changes (if the
            // disambiguation algorithm changes) then we will have to unset
            // the appropriate fields here so that DAY_OF_MONTH is attended
            // to.
            set(DAY_OF_MONTH, day_of_month);
            return;
        }
        case WEEK_OF_YEAR:
        {
            // This follows the outline of WEEK_OF_MONTH, except it applies
            // to the whole year.  Please see the comment for WEEK_OF_MONTH
            // for general notes.

            // Normalize the DAY_OF_WEEK so that 0 is the first day of the week
            // in this locale.  We have dow in 0..6.
            int dow = internalGet(DAY_OF_WEEK) - getFirstDayOfWeek();
            if (dow < 0) dow += 7;

            // Find the day of the week (normalized for locale) for the first
            // of the year.
            int fdy = (dow - internalGet(DAY_OF_YEAR) + 1) % 7;
            if (fdy < 0) fdy += 7;

            // Get the first day of the first full week of the year,
            // including phantom days, if any.  Figure out if the first week
            // counts or not; if it counts, then fill in phantom days.  If
            // not, advance to the first real full week (skip the partial week).
            int start;
            if ((7 - fdy) < getMinimalDaysInFirstWeek())
                start = 8 - fdy; // Skip the first partial week
            else
                start = 1 - fdy; // This may be zero or negative

            // Get the day of the week (normalized for locale) for the last
            // day of the year.
            int yearLen = getActualMaximum(DAY_OF_YEAR);
            int ldy = (yearLen - internalGet(DAY_OF_YEAR) + dow) % 7;
            // We know yearLen >= DAY_OF_YEAR so we skip the += 7 step here.

            // Get the limit day for the blocked-off rectangular year; that
            // is, the day which is one past the last day of the year,
            // after the year has already been filled in with phantom days
            // to fill out the last week.  This day has a normalized DOW of 0.
            int limit = yearLen + 7 - ldy;

            // Now roll between start and (limit - 1).
            int gap = limit - start;
            int day_of_year = (internalGet(DAY_OF_YEAR) + amount*7 -
                    start) % gap;
            if (day_of_year < 0) day_of_year += gap;
            day_of_year += start;

            // Finally, pin to the real start and end of the month.
            if (day_of_year < 1) day_of_year = 1;
            if (day_of_year > yearLen) day_of_year = yearLen;

            // Make sure that the year and day of year are attended to by
            // clearing other fields which would normally take precedence.
            // If the disambiguation algorithm is changed, this section will
            // have to be updated as well.
            set(DAY_OF_YEAR, day_of_year);
            clear(MONTH);
            return;
        }
        case DAY_OF_YEAR:
        {
            // Roll the day of year using millis.  Compute the millis for
            // the start of the year, and get the length of the year.
            long delta = amount * ONE_DAY; // Scale up from days to millis
            long min2 = time - (internalGet(DAY_OF_YEAR) - 1) * ONE_DAY;
            int yearLength = getActualMaximum(DAY_OF_YEAR);
            time = (time + delta - min2) % (yearLength*ONE_DAY);
            if (time < 0) time += yearLength*ONE_DAY;
            setTimeInMillis(time + min2);
            return;
        }
        case DAY_OF_WEEK:
        case DOW_LOCAL:
        {
            // Roll the day of week using millis.  Compute the millis for
            // the start of the week, using the first day of week setting.
            // Restrict the millis to [start, start+7days).
            long delta = amount * ONE_DAY; // Scale up from days to millis
            // Compute the number of days before the current day in this
            // week.  This will be a value 0..6.
            int leadDays = internalGet(field);
            leadDays -= (field == DAY_OF_WEEK) ? getFirstDayOfWeek() : 1;
            if (leadDays < 0) leadDays += 7;
            long min2 = time - leadDays * ONE_DAY;
            time = (time + delta - min2) % ONE_WEEK;
            if (time < 0) time += ONE_WEEK;
            setTimeInMillis(time + min2);
            return;
        }
        case DAY_OF_WEEK_IN_MONTH:
        {
            // Roll the day of week in the month using millis.  Determine
            // the first day of the week in the month, and then the last,
            // and then roll within that range.
            long delta = amount * ONE_WEEK; // Scale up from weeks to millis
            // Find the number of same days of the week before this one
            // in this month.
            int preWeeks = (internalGet(DAY_OF_MONTH) - 1) / 7;
            // Find the number of same days of the week after this one
            // in this month.
            int postWeeks = (getActualMaximum(DAY_OF_MONTH) -
                    internalGet(DAY_OF_MONTH)) / 7;
            // From these compute the min and gap millis for rolling.
            long min2 = time - preWeeks * ONE_WEEK;
            long gap2 = ONE_WEEK * (preWeeks + postWeeks + 1); // Must add 1!
            // Roll within this range
            time = (time + delta - min2) % gap2;
            if (time < 0) time += gap2;
            setTimeInMillis(time + min2);
            return;
        }
        case JULIAN_DAY:
            set(field, internalGet(field) + amount);
            return;
        default:
            // Other fields cannot be rolled by this method
            throw new IllegalArgumentException("Calendar.roll(" + fieldName(field) +
                    ") not supported");
        }
    }

    /**
     * Add a signed amount to a specified field, using this calendar's rules.
     * For example, to add three days to the current date, you can call
     * <code>add(Calendar.DATE, 3)</code>.
     * <p>
     * When adding to certain fields, the values of other fields may conflict and
     * need to be changed.  For example, when adding one to the {@link #MONTH MONTH} field
     * for the Gregorian date 1/31/96, the {@link #DAY_OF_MONTH DAY_OF_MONTH} field
     * must be adjusted so that the result is 2/29/96 rather than the invalid
     * 2/31/96.
     * <p>
     * Adding a positive value always means moving forward in time, so for the Gregorian
     * calendar, starting with 100 BC and adding +1 to year results in 99 BC (even though
     * this actually reduces the numeric value of the field itself).
     * <p>
     * {@icunote} The ICU implementation of this method is able to add to
     * all fields except for {@link #ERA ERA}, {@link #DST_OFFSET DST_OFFSET},
     * and {@link #ZONE_OFFSET ZONE_OFFSET}.  Subclasses may, of course, add support for
     * additional fields in their overrides of <code>add</code>.
     * <p>
     * <b>Note:</b> You should always use <tt>roll</tt> and <tt>add</tt> rather
     * than attempting to perform arithmetic operations directly on the fields
     * of a <tt>Calendar</tt>.  It is quite possible for <tt>Calendar</tt> subclasses
     * to have fields with non-linear behavior, for example missing months
     * or days during non-leap years.  The subclasses' <tt>add</tt> and <tt>roll</tt>
     * methods will take this into account, while simple arithmetic manipulations
     * may give invalid results.
     * <p>
     * <b>Subclassing:</b><br>
     * This implementation of <code>add</code> assumes that the behavior of the
     * field is continuous between its minimum and maximum, which are found by
     * calling {@link #getActualMinimum getActualMinimum} and
     * {@link #getActualMaximum getActualMaximum}.
     * For such fields, simple arithmetic operations are sufficient to
     * perform the add.
     * <p>
     * Subclasses that have fields for which this assumption of continuity breaks
     * down must overide <code>add</code> to handle those fields specially.
     * For example, in the Hebrew calendar the month "Adar I"
     * only occurs in leap years; in other years the calendar jumps from
     * Shevat (month #4) to Adar (month #6).  The
     * {@link HebrewCalendar#add HebrewCalendar.add} method takes this into account,
     * so that adding one month
     * to a date in Shevat gives the proper result (Adar) in a non-leap year.
     * <p>
     * @param field     the time field.
     * @param amount    the amount to add to the field.
     *
     * @exception   IllegalArgumentException if the field is invalid or refers
     *              to a field that cannot be handled by this method.
     * @see #roll(int, int)
     * @stable ICU 2.0
     */
    @SuppressWarnings("fallthrough")
    public void add(int field, int amount) {

        if (amount == 0) {
            return;   // Do nothing!
        }

        // We handle most fields in the same way.  The algorithm is to add
        // a computed amount of millis to the current millis.  The only
        // wrinkle is with DST (and/or a change to the zone's UTC offset, which
        // we'll include with DST) -- for some fields, like the DAY_OF_MONTH,
        // we don't want the wall time to shift due to changes in DST.  If the
        // result of the add operation is to move from DST to Standard, or
        // vice versa, we need to adjust by an hour forward or back,
        // respectively.  For such fields we set keepWallTimeInvariant to true.

        // We only adjust the DST for fields larger than an hour.  For
        // fields smaller than an hour, we cannot adjust for DST without
        // causing problems.  for instance, if you add one hour to April 5,
        // 1998, 1:00 AM, in PST, the time becomes "2:00 AM PDT" (an
        // illegal value), but then the adjustment sees the change and
        // compensates by subtracting an hour.  As a result the time
        // doesn't advance at all.

        // For some fields larger than a day, such as a MONTH, we pin the
        // DAY_OF_MONTH.  This allows <March 31>.add(MONTH, 1) to be
        // <April 30>, rather than <April 31> => <May 1>.

        long delta = amount; // delta in ms
        boolean keepWallTimeInvariant = true;

        switch (field) {
        case ERA:
            set(field, get(field) + amount);
            pinField(ERA);
            return;

        case YEAR:
        case YEAR_WOY:
            // * If era=0 and years go backwards in time, change sign of amount.
            // * Until we have new API per #9393, we temporarily hardcode knowledge of
            //   which calendars have era 0 years that go backwards.
            // * Note that for YEAR (but not YEAR_WOY) we could instead handle
            //   this by applying the amount to the EXTENDED_YEAR field; but since
            //   we would still need to handle YEAR_WOY as below, might as well
            //   also handle YEAR the same way.
        {
            int era = get(ERA);
            if (era == 0) {
                String calType = getType();
                if (calType.equals("gregorian") || calType.equals("roc") || calType.equals("coptic")) {
                    amount = -amount;
                }
            }
        }
        // Fall through into standard handling
        case EXTENDED_YEAR:
        case MONTH:
        {
            boolean oldLenient = isLenient();
            setLenient(true);
            set(field, get(field) + amount);
            pinField(DAY_OF_MONTH);
            if(oldLenient==false) {
                complete();
                setLenient(oldLenient);
            }
        }
        return;

        case WEEK_OF_YEAR:
        case WEEK_OF_MONTH:
        case DAY_OF_WEEK_IN_MONTH:
            delta *= ONE_WEEK;
            break;

        case AM_PM:
            delta *= 12 * ONE_HOUR;
            break;

        case DAY_OF_MONTH:
        case DAY_OF_YEAR:
        case DAY_OF_WEEK:
        case DOW_LOCAL:
        case JULIAN_DAY:
            delta *= ONE_DAY;
            break;

        case HOUR_OF_DAY:
        case HOUR:
            delta *= ONE_HOUR;
            keepWallTimeInvariant = false;
            break;

        case MINUTE:
            delta *= ONE_MINUTE;
            keepWallTimeInvariant = false;
            break;

        case SECOND:
            delta *= ONE_SECOND;
            keepWallTimeInvariant = false;
            break;

        case MILLISECOND:
        case MILLISECONDS_IN_DAY:
            keepWallTimeInvariant = false;
            break;

        default:
            throw new IllegalArgumentException("Calendar.add(" + fieldName(field) +
                    ") not supported");
        }

        // In order to keep the wall time invariant (for fields where this is
        // appropriate), check the combined DST & ZONE offset before and
        // after the add() operation. If it changes, then adjust the millis
        // to compensate.
        int prevOffset = 0;
        int prevWallTime = 0;
        if (keepWallTimeInvariant) {
            prevOffset = get(DST_OFFSET) + get(ZONE_OFFSET);
            prevWallTime = get(MILLISECONDS_IN_DAY);
        }

        setTimeInMillis(getTimeInMillis() + delta);

        if (keepWallTimeInvariant) {
            int newWallTime = get(MILLISECONDS_IN_DAY);
            if (newWallTime != prevWallTime) {
                // There is at least one zone transition between the base
                // time and the result time. As the result, wall time has
                // changed.
                long t = internalGetTimeInMillis();
                int newOffset = get(DST_OFFSET) + get(ZONE_OFFSET);
                if (newOffset != prevOffset) {
                    // When the difference of the previous UTC offset and
                    // the new UTC offset exceeds 1 full day, we do not want
                    // to roll over/back the date. For now, this only happens
                    // in Samoa (Pacific/Apia) on Dec 30, 2011. See ticket:9452.
                    long adjAmount = (prevOffset - newOffset) % ONE_DAY;
                    if (adjAmount != 0) {
                        setTimeInMillis(t + adjAmount);
                        newWallTime = get(MILLISECONDS_IN_DAY);
                    }
                    if (newWallTime != prevWallTime) {
                        // The result wall time or adjusted wall time was shifted because
                        // the target wall time does not exist on the result date.
                        switch (skippedWallTime) {
                        case WALLTIME_FIRST:
                            if (adjAmount > 0) {
                                setTimeInMillis(t);
                            }
                            break;
                        case WALLTIME_LAST:
                            if (adjAmount < 0) {
                                setTimeInMillis(t);
                            }
                            break;
                        case WALLTIME_NEXT_VALID:
                            long tmpT = adjAmount > 0 ? internalGetTimeInMillis() : t;
                            Long immediatePrevTrans = getImmediatePreviousZoneTransition(tmpT);
                            if (immediatePrevTrans != null) {
                                setTimeInMillis(immediatePrevTrans);
                            } else {
                                throw new RuntimeException("Could not locate a time zone transition before " + tmpT);
                            }
                            break;
                        }
                    }
                }
            }
        }
    }

    /**
     * Returns the name of this calendar in the language of the given locale.
     * @stable ICU 2.0
     */
    public String getDisplayName(Locale loc) {
        return this.getClass().getName();
    }

    /**
     * Returns the name of this calendar in the language of the given locale.
     * @stable ICU 3.2
     */
    public String getDisplayName(ULocale loc) {
        return this.getClass().getName();
    }

    /**
     * Compares the times (in millis) represented by two
     * <code>Calendar</code> objects.
     *
     * @param that the <code>Calendar</code> to compare to this.
     * @return <code>0</code> if the time represented by
     * this <code>Calendar</code> is equal to the time represented
     * by that <code>Calendar</code>, a value less than
     * <code>0</code> if the time represented by this is before
     * the time represented by that, and a value greater than
     * <code>0</code> if the time represented by this
     * is after the time represented by that.
     * @throws NullPointerException if that
     * <code>Calendar</code> is null.
     * @throws IllegalArgumentException if the time of that
     * <code>Calendar</code> can't be obtained because of invalid
     * calendar values.
     * @stable ICU 3.4
     */
    @Override
    public int compareTo(Calendar that) {
        long v = getTimeInMillis() - that.getTimeInMillis();
        return v < 0 ? -1 : (v > 0 ? 1 : 0);
    }

    //-------------------------------------------------------------------------
    // Interface for creating custon DateFormats for different types of Calendars
    //-------------------------------------------------------------------------

    /**
     * {@icu} Returns a <code>DateFormat</code> appropriate to this calendar.
     * Subclasses wishing to specialize this behavior should override
     * {@link #handleGetDateFormat}.
     * @stable ICU 2.0
     */
    public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, Locale loc) {
        return formatHelper(this, ULocale.forLocale(loc), dateStyle, timeStyle);
    }

    /**
     * {@icu} Returns a <code>DateFormat</code> appropriate to this calendar.
     * Subclasses wishing to specialize this behavior should override
     * {@link #handleGetDateFormat}.
     * @stable ICU 3.2
     */
    public DateFormat getDateTimeFormat(int dateStyle, int timeStyle, ULocale loc) {
        return formatHelper(this, loc, dateStyle, timeStyle);
    }

    /**
     * Creates a <code>DateFormat</code> appropriate to this calendar.
     * This is a framework method for subclasses to override.  This method
     * is responsible for creating the calendar-specific DateFormat and
     * DateFormatSymbols objects as needed.
     * @param pattern the pattern, specific to the <code>DateFormat</code>
     * subclass
     * @param locale the locale for which the symbols should be drawn
     * @return a <code>DateFormat</code> appropriate to this calendar
     * @stable ICU 2.0
     */
    protected DateFormat handleGetDateFormat(String pattern, Locale locale) {
        return handleGetDateFormat(pattern, null, ULocale.forLocale(locale));
    }

    /**
     * Creates a <code>DateFormat</code> appropriate to this calendar.
     * This is a framework method for subclasses to override.  This method
     * is responsible for creating the calendar-specific DateFormat and
     * DateFormatSymbols objects as needed.
     * @param pattern the pattern, specific to the <code>DateFormat</code>
     * subclass
     * @param override The override string.  A numbering system override string can take one of the following forms:
     *     1). If just a numbering system name is specified, it applies to all numeric fields in the date format pattern.
     *     2). To specify an alternate numbering system on a field by field basis, use the field letters from the pattern
     *         followed by an = sign, followed by the numbering system name.  For example, to specify that just the year
     *         be formatted using Hebrew digits, use the override "y=hebr".  Multiple overrides can be specified in a single
     *         string by separating them with a semi-colon. For example, the override string "m=thai;y=deva" would format using
     *         Thai digits for the month and Devanagari digits for the year.
     * @param locale the locale for which the symbols should be drawn
     * @return a <code>DateFormat</code> appropriate to this calendar
     * @stable ICU 4.2
     */
    protected DateFormat handleGetDateFormat(String pattern, String override, Locale locale) {
        return handleGetDateFormat(pattern, override, ULocale.forLocale(locale));
    }

    /**
     * Creates a <code>DateFormat</code> appropriate to this calendar.
     * This is a framework method for subclasses to override.  This method
     * is responsible for creating the calendar-specific DateFormat and
     * DateFormatSymbols objects as needed.
     * @param pattern the pattern, specific to the <code>DateFormat</code>
     * subclass
     * @param locale the locale for which the symbols should be drawn
     * @return a <code>DateFormat</code> appropriate to this calendar
     * @stable ICU 2.0
     */
    protected DateFormat handleGetDateFormat(String pattern, ULocale locale) {
        return handleGetDateFormat(pattern, null, locale);
    }

    /**
     * Creates a <code>DateFormat</code> appropriate to this calendar.
     * This is a framework method for subclasses to override.  This method
     * is responsible for creating the calendar-specific DateFormat and
     * DateFormatSymbols objects as needed.
     * @param pattern the pattern, specific to the <code>DateFormat</code>
     * subclass
     * @param locale the locale for which the symbols should be drawn
     * @return a <code>DateFormat</code> appropriate to this calendar
     * @draft ICU 3.2 (retain)
     * @provisional This API might change or be removed in a future release.
     */
    protected DateFormat handleGetDateFormat(String pattern, String override, ULocale locale) {
        FormatConfiguration fmtConfig = new FormatConfiguration();
        fmtConfig.pattern = pattern;
        fmtConfig.override = override;
        fmtConfig.formatData = new DateFormatSymbols(this, locale);
        fmtConfig.loc = locale;
        fmtConfig.cal = this;

        return SimpleDateFormat.getInstance(fmtConfig);
    }

    // date format pattern cache
    private static final ICUCache<String, PatternData> PATTERN_CACHE =
            new SimpleCache<>();
    // final fallback patterns
    private static final String[] DEFAULT_PATTERNS = {
        "HH:mm:ss z",
        "HH:mm:ss z",
        "HH:mm:ss",
        "HH:mm",
        "EEEE, yyyy MMMM dd",
        "yyyy MMMM d",
        "yyyy MMM d",
        "yy/MM/dd",
        "{1} {0}",
        "{1} {0}",
        "{1} {0}",
        "{1} {0}",
        "{1} {0}"
    };
    // final fallback patterns
    private static final String[] TIME_SKELETONS = {
        "jmmsszzzz",    // Full
        "jmmssz",       // Long
        "jmmss",        // Medium
        "jmm"           // Short
    };

    static private DateFormat formatHelper(Calendar cal, ULocale loc, int dateStyle,
            int timeStyle) {
        if (timeStyle < DateFormat.NONE || timeStyle > DateFormat.SHORT) {
            throw new IllegalArgumentException("Illegal time style " + timeStyle);
        }
        if (dateStyle < DateFormat.NONE || dateStyle > DateFormat.SHORT) {
            throw new IllegalArgumentException("Illegal date style " + dateStyle);
        }

        PatternData patternData = PatternData.make(cal, loc);
        String override = null;

        // Resolve a pattern for the date/time style
        String pattern = null;
        if ((timeStyle >= 0) && (dateStyle >= 0)) {
            pattern = SimpleFormatterImpl.formatRawPattern(
                    patternData.getDateTimePattern(dateStyle), 2, 2,
                    patternData.patterns[timeStyle],
                    patternData.patterns[dateStyle + 4]);
            // Might need to merge the overrides from the date and time into a single
            // override string TODO: Right now we are forcing the date's override into the
            // time style.
            if ( patternData.overrides != null ) {
                String dateOverride = patternData.overrides[dateStyle + 4];
                String timeOverride = patternData.overrides[timeStyle];
                override = mergeOverrideStrings(
                        patternData.patterns[dateStyle+4],
                        patternData.patterns[timeStyle],
                        dateOverride, timeOverride);
            }
        } else if (timeStyle >= 0) {
            pattern = patternData.patterns[timeStyle];
            if ( patternData.overrides != null ) {
                override = patternData.overrides[timeStyle];
            }
        } else if (dateStyle >= 0) {
            pattern = patternData.patterns[dateStyle + 4];
            if ( patternData.overrides != null ) {
                override = patternData.overrides[dateStyle + 4];
            }
        } else {
            throw new IllegalArgumentException("No date or time style specified");
        }
        DateFormat result = cal.handleGetDateFormat(pattern, override, loc);
        result.setCalendar(cal);
        return result;
    }

    static class PatternData {
        // TODO make this even more object oriented
        private String[] patterns;
        private String[] overrides;
        public PatternData(String[] patterns, String[] overrides) {
            this.patterns = patterns;
            this.overrides = overrides;
        }
        private String getDateTimePattern(int dateStyle) {
            int glueIndex = 8;
            if (patterns.length >= 13) {
                glueIndex += (dateStyle + 1);
            }
            final String dateTimePattern = patterns[glueIndex];
            return dateTimePattern;
        }
        private static PatternData make(Calendar cal, ULocale loc) {
            // First, try to get a pattern from PATTERN_CACHE
            String calType = cal.getType();
            String key = loc.getBaseName() + "+" + calType;
            PatternData patternData = PATTERN_CACHE.get(key);
            if (patternData == null) {
                // Cache missed.  Get one from bundle
                try {
                    patternData = getPatternData(loc, calType);
                } catch (MissingResourceException e) {
                    patternData = new PatternData(DEFAULT_PATTERNS, null);
                }
                PATTERN_CACHE.put(key, patternData);
            }
            return patternData;
        }
    }

    /**
     * Retrieves the DateTime patterns and overrides from the resource bundle and generates a
     * new PatternData object.
     * @param locale Locale to retrieve.
     * @param calType Calendar type to retrieve. If not found will fallback to gregorian.
     * @return PatternData object for this locale and calendarType.
     */
    private static PatternData getPatternData(ULocale locale, String calType) {
        ICUResourceBundle rb =
                (ICUResourceBundle) UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, locale);
        ICUResourceBundle dtPatternsRb = rb.findWithFallback("calendar/" + calType + "/DateTimePatterns");
        if (dtPatternsRb == null) {
            dtPatternsRb = rb.getWithFallback("calendar/gregorian/DateTimePatterns");
        }

        int patternsSize = dtPatternsRb.getSize();
        String[] dateTimePatterns = new String[patternsSize];
        String[] dateTimePatternsOverrides = new String[patternsSize];
        int i = 0; // index for dateTimePatterns, dateTimePatternsOverrides

        String baseLocID = locale.getBaseName();
        if (baseLocID.length() > 0 && !baseLocID.equals("und")) {
            ULocale baseLoc = new ULocale(baseLocID);
            // The following is different from ICU4C, where we can get the valid locale
            // for the SimpleDateFormat object. Here we do not have a SimpleDateFormat and
            // valid locale for the Calendar is a bit meaningless.
            ULocale validLoc = ULocale.addLikelySubtags(dtPatternsRb.getULocale());
            if (validLoc != baseLoc) {
                String baseReg = baseLoc.getCountry();
                if ((baseReg.length() > 0 && !baseReg.equals(validLoc.getCountry()))
                        || !baseLoc.getLanguage().equals(validLoc.getLanguage())) {
                    // use DTPG if the standard time formats may have the wrong time cycle,
                    // because the valid locale differs in important ways (region, language)
                    // from the base locale.
                    // We could *also* check whether they do actually have a mismatch with
                    // the time cycle preferences for the region, but that is a lot more
                    // work for little or no additional benefit, since just going ahead
                    // and always synthesizing the time format as per the following should
                    // create a locale-appropriate pattern with cycle that matches the
                    // region preferences anyway.
                    // In this case we get the first 4 entries of dateTimePatterns using
                    // DateTimePatternGenerator, not resource data.
                    DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstanceNoStdPat(locale);
                    for (; i < 4; i++) {
                        dateTimePatterns[i] = dtpg.getBestPattern(TIME_SKELETONS[i]);
                    }
                }
            }
        }

        for (; i < patternsSize; i++) { // get all or remaining dateTimePatterns entries
            ICUResourceBundle concatenationPatternRb = (ICUResourceBundle) dtPatternsRb.get(i);
            switch (concatenationPatternRb.getType()) {
                case UResourceBundle.STRING:
                    dateTimePatterns[i] = concatenationPatternRb.getString();
                    break;
                case UResourceBundle.ARRAY:
                    dateTimePatterns[i] = concatenationPatternRb.getString(0);
                    dateTimePatternsOverrides[i] = concatenationPatternRb.getString(1);
                    break;
            }
        }
        return new PatternData(dateTimePatterns, dateTimePatternsOverrides);
    }

    /**
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public static String getDateTimePattern(Calendar cal, ULocale uLocale, int dateStyle) {
        PatternData patternData = PatternData.make(cal, uLocale);
        return patternData.getDateTimePattern(dateStyle);
    }

    private static String mergeOverrideStrings( String datePattern, String timePattern,
            String dateOverride, String timeOverride ) {

        if ( dateOverride == null && timeOverride == null ) {
            return null;
        }

        if ( dateOverride == null ) {
            return expandOverride(timePattern,timeOverride);
        }

        if ( timeOverride == null ) {
            return expandOverride(datePattern,dateOverride);
        }

        if ( dateOverride.equals(timeOverride) ) {
            return dateOverride;
        }

        return (expandOverride(datePattern,dateOverride)+";"+
                expandOverride(timePattern,timeOverride));

    }

    private static final char QUOTE = '\'';
    private static String expandOverride(String pattern, String override) {

        if (override.indexOf('=') >= 0) {
            return override;
        }
        boolean inQuotes = false;
        char prevChar = ' ';
        StringBuilder result = new StringBuilder();

        StringCharacterIterator it = new StringCharacterIterator(pattern);

        for (char c = it.first(); c!= StringCharacterIterator.DONE; c = it.next()) {
            if ( c == QUOTE ) {
                inQuotes = !inQuotes;
                prevChar = c;
                continue;
            }
            if ( !inQuotes && c != prevChar ) {
                if (result.length() > 0) {
                    result.append(";");
                }
                result.append(c);
                result.append("=");
                result.append(override);
            }
            prevChar = c;
        }
        return result.toString();
    }
    /**
     * An instance of FormatConfiguration represents calendar specific
     * date format configuration and used for calling the ICU private
     * SimpleDateFormat factory method.
     *
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public static class FormatConfiguration {
        private String pattern;
        private String override;
        private DateFormatSymbols formatData;
        private Calendar cal;
        private ULocale loc;

        // Only Calendar can instantiate
        private FormatConfiguration() {
        }

        /**
         * Returns the pattern string
         * @return the format pattern string
         * @internal
         * @deprecated This API is ICU internal only.
         */
        @Deprecated
        public String getPatternString() {
            return pattern;
        }

        /**
         * @internal
         * @deprecated This API is ICU internal only.
         */
        @Deprecated
        public String getOverrideString() {
            return override;
        }

        /**
         * Returns the calendar
         * @return the calendar
         * @internal
         * @deprecated This API is ICU internal only.
         */
        @Deprecated
        public Calendar getCalendar() {
            return cal;
        }

        /**
         * Returns the locale
         * @return the locale
         * @internal
         * @deprecated This API is ICU internal only.
         */
        @Deprecated
        public ULocale getLocale() {
            return loc;
        }

        /**
         * Returns the format symbols
         * @return the format symbols
         * @internal
         * @deprecated This API is ICU internal only.
         */
        @Deprecated
        public DateFormatSymbols getDateFormatSymbols() {
            return formatData;
        }
    }

    //-------------------------------------------------------------------------
    // Protected utility methods for use by subclasses.  These are very handy
    // for implementing add, roll, and computeFields.
    //-------------------------------------------------------------------------

    /**
     * Adjust the specified field so that it is within
     * the allowable range for the date to which this calendar is set.
     * For example, in a Gregorian calendar pinning the {@link #DAY_OF_MONTH DAY_OF_MONTH}
     * field for a calendar set to April 31 would cause it to be set
     * to April 30.
     * <p>
     * <b>Subclassing:</b>
     * <br>
     * This utility method is intended for use by subclasses that need to implement
     * their own overrides of {@link #roll roll} and {@link #add add}.
     * <p>
     * <b>Note:</b>
     * <code>pinField</code> is implemented in terms of
     * {@link #getActualMinimum getActualMinimum}
     * and {@link #getActualMaximum getActualMaximum}.  If either of those methods uses
     * a slow, iterative algorithm for a particular field, it would be
     * unwise to attempt to call <code>pinField</code> for that field.  If you
     * really do need to do so, you should override this method to do
     * something more efficient for that field.
     * <p>
     * @param field The calendar field whose value should be pinned.
     *
     * @see #getActualMinimum
     * @see #getActualMaximum
     * @stable ICU 2.0
     */
    protected void pinField(int field) {
        int max = getActualMaximum(field);
        int min = getActualMinimum(field);

        if (fields[field] > max) {
            set(field, max);
        } else if (fields[field] < min) {
            set(field, min);
        }
    }

    /**
     * Returns the week number of a day, within a period. This may be the week number in
     * a year or the week number in a month. Usually this will be a value &gt;= 1, but if
     * some initial days of the period are excluded from week 1, because
     * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} is &gt; 1, then
     * the week number will be zero for those
     * initial days. This method requires the day number and day of week for some
     * known date in the period in order to determine the day of week
     * on the desired day.
     * <p>
     * <b>Subclassing:</b>
     * <br>
     * This method is intended for use by subclasses in implementing their
     * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods.
     * It is often useful in {@link #getActualMinimum getActualMinimum} and
     * {@link #getActualMaximum getActualMaximum} as well.
     * <p>
     * This variant is handy for computing the week number of some other
     * day of a period (often the first or last day of the period) when its day
     * of the week is not known but the day number and day of week for some other
     * day in the period (e.g. the current date) <em>is</em> known.
     * <p>
     * @param desiredDay    The {@link #DAY_OF_YEAR DAY_OF_YEAR} or
     *              {@link #DAY_OF_MONTH DAY_OF_MONTH} whose week number is desired.
     *              Should be 1 for the first day of the period.
     *
     * @param dayOfPeriod   The {@link #DAY_OF_YEAR DAY_OF_YEAR}
     *              or {@link #DAY_OF_MONTH DAY_OF_MONTH} for a day in the period whose
     *              {@link #DAY_OF_WEEK DAY_OF_WEEK} is specified by the
     *              <code>dayOfWeek</code> parameter.
     *              Should be 1 for first day of period.
     *
     * @param dayOfWeek  The {@link #DAY_OF_WEEK DAY_OF_WEEK} for the day
     *              corresponding to the <code>dayOfPeriod</code> parameter.
     *              1-based with 1=Sunday.
     *
     * @return      The week number (one-based), or zero if the day falls before
     *              the first week because
     *              {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
     *              is more than one.
     * @stable ICU 2.0
     */
    protected int weekNumber(int desiredDay, int dayOfPeriod, int dayOfWeek)
    {
        // Determine the day of the week of the first day of the period
        // in question (either a year or a month).  Zero represents the
        // first day of the week on this calendar.
        int periodStartDayOfWeek = (dayOfWeek - getFirstDayOfWeek() - dayOfPeriod + 1) % 7;
        if (periodStartDayOfWeek < 0) periodStartDayOfWeek += 7;

        // Compute the week number.  Initially, ignore the first week, which
        // may be fractional (or may not be).  We add periodStartDayOfWeek in
        // order to fill out the first week, if it is fractional.
        int weekNo = (desiredDay + periodStartDayOfWeek - 1)/7;

        // If the first week is long enough, then count it.  If
        // the minimal days in the first week is one, or if the period start
        // is zero, we always increment weekNo.
        if ((7 - periodStartDayOfWeek) >= getMinimalDaysInFirstWeek()) ++weekNo;

        return weekNo;
    }

    /**
     * Returns the week number of a day, within a period. This may be the week number in
     * a year, or the week number in a month. Usually this will be a value &gt;= 1, but if
     * some initial days of the period are excluded from week 1, because
     * {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek} is &gt; 1,
     * then the week number will be zero for those
     * initial days. This method requires the day of week for the given date in order to
     * determine the result.
     * <p>
     * <b>Subclassing:</b>
     * <br>
     * This method is intended for use by subclasses in implementing their
     * {@link #computeTime computeTime} and/or {@link #computeFields computeFields} methods.
     * It is often useful in {@link #getActualMinimum getActualMinimum} and
     * {@link #getActualMaximum getActualMaximum} as well.
     * <p>
     * @param dayOfPeriod   The {@link #DAY_OF_YEAR DAY_OF_YEAR} or
     *                      {@link #DAY_OF_MONTH DAY_OF_MONTH} whose week number is desired.
     *                      Should be 1 for the first day of the period.
     *
     * @param dayOfWeek     The {@link #DAY_OF_WEEK DAY_OF_WEEK} for the day
     *                      corresponding to the <code>dayOfPeriod</code> parameter.
     *                      1-based with 1=Sunday.
     *
     * @return      The week number (one-based), or zero if the day falls before
     *              the first week because
     *              {@link #getMinimalDaysInFirstWeek getMinimalDaysInFirstWeek}
     *              is more than one.
     * @stable ICU 2.0
     */
    protected final int weekNumber(int dayOfPeriod, int dayOfWeek)
    {
        return weekNumber(dayOfPeriod, dayOfPeriod, dayOfWeek);
    }

    //-------------------------------------------------------------------------
    // Constants
    //-------------------------------------------------------------------------

    private static final int FIELD_DIFF_MAX_INT = Integer.MAX_VALUE;    // 2147483647

    /**
     * {@icu} Returns the difference between the given time and the time this
     * calendar object is set to.  If this calendar is set
     * <em>before</em> the given time, the returned value will be
     * positive.  If this calendar is set <em>after</em> the given
     * time, the returned value will be negative.  The
     * <code>field</code> parameter specifies the units of the return
     * value.  For example, if <code>fieldDifference(when,
     * Calendar.MONTH)</code> returns 3, then this calendar is set to
     * 3 months before <code>when</code>, and possibly some additional
     * time less than one month.
     *
     * <p>As a side effect of this call, this calendar is advanced
     * toward <code>when</code> by the given amount.  That is, calling
     * this method has the side effect of calling <code>add(field,
     * n)</code>, where <code>n</code> is the return value.
     *
     * <p>Usage: To use this method, call it first with the largest
     * field of interest, then with progressively smaller fields.  For
     * example:
     *
     * <pre>
     * int y = cal.fieldDifference(when, Calendar.YEAR);
     * int m = cal.fieldDifference(when, Calendar.MONTH);
     * int d = cal.fieldDifference(when, Calendar.DATE);</pre>
     *
     * computes the difference between <code>cal</code> and
     * <code>when</code> in years, months, and days.
     *
     * <p>Note: <code>fieldDifference()</code> is
     * <em>asymmetrical</em>.  That is, in the following code:
     *
     * <pre>
     * cal.setTime(date1);
     * int m1 = cal.fieldDifference(date2, Calendar.MONTH);
     * int d1 = cal.fieldDifference(date2, Calendar.DATE);
     * cal.setTime(date2);
     * int m2 = cal.fieldDifference(date1, Calendar.MONTH);
     * int d2 = cal.fieldDifference(date1, Calendar.DATE);</pre>
     *
     * one might expect that <code>m1 == -m2 &amp;&amp; d1 == -d2</code>.
     * However, this is not generally the case, because of
     * irregularities in the underlying calendar system (e.g., the
     * Gregorian calendar has a varying number of days per month).
     *
     * @param when the date to compare this calendar's time to
     * @param field the field in which to compute the result
     * @return the difference, either positive or negative, between
     * this calendar's time and <code>when</code>, in terms of
     * <code>field</code>.
     * @stable ICU 2.0
     */
    public int fieldDifference(Date when, int field) {
        int min = 0;
        long startMs = getTimeInMillis();
        long targetMs = when.getTime();
        // Always add from the start millis.  This accommodates
        // operations like adding years from February 29, 2000 up to
        // February 29, 2004.  If 1, 1, 1, 1 is added to the year
        // field, the DOM gets pinned to 28 and stays there, giving an
        // incorrect DOM difference of 1.  We have to add 1, reset, 2,
        // reset, 3, reset, 4.
        if (startMs < targetMs) {
            int max = 1;
            // Find a value that is too large
            for (;;) {
                setTimeInMillis(startMs);
                add(field, max);
                long ms = getTimeInMillis();
                if (ms == targetMs) {
                    return max;
                } else if (ms > targetMs) {
                    break;
                } else if (max < FIELD_DIFF_MAX_INT) {
                    min = max;
                    max <<= 1;
                    if (max < 0) {
                        max = FIELD_DIFF_MAX_INT;
                    }
                } else {
                    // Field difference too large to fit into int
                    throw new RuntimeException();
                }
            }
            // Do a binary search
            while ((max - min) > 1) {
                int t = min + (max - min)/2; // make sure intermediate values don't exceed FIELD_DIFF_MAX_INT
                setTimeInMillis(startMs);
                add(field, t);
                long ms = getTimeInMillis();
                if (ms == targetMs) {
                    return t;
                } else if (ms > targetMs) {
                    max = t;
                } else {
                    min = t;
                }
            }
        } else if (startMs > targetMs) {
            //Eclipse stated the following is "dead code"
            /*if (false) {
                // This works, and makes the code smaller, but costs
                // an extra object creation and an extra couple cycles
                // of calendar computation.
                setTimeInMillis(targetMs);
                min = -fieldDifference(new Date(startMs), field);
            }*/
            int max = -1;
            // Find a value that is too small
            for (;;) {
                setTimeInMillis(startMs);
                add(field, max);
                long ms = getTimeInMillis();
                if (ms == targetMs) {
                    return max;
                } else if (ms < targetMs) {
                    break;
                } else {
                    min = max;
                    max <<= 1;
                    if (max == 0) {
                        // Field difference too large to fit into int
                        throw new RuntimeException();
                    }
                }
            }
            // Do a binary search
            while ((min - max) > 1) {
                int t = min + (max - min)/2; // make sure intermediate values don't exceed FIELD_DIFF_MAX_INT
                setTimeInMillis(startMs);
                add(field, t);
                long ms = getTimeInMillis();
                if (ms == targetMs) {
                    return t;
                } else if (ms < targetMs) {
                    max = t;
                } else {
                    min = t;
                }
            }
        }
        // Set calendar to end point
        setTimeInMillis(startMs);
        add(field, min);
        return min;
    }

    /**
     * Sets the time zone with the given time zone value.
     * @param value the given time zone.
     * @stable ICU 2.0
     */
    public void setTimeZone(TimeZone value)
    {
        zone = value;
        /* Recompute the fields from the time using the new zone.  This also
         * works if isTimeSet is false (after a call to set()).  In that case
         * the time will be computed from the fields using the new zone, then
         * the fields will get recomputed from that.  Consider the sequence of
         * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST).
         * Is cal set to 1 o'clock EST or 1 o'clock PST?  Answer: PST.  More
         * generally, a call to setTimeZone() affects calls to set() BEFORE AND
         * AFTER it up to the next call to complete().
         */
        areFieldsSet = false;
    }

    /**
     * Returns the time zone.
     * @return the time zone object associated with this calendar.
     * @stable ICU 2.0
     */
    public TimeZone getTimeZone()
    {
        return zone;
    }

    /**
     * Specify whether or not date/time interpretation is to be lenient.  With
     * lenient interpretation, a date such as "February 942, 1996" will be
     * treated as being equivalent to the 941st day after February 1, 1996.
     * With strict interpretation, such dates will cause an exception to be
     * thrown.
     *
     * @see DateFormat#setLenient
     * @stable ICU 2.0
     */
    public void setLenient(boolean lenient)
    {
        this.lenient = lenient;
    }

    /**
     * Tell whether date/time interpretation is to be lenient.
     * @stable ICU 2.0
     */
    public boolean isLenient()
    {
        return lenient;
    }

    /**
     * {@icu}Sets the behavior for handling wall time repeating multiple times
     * at negative time zone offset transitions. For example, 1:30 AM on
     * November 6, 2011 in US Eastern time (America/New_York) occurs twice;
     * 1:30 AM EDT, then 1:30 AM EST one hour later. When <code>WALLTIME_FIRST</code>
     * is used, the wall time 1:30AM in this example will be interpreted as 1:30 AM EDT
     * (first occurrence). When <code>WALLTIME_LAST</code> is used, it will be
     * interpreted as 1:30 AM EST (last occurrence). The default value is
     * <code>WALLTIME_LAST</code>.
     *
     * @param option the behavior for handling repeating wall time, either
     * <code>WALLTIME_FIRST</code> or <code>WALLTIME_LAST</code>.
     * @throws IllegalArgumentException when <code>option</code> is neither
     * <code>WALLTIME_FIRST</code> nor <code>WALLTIME_LAST</code>.
     *
     * @see #getRepeatedWallTimeOption()
     * @see #WALLTIME_FIRST
     * @see #WALLTIME_LAST
     *
     * @stable ICU 49
     */
    public void setRepeatedWallTimeOption(int option) {
        if (option != WALLTIME_LAST && option != WALLTIME_FIRST) {
            throw new IllegalArgumentException("Illegal repeated wall time option - " + option);
        }
        repeatedWallTime = option;
    }

    /**
     * {@icu}Gets the behavior for handling wall time repeating multiple times
     * at negative time zone offset transitions.
     *
     * @return the behavior for handling repeating wall time, either
     * <code>WALLTIME_FIRST</code> or <code>WALLTIME_LAST</code>.
     *
     * @see #setRepeatedWallTimeOption(int)
     * @see #WALLTIME_FIRST
     * @see #WALLTIME_LAST
     *
     * @stable ICU 49
     */
    public int getRepeatedWallTimeOption() {
        return repeatedWallTime;
    }

    /**
     * {@icu}Sets the behavior for handling skipped wall time at positive time zone offset
     * transitions. For example, 2:30 AM on March 13, 2011 in US Eastern time (America/New_York)
     * does not exist because the wall time jump from 1:59 AM EST to 3:00 AM EDT. When
     * <code>WALLTIME_FIRST</code> is used, 2:30 AM is interpreted as 30 minutes before 3:00 AM
     * EDT, therefore, it will be resolved as 1:30 AM EST. When <code>WALLTIME_LAST</code>
     * is used, 2:30 AM is interpreted as 31 minutes after 1:59 AM EST, therefore, it will be
     * resolved as 3:30 AM EDT. When <code>WALLTIME_NEXT_VALID</code> is used, 2:30 AM will
     * be resolved as next valid wall time, that is 3:00 AM EDT. The default value is
     * <code>WALLTIME_LAST</code>.
     * <p>
     * <b>Note:</b>This option is effective only when this calendar is {@link #isLenient() lenient}.
     * When the calendar is strict, such non-existing wall time will cause an exception.
     *
     * @param option the behavior for handling skipped wall time at positive time zone
     * offset transitions, one of <code>WALLTIME_FIRST</code>, <code>WALLTIME_LAST</code> and
     * <code>WALLTIME_NEXT_VALID</code>.
     * @throws IllegalArgumentException when <code>option</code> is not any of
     * <code>WALLTIME_FIRST</code>, <code>WALLTIME_LAST</code> and <code>WALLTIME_NEXT_VALID</code>.
     *
     * @see #getSkippedWallTimeOption()
     * @see #WALLTIME_FIRST
     * @see #WALLTIME_LAST
     * @see #WALLTIME_NEXT_VALID
     *
     * @stable ICU 49
     */
    public void setSkippedWallTimeOption(int option) {
        if (option != WALLTIME_LAST && option != WALLTIME_FIRST && option != WALLTIME_NEXT_VALID) {
            throw new IllegalArgumentException("Illegal skipped wall time option - " + option);
        }
        skippedWallTime = option;
    }

    /**
     * {@icu}Gets the behavior for handling skipped wall time at positive time zone offset
     * transitions.
     *
     * @return the behavior for handling skipped wall time, one of
     * <code>WALLTIME_FIRST</code>, <code>WALLTIME_LAST</code> and <code>WALLTIME_NEXT_VALID</code>.
     *
     * @see #setSkippedWallTimeOption(int)
     * @see #WALLTIME_FIRST
     * @see #WALLTIME_LAST
     * @see #WALLTIME_NEXT_VALID
     *
     * @stable ICU 49
     */
    public int getSkippedWallTimeOption() {
        return skippedWallTime;
    }

    /**
     * Sets what the first day of the week is,
     * where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}.
     * @param value the given first day of the week, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}.
     * @stable ICU 2.0
     */
    public void setFirstDayOfWeek(int value)
    {
        if (firstDayOfWeek != value) {
            if (value < SUNDAY || value > SATURDAY) {
                throw new IllegalArgumentException("Invalid day of week");
            }
            firstDayOfWeek = value;
            areFieldsSet = false;
        }
    }

    /**
     * Returns what the first day of the week is,
     * where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}.
     * e.g., Sunday in US, Monday in France
     * @return the first day of the week, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}.
     * @stable ICU 2.0
     */
    public int getFirstDayOfWeek()
    {
        return firstDayOfWeek;
    }

    /**
     * Sets what the minimal days required in the first week of the year are.
     * For example, if the first week is defined as one that contains the first
     * day of the first month of a year, call the method with value 1. If it
     * must be a full week, use value 7.
     * @param value the given minimal days required in the first week
     * of the year.
     * @stable ICU 2.0
     */
    public void setMinimalDaysInFirstWeek(int value)
    {
        // Values less than 1 have the same effect as 1; values greater
        // than 7 have the same effect as 7. However, we normalize values
        // so operator== and so forth work.
        if (value < 1) {
            value = 1;
        } else if (value > 7) {
            value = 7;
        }
        if (minimalDaysInFirstWeek != value) {
            minimalDaysInFirstWeek = value;
            areFieldsSet = false;
        }
    }

    /**
     * Returns what the minimal days required in the first week of the year are.
     * That is, if the first week is defined as one that contains the first day
     * of the first month of a year, getMinimalDaysInFirstWeek returns 1. If
     * the minimal days required must be a full week, getMinimalDaysInFirstWeek
     * returns 7.
     * @return the minimal days required in the first week of the year.
     * @stable ICU 2.0
     */
    public int getMinimalDaysInFirstWeek()
    {
        return minimalDaysInFirstWeek;
    }

    private static final int LIMITS[][] = {
        //    Minimum  Greatest min      Least max   Greatest max
        {/*                                                      */}, // ERA
        {/*                                                      */}, // YEAR
        {/*                                                      */}, // MONTH
        {/*                                                      */}, // WEEK_OF_YEAR
        {/*                                                      */}, // WEEK_OF_MONTH
        {/*                                                      */}, // DAY_OF_MONTH
        {/*                                                      */}, // DAY_OF_YEAR
        {           1,            1,             7,             7  }, // DAY_OF_WEEK
        {/*                                                      */}, // DAY_OF_WEEK_IN_MONTH
        {           0,            0,             1,             1  }, // AM_PM
        {           0,            0,            11,            11  }, // HOUR
        {           0,            0,            23,            23  }, // HOUR_OF_DAY
        {           0,            0,            59,            59  }, // MINUTE
        {           0,            0,            59,            59  }, // SECOND
        {           0,            0,           999,           999  }, // MILLISECOND
        {-12*ONE_HOUR, -12*ONE_HOUR,   12*ONE_HOUR,   12*ONE_HOUR  }, // ZONE_OFFSET
        {           0,            0,    1*ONE_HOUR,    1*ONE_HOUR  }, // DST_OFFSET
        {/*                                                      */}, // YEAR_WOY
        {           1,            1,             7,             7  }, // DOW_LOCAL
        {/*                                                      */}, // EXTENDED_YEAR
        { -0x7F000000,  -0x7F000000,    0x7F000000,    0x7F000000  }, // JULIAN_DAY
        {           0,            0, 24*ONE_HOUR-1, 24*ONE_HOUR-1  }, // MILLISECONDS_IN_DAY
        {           0,            0,             1,             1  }, // IS_LEAP_MONTH
    };

    /**
     * Subclass API for defining limits of different types.
     * Subclasses must implement this method to return limits for the
     * following fields:
     *
     * <pre>ERA
     * YEAR
     * MONTH
     * WEEK_OF_YEAR
     * WEEK_OF_MONTH
     * DAY_OF_MONTH
     * DAY_OF_YEAR
     * DAY_OF_WEEK_IN_MONTH
     * YEAR_WOY
     * EXTENDED_YEAR</pre>
     *
     * @param field one of the above field numbers
     * @param limitType one of <code>MINIMUM</code>, <code>GREATEST_MINIMUM</code>,
     * <code>LEAST_MAXIMUM</code>, or <code>MAXIMUM</code>
     * @stable ICU 2.0
     */
    abstract protected int handleGetLimit(int field, int limitType);

    /**
     * Returns a limit for a field.
     * @param field the field, from 0..<code>getFieldCount()-1</code>
     * @param limitType the type specifier for the limit
     * @see #MINIMUM
     * @see #GREATEST_MINIMUM
     * @see #LEAST_MAXIMUM
     * @see #MAXIMUM
     * @stable ICU 2.0
     */
    protected int getLimit(int field, int limitType) {
        switch (field) {
        case DAY_OF_WEEK:
        case AM_PM:
        case HOUR:
        case HOUR_OF_DAY:
        case MINUTE:
        case SECOND:
        case MILLISECOND:
        case ZONE_OFFSET:
        case DST_OFFSET:
        case DOW_LOCAL:
        case JULIAN_DAY:
        case MILLISECONDS_IN_DAY:
        case IS_LEAP_MONTH:
            return LIMITS[field][limitType];

        case WEEK_OF_MONTH:
        {
            int limit;
            if (limitType == MINIMUM) {
                limit = getMinimalDaysInFirstWeek() == 1 ? 1 : 0;
            } else if (limitType == GREATEST_MINIMUM){
                limit = 1;
            } else {
                int minDaysInFirst = getMinimalDaysInFirstWeek();
                int daysInMonth = handleGetLimit(DAY_OF_MONTH, limitType);
                if (limitType == LEAST_MAXIMUM) {
                    limit = (daysInMonth + (7 - minDaysInFirst)) / 7;
                } else { // limitType == MAXIMUM
                    limit = (daysInMonth + 6 + (7 - minDaysInFirst)) / 7;
                }
            }
            return limit;
        }

        }
        return handleGetLimit(field, limitType);
    }

    /**
     * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code>
     * indicating the minimum value that a field can take (least minimum).
     * @see #getLimit
     * @see #handleGetLimit
     * @stable ICU 2.0
     */
    protected static final int MINIMUM = 0;

    /**
     * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code>
     * indicating the greatest minimum value that a field can take.
     * @see #getLimit
     * @see #handleGetLimit
     * @stable ICU 2.0
     */
    protected static final int GREATEST_MINIMUM = 1;

    /**
     * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code>
     * indicating the least maximum value that a field can take.
     * @see #getLimit
     * @see #handleGetLimit
     * @stable ICU 2.0
     */
    protected static final int LEAST_MAXIMUM = 2;

    /**
     * Limit type for <code>getLimit()</code> and <code>handleGetLimit()</code>
     * indicating the maximum value that a field can take (greatest maximum).
     * @see #getLimit
     * @see #handleGetLimit
     * @stable ICU 2.0
     */
    protected static final int MAXIMUM = 3;

    /**
     * Returns the minimum value for the given time field.
     * e.g., for Gregorian DAY_OF_MONTH, 1.
     * @param field the given time field.
     * @return the minimum value for the given time field.
     * @stable ICU 2.0
     */
    public final int getMinimum(int field) {
        return getLimit(field, MINIMUM);
    }

    /**
     * Returns the maximum value for the given time field.
     * e.g. for Gregorian DAY_OF_MONTH, 31.
     * @param field the given time field.
     * @return the maximum value for the given time field.
     * @stable ICU 2.0
     */
    public final int getMaximum(int field) {
        return getLimit(field, MAXIMUM);
    }

    /**
     * Returns the highest minimum value for the given field if varies.
     * Otherwise same as getMinimum(). For Gregorian, no difference.
     * @param field the given time field.
     * @return the highest minimum value for the given time field.
     * @stable ICU 2.0
     */
    public final int getGreatestMinimum(int field) {
        return getLimit(field, GREATEST_MINIMUM);
    }

    /**
     * Returns the lowest maximum value for the given field if varies.
     * Otherwise same as getMaximum(). e.g., for Gregorian DAY_OF_MONTH, 28.
     * @param field the given time field.
     * @return the lowest maximum value for the given time field.
     * @stable ICU 2.0
     */
    public final int getLeastMaximum(int field) {
        return getLimit(field, LEAST_MAXIMUM);
    }

    //-------------------------------------------------------------------------
    // Weekend support -- determining which days of the week are the weekend
    // in a given locale
    //-------------------------------------------------------------------------

    /**
     * {@icu} Returns whether the given day of the week is a weekday, a
     * weekend day, or a day that transitions from one to the other, for the
     * locale and calendar system associated with this Calendar (the locale's
     * region is often the most determinant factor). If a transition occurs at
     * midnight, then the days before and after the transition will have the
     * type WEEKDAY or WEEKEND.  If a transition occurs at a time
     * other than midnight, then the day of the transition will have
     * the type WEEKEND_ONSET or WEEKEND_CEASE.  In this case, the
     * method getWeekendTransition() will return the point of
     * transition.
     * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
     * THURSDAY, FRIDAY, or SATURDAY
     * @return either WEEKDAY, WEEKEND, WEEKEND_ONSET, or
     * WEEKEND_CEASE
     * @exception IllegalArgumentException if dayOfWeek is not
     * between SUNDAY and SATURDAY, inclusive
     * @see #WEEKDAY
     * @see #WEEKEND
     * @see #WEEKEND_ONSET
     * @see #WEEKEND_CEASE
     * @see #getWeekendTransition
     * @see #isWeekend(Date)
     * @see #isWeekend()
     * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)}
     */
    @Deprecated
    public int getDayOfWeekType(int dayOfWeek) {
        if (dayOfWeek < SUNDAY || dayOfWeek > SATURDAY) {
            throw new IllegalArgumentException("Invalid day of week");
        }
        if (weekendOnset == weekendCease) {
            if (dayOfWeek != weekendOnset)
                return WEEKDAY;
            return (weekendOnsetMillis == 0) ? WEEKEND : WEEKEND_ONSET;
        }
        if (weekendOnset < weekendCease) {
            if (dayOfWeek < weekendOnset || dayOfWeek > weekendCease) {
                return WEEKDAY;
            }
        } else {
            if (dayOfWeek > weekendCease && dayOfWeek < weekendOnset) {
                return WEEKDAY;
            }
        }
        if (dayOfWeek == weekendOnset) {
            return (weekendOnsetMillis == 0) ? WEEKEND : WEEKEND_ONSET;
        }
        if (dayOfWeek == weekendCease) {
            return (weekendCeaseMillis >= 86400000) ? WEEKEND : WEEKEND_CEASE;
        }
        return WEEKEND;
    }

    /**
     * {@icu} Returns the time during the day at which the weekend begins or end in this
     * calendar system.  If getDayOfWeekType(dayOfWeek) == WEEKEND_ONSET return the time
     * at which the weekend begins.  If getDayOfWeekType(dayOfWeek) == WEEKEND_CEASE
     * return the time at which the weekend ends.  If getDayOfWeekType(dayOfWeek) has some
     * other value, then throw an exception.
     * @param dayOfWeek either SUNDAY, MONDAY, TUESDAY, WEDNESDAY,
     * THURSDAY, FRIDAY, or SATURDAY
     * @return the milliseconds after midnight at which the
     * weekend begins or ends
     * @exception IllegalArgumentException if dayOfWeek is not
     * WEEKEND_ONSET or WEEKEND_CEASE
     * @see #getDayOfWeekType
     * @see #isWeekend(Date)
     * @see #isWeekend()
     * @deprecated ICU 54 use {@link #getWeekDataForRegion(String)}, {@link #getWeekData()}, {@link #setWeekData(WeekData)}
     */
    @Deprecated
    public int getWeekendTransition(int dayOfWeek) {
        if (dayOfWeek == weekendOnset) {
            return weekendOnsetMillis;
        } else if (dayOfWeek == weekendCease) {
            return weekendCeaseMillis;
        }
        throw new IllegalArgumentException("Not weekend transition day");
    }

    /**
     * {@icu} Returns true if the given date and time is in the weekend in this calendar
     * system.  Equivalent to calling setTime() followed by isWeekend().  Note: This
     * method changes the time this calendar is set to.
     * @param date the date and time
     * @return true if the given date and time is part of the
     * weekend
     * @see #getDayOfWeekType
     * @see #getWeekendTransition
     * @see #isWeekend()
     * @stable ICU 2.0
     */
    public boolean isWeekend(Date date) {
        setTime(date);
        return isWeekend();
    }

    /**
     * {@icu} Returns true if this Calendar's current date and time is in the weekend in
     * this calendar system.
     * @return true if the given date and time is part of the
     * weekend
     * @see #getDayOfWeekType
     * @see #getWeekendTransition
     * @see #isWeekend(Date)
     * @stable ICU 2.0
     */
    public boolean isWeekend() {
        int dow =  get(DAY_OF_WEEK);
        int dowt = getDayOfWeekType(dow);
        switch (dowt) {
        case WEEKDAY:
            return false;
        case WEEKEND:
            return true;
        default: // That is, WEEKEND_ONSET or WEEKEND_CEASE
            // Use internalGet() because the above call to get() populated
            // all fields.
            // [Note: There should be a better way to get millis in day.
            //  For ICU4J, submit request for a MILLIS_IN_DAY field
            //  and a DAY_NUMBER field (could be Julian day #). - aliu]
            int millisInDay = internalGet(MILLISECOND) + 1000 * (internalGet(SECOND) +
                    60 * (internalGet(MINUTE) + 60 * internalGet(HOUR_OF_DAY)));
            int transition = getWeekendTransition(dow);
            return (dowt == WEEKEND_ONSET)
                    ? (millisInDay >= transition)
                            : (millisInDay <  transition);
        }
        // (We can never reach this point.)
    }

    //-------------------------------------------------------------------------
    // End of weekend support
    //-------------------------------------------------------------------------

    /**
     * Overrides Cloneable
     * @stable ICU 2.0
     */
    @Override
    public Object clone()
    {
        try {
            Calendar other = (Calendar) super.clone();

            other.fields = new int[fields.length];
            other.stamp = new int[fields.length];
            System.arraycopy(this.fields, 0, other.fields, 0, fields.length);
            System.arraycopy(this.stamp, 0, other.stamp, 0, fields.length);

            other.zone = (TimeZone) zone.clone();
            return other;
        }
        catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new ICUCloneNotSupportedException(e);
        }
    }

    /**
     * Returns a string representation of this calendar. This method
     * is intended to be used only for debugging purposes, and the
     * format of the returned string may vary between implementations.
     * The returned string may be empty but may not be <code>null</code>.
     *
     * @return  a string representation of this calendar.
     * @stable ICU 2.0
     */
    @Override
    public String toString() {
        StringBuilder buffer = new StringBuilder();
        buffer.append(getClass().getName());
        buffer.append("[time=");
        buffer.append(isTimeSet ? String.valueOf(time) : "?");
        buffer.append(",areFieldsSet=");
        buffer.append(areFieldsSet);
        buffer.append(",areAllFieldsSet=");
        buffer.append(areAllFieldsSet);
        buffer.append(",lenient=");
        buffer.append(lenient);
        buffer.append(",zone=");
        buffer.append(zone);
        buffer.append(",firstDayOfWeek=");
        buffer.append(firstDayOfWeek);
        buffer.append(",minimalDaysInFirstWeek=");
        buffer.append(minimalDaysInFirstWeek);
        buffer.append(",repeatedWallTime=");
        buffer.append(repeatedWallTime);
        buffer.append(",skippedWallTime=");
        buffer.append(skippedWallTime);
        for (int i=0; i<fields.length; ++i) {
            buffer.append(',').append(fieldName(i)).append('=');
            buffer.append(isSet(i) ? String.valueOf(fields[i]) : "?");
        }
        buffer.append(']');
        return buffer.toString();
    }

    /**
     * Simple, immutable struct-like class for access to the CLDR week data.
     *
     * @stable ICU 54
     */
    public static final class WeekData {
        /**
         * the first day of the week, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}
         *
         * @stable ICU 54
         */
        public final int firstDayOfWeek;
        /**
         * the minimal number of days in the first week
         *
         * @stable ICU 54
         */
        public final int minimalDaysInFirstWeek;
        /**
         * the onset day, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}
         *
         * @stable ICU 54
         */
        public final int weekendOnset;
        /**
         * the onset time in millis during the onset day
         *
         * @stable ICU 54
         */
        public final int weekendOnsetMillis;
        /**
         * the cease day, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}
         *
         * @stable ICU 54
         */
        public final int weekendCease;
        /**
         * the cease time in millis during the cease day. Exclusive, so the max is 24:00:00.000.
         * Note that this will format as 00:00 the next day.
         *
         * @stable ICU 54
         */
        public final int weekendCeaseMillis;

        /**
         * Constructor
         *
         * @param fdow the first day of the week, where 1 = {@link #SUNDAY} and 7 = {@link #SATURDAY}
         * @param mdifw the minimal number of days in the first week
         * @param weekendOnset the onset day, where 1 = Sunday and 7 = Saturday
         * @param weekendOnsetMillis the onset time in millis during the onset day
         * @param weekendCease the cease day, where 1 = Sunday and 7 = Saturday
         * @param weekendCeaseMillis the cease time in millis during the cease day.
         *
         * @stable ICU 54
         */
        public WeekData(int fdow, int mdifw,
                int weekendOnset, int weekendOnsetMillis,
                int weekendCease, int weekendCeaseMillis) {
            this.firstDayOfWeek = fdow;
            this.minimalDaysInFirstWeek = mdifw;
            this.weekendOnset = weekendOnset;
            this.weekendOnsetMillis = weekendOnsetMillis;
            this.weekendCease = weekendCease;
            this.weekendCeaseMillis = weekendCeaseMillis;
        }

        /**
         * {@inheritDoc}
         *
         * @stable ICU 54
         */
        @Override
        public int hashCode() {
            return ((((firstDayOfWeek * 37 + minimalDaysInFirstWeek) * 37 + weekendOnset) * 37
                    + weekendOnsetMillis) * 37 + weekendCease) * 37 + weekendCeaseMillis;
        }

        /**
         * {@inheritDoc}
         *
         * @stable ICU 54
         */
        @Override
        public boolean equals(Object other) {
            if (this == other) {
                return true;
            }
            if (!(other instanceof WeekData)) {
                return false;
            }
            WeekData that = (WeekData) other;
            return firstDayOfWeek == that.firstDayOfWeek
                    && minimalDaysInFirstWeek == that.minimalDaysInFirstWeek
                    && weekendOnset == that.weekendOnset
                    && weekendOnsetMillis == that.weekendOnsetMillis
                    && weekendCease == that.weekendCease
                    && weekendCeaseMillis == that.weekendCeaseMillis;
        }

        /**
         * {@inheritDoc}
         *
         * @stable ICU 54
         */
        @Override
        public String toString() {
            return "{" + firstDayOfWeek
                    + ", " + minimalDaysInFirstWeek
                    + ", " + weekendOnset
                    + ", " + weekendOnsetMillis
                    + ", " + weekendCease
                    + ", " + weekendCeaseMillis
                    + "}";
        }
    }

    /**
     * {@icu} Return simple, immutable struct-like class for access to the CLDR week data.
     * @param region The input region. The results are undefined if the region code is not valid.
     * @return the WeekData for the input region. It is never null.
     *
     * @stable ICU 54
     */
    public static WeekData getWeekDataForRegion(String region) {
        return WEEK_DATA_CACHE.createInstance(region, region);
    }

    /**
     * {@icu} Return simple, immutable struct-like class for access to the week data in this calendar.
     * @return the WeekData for this calendar.
     *
     * @stable ICU 54
     */
    public WeekData getWeekData() {
        return new WeekData(firstDayOfWeek, minimalDaysInFirstWeek, weekendOnset, weekendOnsetMillis, weekendCease, weekendCeaseMillis);
    }

    /**
     * {@icu} Set data in this calendar based on the WeekData input.
     * @param wdata The week data to use
     * @return this, for chaining
     *
     * @stable ICU 54
     */
    public Calendar setWeekData(WeekData wdata) {
        setFirstDayOfWeek(wdata.firstDayOfWeek);
        setMinimalDaysInFirstWeek(wdata.minimalDaysInFirstWeek);

        weekendOnset       = wdata.weekendOnset;
        weekendOnsetMillis = wdata.weekendOnsetMillis;
        weekendCease       = wdata.weekendCease;
        weekendCeaseMillis = wdata.weekendCeaseMillis;
        return this;
    }

    private static WeekData getWeekDataForRegionInternal(String region) {
        if (region == null) {
            region = "001";
        }

        UResourceBundle rb = UResourceBundle.getBundleInstance(
                ICUData.ICU_BASE_NAME,
                "supplementalData",
                ICUResourceBundle.ICU_DATA_CLASS_LOADER);
        UResourceBundle weekDataInfo = rb.get("weekData");
        UResourceBundle weekDataBundle = null;

        try {
            weekDataBundle = weekDataInfo.get(region);
        } catch (MissingResourceException mre) {
            if (!region.equals("001")) {
                // use "001" as fallback
                weekDataBundle = weekDataInfo.get("001");
            } else {
                throw mre;
            }
        }

        int[] wdi = weekDataBundle.getIntVector();
        return new WeekData(wdi[0],wdi[1],wdi[2],wdi[3],wdi[4],wdi[5]);
    }

    /*
     * Cache to hold week data by region
     */
    private static class WeekDataCache extends SoftCache<String, WeekData, String> {

        /* (non-Javadoc)
         * @see com.ibm.icu.impl.CacheBase#createInstance(java.lang.Object, java.lang.Object)
         */
        @Override
        protected WeekData createInstance(String key, String data) {
            return getWeekDataForRegionInternal(key);
        }
    }

    private static final WeekDataCache WEEK_DATA_CACHE = new WeekDataCache();

    /*
     * Set this calendar to contain week and week data for the given region.
     */
    private void setWeekData(String region) {
        if (region == null) {
            region = "001";
        }
        WeekData wdata = WEEK_DATA_CACHE.getInstance(region, region);
        setWeekData(wdata);
    }

    /**
     * Recompute the time and update the status fields isTimeSet
     * and areFieldsSet.  Callers should check isTimeSet and only
     * call this method if isTimeSet is false.
     */
    private void updateTime() {
        computeTime();
        // If we are lenient, we need to recompute the fields to normalize
        // the values.  Also, if we haven't set all the fields yet (i.e.,
        // in a newly-created object), we need to fill in the fields. [LIU]
        if (isLenient() || !areAllFieldsSet) areFieldsSet = false;
        isTimeSet = true;
        areFieldsVirtuallySet = false;
    }

    /**
     * Save the state of this object to a stream (i.e., serialize it).
     */
    private void writeObject(ObjectOutputStream stream)
            throws IOException
            {
        // Try to compute the time correctly, for the future (stream
        // version 2) in which we don't write out fields[] or isSet[].
        if (!isTimeSet) {
            try {
                updateTime();
            }
            catch (IllegalArgumentException e) {}
        }

        // Write out the 1.1 FCS object.
        stream.defaultWriteObject();
            }

    /**
     * Reconstitute this object from a stream (i.e., deserialize it).
     */
    private void readObject(ObjectInputStream stream)
            throws IOException, ClassNotFoundException {

        stream.defaultReadObject();

        initInternal();

        isTimeSet = true;
        areFieldsSet = areAllFieldsSet = false;
        areFieldsVirtuallySet = true; // cause fields to be recalculated if requested.
        nextStamp = MINIMUM_USER_STAMP;
    }


    //----------------------------------------------------------------------
    // Time -> Fields
    //----------------------------------------------------------------------

    /**
     * Converts the current millisecond time value <code>time</code> to
     * field values in <code>fields[]</code>.  This synchronizes the time
     * field values with a new time that is set for the calendar.  The time
     * is <em>not</em> recomputed first; to recompute the time, then the
     * fields, call the <code>complete</code> method.
     * @see #complete
     * @stable ICU 2.0
     */
    protected void computeFields() {
        int offsets[] = new int[2];
        getTimeZone().getOffset(time, false, offsets);
        long localMillis = time + offsets[0] + offsets[1];

        // Mark fields as set.  Do this before calling handleComputeFields().
        int mask = internalSetMask;
        for (int i=0; i<fields.length; ++i) {
            if ((mask & 1) == 0) {
                stamp[i] = INTERNALLY_SET;
            } else {
                stamp[i] = UNSET;
            }
            mask >>= 1;
        }

        // We used to check for and correct extreme millis values (near
        // Long.MIN_VALUE or Long.MAX_VALUE) here.  Such values would cause
        // overflows from positive to negative (or vice versa) and had to
        // be manually tweaked.  We no longer need to do this because we
        // have limited the range of supported dates to those that have a
        // Julian day that fits into an int.  This allows us to implement a
        // JULIAN_DAY field and also removes some inelegant code. - Liu
        // 11/6/00

        long days = floorDivide(localMillis, ONE_DAY);

        fields[JULIAN_DAY] = (int) days + EPOCH_JULIAN_DAY;

        computeGregorianAndDOWFields(fields[JULIAN_DAY]);

        // Call framework method to have subclass compute its fields.
        // These must include, at a minimum, MONTH, DAY_OF_MONTH,
        // EXTENDED_YEAR, YEAR, DAY_OF_YEAR.  This method will call internalSet(),
        // which will update stamp[].
        handleComputeFields(fields[JULIAN_DAY]);

        // Compute week-related fields, based on the subclass-computed
        // fields computed by handleComputeFields().
        computeWeekFields();

        // Compute time-related fields.  These are indepent of the date and
        // of the subclass algorithm.  They depend only on the local zone
        // wall milliseconds in day.
        int millisInDay = (int) (localMillis - (days * ONE_DAY));
        fields[MILLISECONDS_IN_DAY] = millisInDay;
        fields[MILLISECOND] = millisInDay % 1000;
        millisInDay /= 1000;
        fields[SECOND] = millisInDay % 60;
        millisInDay /= 60;
        fields[MINUTE] = millisInDay % 60;
        millisInDay /= 60;
        fields[HOUR_OF_DAY] = millisInDay;
        fields[AM_PM] = millisInDay / 12; // Assume AM == 0
        fields[HOUR] = millisInDay % 12;
        fields[ZONE_OFFSET] = offsets[0];
        fields[DST_OFFSET] = offsets[1];
    }

    /**
     * Compute the Gregorian calendar year, month, and day of month from
     * the given Julian day.  These values are not stored in fields, but in
     * member variables gregorianXxx.  Also compute the DAY_OF_WEEK and
     * DOW_LOCAL fields.
     */
    private final void computeGregorianAndDOWFields(int julianDay) {
        computeGregorianFields(julianDay);

        // Compute day of week: JD 0 = Monday
        int dow = fields[DAY_OF_WEEK] = julianDayToDayOfWeek(julianDay);

        // Calculate 1-based localized day of week
        int dowLocal = dow - getFirstDayOfWeek() + 1;
        if (dowLocal < 1) {
            dowLocal += 7;
        }
        fields[DOW_LOCAL] = dowLocal;
    }

    /**
     * Compute the Gregorian calendar year, month, and day of month from the
     * Julian day.  These values are not stored in fields, but in member
     * variables gregorianXxx.  They are used for time zone computations and by
     * subclasses that are Gregorian derivatives.  Subclasses may call this
     * method to perform a Gregorian calendar millis-&gt;fields computation.
     * To perform a Gregorian calendar fields-&gt;millis computation, call
     * computeGregorianMonthStart().
     * @see #computeGregorianMonthStart
     * @stable ICU 2.0
     */
    protected final void computeGregorianFields(int julianDay) {
        int year, month, dayOfMonth, dayOfYear;

        // The Gregorian epoch day is zero for Monday January 1, year 1.
        long gregorianEpochDay = julianDay - JAN_1_1_JULIAN_DAY;

        // Here we convert from the day number to the multiple radix
        // representation.  We use 400-year, 100-year, and 4-year cycles.
        // For example, the 4-year cycle has 4 years + 1 leap day; giving
        // 1461 == 365*4 + 1 days.
        int[] rem = new int[1];
        int n400 = floorDivide(gregorianEpochDay, 146097, rem); // 400-year cycle length
        int n100 = floorDivide(rem[0], 36524, rem); // 100-year cycle length
        int n4 = floorDivide(rem[0], 1461, rem); // 4-year cycle length
        int n1 = floorDivide(rem[0], 365, rem);
        year = 400*n400 + 100*n100 + 4*n4 + n1;
        dayOfYear = rem[0]; // zero-based day of year
        if (n100 == 4 || n1 == 4) {
            dayOfYear = 365; // Dec 31 at end of 4- or 400-yr cycle
        } else {
            ++year;
        }

        boolean isLeap = ((year&0x3) == 0) && // equiv. to (year%4 == 0)
                (year%100 != 0 || year%400 == 0);

        int correction = 0;
        int march1 = isLeap ? 60 : 59; // zero-based DOY for March 1
        if (dayOfYear >= march1) correction = isLeap ? 1 : 2;
        month = (12 * (dayOfYear + correction) + 6) / 367; // zero-based month
        dayOfMonth = dayOfYear -
                GREGORIAN_MONTH_COUNT[month][isLeap?3:2] + 1; // one-based DOM

        gregorianYear = year;
        gregorianMonth = month; // 0-based already
        gregorianDayOfMonth = dayOfMonth; // 1-based already
        gregorianDayOfYear = dayOfYear + 1; // Convert from 0-based to 1-based
    }

    /**
     * Compute the fields WEEK_OF_YEAR, YEAR_WOY, WEEK_OF_MONTH,
     * DAY_OF_WEEK_IN_MONTH, and DOW_LOCAL from EXTENDED_YEAR, YEAR,
     * DAY_OF_WEEK, and DAY_OF_YEAR.  The latter fields are computed by the
     * subclass based on the calendar system.
     *
     * <p>The YEAR_WOY field is computed simplistically.  It is equal to YEAR
     * most of the time, but at the year boundary it may be adjusted to YEAR-1
     * or YEAR+1 to reflect the overlap of a week into an adjacent year.  In
     * this case, a simple increment or decrement is performed on YEAR, even
     * though this may yield an invalid YEAR value.  For instance, if the YEAR
     * is part of a calendar system with an N-year cycle field CYCLE, then
     * incrementing the YEAR may involve incrementing CYCLE and setting YEAR
     * back to 0 or 1.  This is not handled by this code, and in fact cannot be
     * simply handled without having subclasses define an entire parallel set of
     * fields for fields larger than or equal to a year.  This additional
     * complexity is not warranted, since the intention of the YEAR_WOY field is
     * to support ISO 8601 notation, so it will typically be used with a
     * proleptic Gregorian calendar, which has no field larger than a year.
     */
    private final void computeWeekFields() {
        int eyear = fields[EXTENDED_YEAR];
        int dayOfWeek = fields[DAY_OF_WEEK];
        int dayOfYear = fields[DAY_OF_YEAR];

        // WEEK_OF_YEAR start
        // Compute the week of the year.  For the Gregorian calendar, valid week
        // numbers run from 1 to 52 or 53, depending on the year, the first day
        // of the week, and the minimal days in the first week.  For other
        // calendars, the valid range may be different -- it depends on the year
        // length.  Days at the start of the year may fall into the last week of
        // the previous year; days at the end of the year may fall into the
        // first week of the next year.  ASSUME that the year length is less than
        // 7000 days.
        int yearOfWeekOfYear = eyear;
        int relDow = (dayOfWeek + 7 - getFirstDayOfWeek()) % 7; // 0..6
        int relDowJan1 = (dayOfWeek - dayOfYear + 7001 - getFirstDayOfWeek()) % 7; // 0..6
        int woy = (dayOfYear - 1 + relDowJan1) / 7; // 0..53
        if ((7 - relDowJan1) >= getMinimalDaysInFirstWeek()) {
            ++woy;
        }

        // Adjust for weeks at the year end that overlap into the previous or
        // next calendar year.
        if (woy == 0) {
            // We are the last week of the previous year.
            // Check to see if we are in the last week; if so, we need
            // to handle the case in which we are the first week of the
            // next year.

            int prevDoy = dayOfYear + handleGetYearLength(eyear - 1);
            woy = weekNumber(prevDoy, dayOfWeek);
            yearOfWeekOfYear--;
        } else {
            int lastDoy = handleGetYearLength(eyear);
            // Fast check: For it to be week 1 of the next year, the DOY
            // must be on or after L-5, where L is yearLength(), then it
            // cannot possibly be week 1 of the next year:
            //          L-5                  L
            // doy: 359 360 361 362 363 364 365 001
            // dow:      1   2   3   4   5   6   7
            if (dayOfYear >= (lastDoy - 5)) {
                int lastRelDow = (relDow + lastDoy - dayOfYear) % 7;
                if (lastRelDow < 0) {
                    lastRelDow += 7;
                }
                if (((6 - lastRelDow) >= getMinimalDaysInFirstWeek()) &&
                        ((dayOfYear + 7 - relDow) > lastDoy)) {
                    woy = 1;
                    yearOfWeekOfYear++;
                }
            }
        }
        fields[WEEK_OF_YEAR] = woy;
        fields[YEAR_WOY] = yearOfWeekOfYear;
        // WEEK_OF_YEAR end

        int dayOfMonth = fields[DAY_OF_MONTH];
        fields[WEEK_OF_MONTH] = weekNumber(dayOfMonth, dayOfWeek);
        fields[DAY_OF_WEEK_IN_MONTH] = (dayOfMonth-1) / 7 + 1;
    }

    //----------------------------------------------------------------------
    // Fields -> Time
    //----------------------------------------------------------------------

    /**
     * Value to OR against resolve table field values for remapping.
     * @see #resolveFields
     * @stable ICU 2.0
     */
    protected static final int RESOLVE_REMAP = 32;
    // A power of 2 greater than or equal to MAX_FIELD_COUNT

    // Default table for day in year
    static final int[][][] DATE_PRECEDENCE = {
        {
            { DAY_OF_MONTH },
            { WEEK_OF_YEAR, DAY_OF_WEEK },
            { WEEK_OF_MONTH, DAY_OF_WEEK },
            { DAY_OF_WEEK_IN_MONTH, DAY_OF_WEEK },
            { WEEK_OF_YEAR, DOW_LOCAL },
            { WEEK_OF_MONTH, DOW_LOCAL },
            { DAY_OF_WEEK_IN_MONTH, DOW_LOCAL },
            { DAY_OF_YEAR },
            { RESOLVE_REMAP | DAY_OF_MONTH, YEAR },  // if YEAR is set over YEAR_WOY use DAY_OF_MONTH
            { RESOLVE_REMAP | WEEK_OF_YEAR, YEAR_WOY },  // if YEAR_WOY is set,  calc based on WEEK_OF_YEAR
        },
        {
            { WEEK_OF_YEAR },
            { WEEK_OF_MONTH },
            { DAY_OF_WEEK_IN_MONTH },
            { RESOLVE_REMAP | DAY_OF_WEEK_IN_MONTH, DAY_OF_WEEK },
            { RESOLVE_REMAP | DAY_OF_WEEK_IN_MONTH, DOW_LOCAL },
        },
    };

    static final int[][][] DOW_PRECEDENCE = {
        {
            { DAY_OF_WEEK },
            { DOW_LOCAL },
        },
    };

    /**
     * Given a precedence table, return the newest field combination in
     * the table, or -1 if none is found.
     *
     * <p>The precedence table is a 3-dimensional array of integers.  It
     * may be thought of as an array of groups.  Each group is an array of
     * lines.  Each line is an array of field numbers.  Within a line, if
     * all fields are set, then the time stamp of the line is taken to be
     * the stamp of the most recently set field.  If any field of a line is
     * unset, then the line fails to match.  Within a group, the line with
     * the newest time stamp is selected.  The first field of the line is
     * returned to indicate which line matched.
     *
     * <p>In some cases, it may be desirable to map a line to field that
     * whose stamp is NOT examined.  For example, if the best field is
     * DAY_OF_WEEK then the DAY_OF_WEEK_IN_MONTH algorithm may be used.  In
     * order to do this, insert the value <code>REMAP_RESOLVE | F</code> at
     * the start of the line, where <code>F</code> is the desired return
     * field value.  This field will NOT be examined; it only determines
     * the return value if the other fields in the line are the newest.
     *
     * <p>If all lines of a group contain at least one unset field, then no
     * line will match, and the group as a whole will fail to match.  In
     * that case, the next group will be processed.  If all groups fail to
     * match, then -1 is returned.
     * @stable ICU 2.0
     */
    protected int resolveFields(int[][][] precedenceTable) {
        int bestField = -1;
        int tempBestField;
        for (int g=0; g<precedenceTable.length && bestField < 0; ++g) {
            int[][] group = precedenceTable[g];
            int bestStamp = UNSET;
            linesInGroup:
                for (int l=0; l<group.length; ++l) {
                    int[] line= group[l];
                    int lineStamp = UNSET;
                    // Skip over first entry if it is negative
                    for (int i=(line[0]>=RESOLVE_REMAP)?1:0; i<line.length; ++i) {
                        int s = stamp[line[i]];
                        // If any field is unset then don't use this line
                        if (s == UNSET) {
                            continue linesInGroup;
                        } else {
                            lineStamp = Math.max(lineStamp, s);
                        }
                    }
                    // Record new maximum stamp & field no.
                    if (lineStamp > bestStamp) {
                        tempBestField = line[0]; // First field refers to entire line
                        if (tempBestField >= RESOLVE_REMAP) {
                            tempBestField &= (RESOLVE_REMAP-1);
                            // This check is needed to resolve some issues with UCAL_YEAR precedence mapping
                            if (tempBestField != DATE || (stamp[WEEK_OF_MONTH] < stamp[tempBestField])) {
                                bestField = tempBestField;
                            }
                        } else {
                            bestField = tempBestField;
                        }

                        if (bestField == tempBestField) {
                            bestStamp = lineStamp;
                        }
                    }
                }
        }
        return (bestField>=RESOLVE_REMAP)?(bestField&(RESOLVE_REMAP-1)):bestField;
    }

    /**
     * Returns the newest stamp of a given range of fields.
     * @stable ICU 2.0
     */
    protected int newestStamp(int first, int last, int bestStampSoFar) {
        int bestStamp = bestStampSoFar;
        for (int i=first; i<=last; ++i) {
            if (stamp[i] > bestStamp) {
                bestStamp = stamp[i];
            }
        }
        return bestStamp;
    }

    /**
     * Returns the timestamp of a field.
     * @stable ICU 2.0
     */
    protected final int getStamp(int field) {
        return stamp[field];
    }

    /**
     * Returns the field that is newer, either defaultField, or
     * alternateField.  If neither is newer or neither is set, return defaultField.
     * @stable ICU 2.0
     */
    protected int newerField(int defaultField, int alternateField) {
        if (stamp[alternateField] > stamp[defaultField]) {
            return alternateField;
        }
        return defaultField;
    }

    /**
     * Ensure that each field is within its valid range by calling {@link
     * #validateField(int)} on each field that has been set.  This method
     * should only be called if this calendar is not lenient.
     * @see #isLenient
     * @see #validateField(int)
     * @stable ICU 2.0
     */
    protected void validateFields() {
        for (int field = 0; field < fields.length; field++) {
            if (stamp[field] >= MINIMUM_USER_STAMP) {
                validateField(field);
            }
        }
    }

    /**
     * Validate a single field of this calendar.  Subclasses should
     * override this method to validate any calendar-specific fields.
     * Generic fields can be handled by
     * <code>Calendar.validateField()</code>.
     * @see #validateField(int, int, int)
     * @stable ICU 2.0
     */
    protected void validateField(int field) {
        int y;
        switch (field) {
        case DAY_OF_MONTH:
            y = handleGetExtendedYear();
            validateField(field, 1, handleGetMonthLength(y, internalGet(MONTH)));
            break;
        case DAY_OF_YEAR:
            y = handleGetExtendedYear();
            validateField(field, 1, handleGetYearLength(y));
            break;
        case DAY_OF_WEEK_IN_MONTH:
            if (internalGet(field) == 0) {
                throw new IllegalArgumentException("DAY_OF_WEEK_IN_MONTH cannot be zero");
            }
            validateField(field, getMinimum(field), getMaximum(field));
            break;
        default:
            validateField(field, getMinimum(field), getMaximum(field));
            break;
        }
    }

    /**
     * Validate a single field of this calendar given its minimum and
     * maximum allowed value.  If the field is out of range, throw a
     * descriptive <code>IllegalArgumentException</code>.  Subclasses may
     * use this method in their implementation of {@link
     * #validateField(int)}.
     * @stable ICU 2.0
     */
    protected final void validateField(int field, int min, int max) {
        int value = fields[field];
        if (value < min || value > max) {
            throw new IllegalArgumentException(fieldName(field) +
                    '=' + value + ", valid range=" +
                    min + ".." + max);
        }
    }

    /**
     * Converts the current field values in <code>fields[]</code> to the
     * millisecond time value <code>time</code>.
     * @stable ICU 2.0
     */
    protected void computeTime() {
        if (!isLenient()) {
            validateFields();
        }

        // Compute the Julian day
        int julianDay = computeJulianDay();

        long millis = julianDayToMillis(julianDay);

        long millisInDay;

        // We only use MILLISECONDS_IN_DAY if it has been set by the user.
        // This makes it possible for the caller to set the calendar to a
        // time and call clear(MONTH) to reset the MONTH to January.  This
        // is legacy behavior.  Without this, clear(MONTH) has no effect,
        // since the internally set JULIAN_DAY is used.
        if (stamp[MILLISECONDS_IN_DAY] >= MINIMUM_USER_STAMP &&
                newestStamp(AM_PM, MILLISECOND, UNSET) <= stamp[MILLISECONDS_IN_DAY]) {
            millisInDay = internalGet(MILLISECONDS_IN_DAY);
        } else {
            int hour = Math.abs(internalGet(HOUR_OF_DAY));
            hour = Math.max(hour, Math.abs(internalGet(HOUR)));
            // if hour field value is greater than 596, then the
            // milliseconds value exceeds integer range, hence
            // using a conservative estimate of 548, we invoke
            // the long return version of the compute millis method if
            // the hour value exceeds 548
            if (hour > MAX_HOURS) {
                millisInDay = computeMillisInDayLong();
            } else {
                millisInDay = computeMillisInDay();
            }
        }

        if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP ||
                stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) {
            time = millis + millisInDay - (internalGet(ZONE_OFFSET) + internalGet(DST_OFFSET));
        } else {
            // Compute the time zone offset and DST offset.  There are two potential
            // ambiguities here.  We'll assume a 2:00 am (wall time) switchover time
            // for discussion purposes here.
            //
            // 1. The positive offset change such as transition into DST.
            //    Here, a designated time of 2:00 am - 2:59 am does not actually exist.
            //    For this case, skippedWallTime option specifies the behavior.
            //    For example, 2:30 am is interpreted as;
            //      - WALLTIME_LAST(default): 3:30 am (DST) (interpreting 2:30 am as 31 minutes after 1:59 am (STD))
            //      - WALLTIME_FIRST: 1:30 am (STD) (interpreting 2:30 am as 30 minutes before 3:00 am (DST))
            //      - WALLTIME_NEXT_VALID: 3:00 am (DST) (next valid time after 2:30 am on a wall clock)
            // 2. The negative offset change such as transition out of DST.
            //    Here, a designated time of 1:00 am - 1:59 am can be in standard or DST.  Both are valid
            //    representations (the rep jumps from 1:59:59 DST to 1:00:00 Std).
            //    For this case, repeatedWallTime option specifies the behavior.
            //    For example, 1:30 am is interpreted as;
            //      - WALLTIME_LAST(default): 1:30 am (STD) - latter occurrence
            //      - WALLTIME_FIRST: 1:30 am (DST) - former occurrence
            //
            // In addition to above, when calendar is strict (not default), wall time falls into
            // the skipped time range will be processed as an error case.
            //
            // These special cases are mostly handled in #computeZoneOffset(long), except WALLTIME_NEXT_VALID
            // at positive offset change. The protected method computeZoneOffset(long) is exposed to Calendar
            // subclass implementations and marked as @stable. Strictly speaking, WALLTIME_NEXT_VALID
            // should be also handled in the same place, but we cannot change the code flow without deprecating
            // the protected method.
            //
            // We use the TimeZone object, unless the user has explicitly set the ZONE_OFFSET
            // or DST_OFFSET fields; then we use those fields.

            if (!lenient || skippedWallTime == WALLTIME_NEXT_VALID) {
                // When strict, invalidate a wall time falls into a skipped wall time range.
                // When lenient and skipped wall time option is WALLTIME_NEXT_VALID,
                // the result time will be adjusted to the next valid time (on wall clock).
                int zoneOffset = computeZoneOffset(millis, millisInDay);
                long tmpTime = millis + millisInDay - zoneOffset;

                int zoneOffset1 = zone.getOffset(tmpTime);

                // zoneOffset != zoneOffset1 only when the given wall time fall into
                // a skipped wall time range caused by positive zone offset transition.
                if (zoneOffset != zoneOffset1) {
                    if (!lenient) {
                        throw new IllegalArgumentException("The specified wall time does not exist due to time zone offset transition.");
                    }

                    assert skippedWallTime == WALLTIME_NEXT_VALID : skippedWallTime;
                    // Adjust time to the next valid wall clock time.
                    // At this point, tmpTime is on or after the zone offset transition causing
                    // the skipped time range.
                    Long immediatePrevTransition = getImmediatePreviousZoneTransition(tmpTime);
                    if (immediatePrevTransition == null) {
                        throw new RuntimeException("Could not locate a time zone transition before " + tmpTime);
                    }
                    time = immediatePrevTransition;
                } else {
                    time = tmpTime;
                }
            } else {
                time = millis + millisInDay - computeZoneOffset(millis, millisInDay);
            }
        }
    }

    /**
     * Find the previous zone transtion near the given time.
     *
     * @param base The base time, inclusive.
     * @return The time of the previous transition, or null if not found.
     */
    private Long getImmediatePreviousZoneTransition(long base) {
        Long transitionTime = null;

        if (zone instanceof BasicTimeZone) {
            TimeZoneTransition transition = ((BasicTimeZone) zone).getPreviousTransition(base, true);
            if (transition != null) {
                transitionTime = transition.getTime();
            }
        } else {
            // Usually, it is enough to check past one hour because such transition is most
            // likely +1 hour shift. However, there is an example jumped +24 hour in the tz database.
            transitionTime = getPreviousZoneTransitionTime(zone, base, 2 * 60 * 60 * 1000); // check last 2 hours
            if (transitionTime == null) {
                transitionTime = getPreviousZoneTransitionTime(zone, base, 30 * 60 * 60 * 1000); // try last 30 hours
            }
        }
        return transitionTime;
    }

    /**
     * Find the previous zone transition within the specified duration.
     * Note: This method is only used when TimeZone is NOT a BasicTimeZone.
     * @param tz The time zone.
     * @param base The base time, inclusive.
     * @param duration The range of time evaluated.
     * @return The time of the previous zone transition, or null if not available.
     */
    private static Long getPreviousZoneTransitionTime(TimeZone tz, long base, long duration) {
        assert duration > 0;

        long upper = base;
        long lower = base - duration - 1;
        int offsetU = tz.getOffset(upper);
        int offsetL = tz.getOffset(lower);
        if (offsetU == offsetL) {
            return null;
        }
        return findPreviousZoneTransitionTime(tz, offsetU, upper, lower);
    }

    /**
     * The time units used by {@link #findPreviousZoneTransitionTime(TimeZone, int, long, long)}
     * for optimizing transition time binary search.
     */
    private static final int[] FIND_ZONE_TRANSITION_TIME_UNITS = {
        60*60*1000, // 1 hour
        30*60*1000, // 30 minutes
        60*1000,    // 1 minute
        1000,       // 1 second
    };

    /**
     * Implementing binary search for zone transtion detection, used by {@link #getPreviousZoneTransitionTime(TimeZone, long, long)}
     * @param tz The time zone.
     * @param upperOffset The zone offset at <code>upper</code>
     * @param upper The upper bound, inclusive.
     * @param lower The lower bound, exclusive.
     * @return The time of the previous zone transition, or null if not available.
     */
    private static Long findPreviousZoneTransitionTime(TimeZone tz, int upperOffset, long upper, long lower) {
        boolean onUnitTime = false;
        long mid = 0;

        for (int unit : FIND_ZONE_TRANSITION_TIME_UNITS) {
            long lunits = lower/unit;
            long uunits = upper/unit;
            if (uunits > lunits) {
                mid = ((lunits + uunits + 1) >>> 1) * unit;
                onUnitTime = true;
                break;
            }
        }

        int midOffset;
        if (!onUnitTime) {
            mid = (upper + lower) >>> 1;
        }

        if (onUnitTime) {
            if (mid != upper) {
                midOffset  = tz.getOffset(mid);
                if (midOffset != upperOffset) {
                    return findPreviousZoneTransitionTime(tz, upperOffset, upper, mid);
                }
                upper = mid;
            }
            // check mid-1
            mid--;
        } else {
            mid = (upper + lower) >>> 1;
        }

        if (mid == lower) {
            return Long.valueOf(upper);
        }
        midOffset = tz.getOffset(mid);
        if (midOffset != upperOffset) {
            if (onUnitTime) {
                return Long.valueOf(upper);
            }
            return findPreviousZoneTransitionTime(tz, upperOffset, upper, mid);
        }
        return findPreviousZoneTransitionTime(tz, upperOffset, mid, lower);
    }

    /**
     * Compute the milliseconds in the day from the fields.  This is a
     * value from 0 to 23:59:59.999 inclusive, unless fields are out of
     * range, in which case it can be an arbitrary value.  This value
     * reflects local zone wall time.
     * @deprecated ICU 60
     */
    @Deprecated
    protected int computeMillisInDay() {
        // Do the time portion of the conversion.

        int millisInDay = 0;

        // Find the best set of fields specifying the time of day.  There
        // are only two possibilities here; the HOUR_OF_DAY or the
        // AM_PM and the HOUR.
        int hourOfDayStamp = stamp[HOUR_OF_DAY];
        int hourStamp = Math.max(stamp[HOUR], stamp[AM_PM]);
        int bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp : hourOfDayStamp;

        // Hours
        if (bestStamp != UNSET) {
            if (bestStamp == hourOfDayStamp) {
                // Don't normalize here; let overflow bump into the next period.
                // This is consistent with how we handle other fields.
                millisInDay += internalGet(HOUR_OF_DAY);
            } else {
                // Don't normalize here; let overflow bump into the next period.
                // This is consistent with how we handle other fields.
                millisInDay += internalGet(HOUR);
                millisInDay += 12 * internalGet(AM_PM); // Default works for unset AM_PM
            }
        }

        // We use the fact that unset == 0; we start with millisInDay
        // == HOUR_OF_DAY.
        millisInDay *= 60;
        millisInDay += internalGet(MINUTE); // now have minutes
        millisInDay *= 60;
        millisInDay += internalGet(SECOND); // now have seconds
        millisInDay *= 1000;
        millisInDay += internalGet(MILLISECOND); // now have millis

        return millisInDay;
    }

    /**
     * Compute the milliseconds in the day from the fields.  The standard
     * value range is from 0 to 23:59:59.999 inclusive. This value
     * reflects local zone wall time.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected long computeMillisInDayLong() {
        // Do the time portion of the conversion.

        long millisInDay = 0;

        // Find the best set of fields specifying the time of day.  There
        // are only two possibilities here; the HOUR_OF_DAY or the
        // AM_PM and the HOUR.
        int hourOfDayStamp = stamp[HOUR_OF_DAY];
        int hourStamp = Math.max(stamp[HOUR], stamp[AM_PM]);
        int bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp : hourOfDayStamp;

        // Hours
        if (bestStamp != UNSET) {
            if (bestStamp == hourOfDayStamp) {
                // Don't normalize here; let overflow bump into the next period.
                // This is consistent with how we handle other fields.
                millisInDay += internalGet(HOUR_OF_DAY);
            } else {
                // Don't normalize here; let overflow bump into the next period.
                // This is consistent with how we handle other fields.
                millisInDay += internalGet(HOUR);
                millisInDay += 12 * internalGet(AM_PM); // Default works for unset AM_PM
            }
        }

        // We use the fact that unset == 0; we start with millisInDay
        // == HOUR_OF_DAY.
        millisInDay *= 60;
        millisInDay += internalGet(MINUTE); // now have minutes
        millisInDay *= 60;
        millisInDay += internalGet(SECOND); // now have seconds
        millisInDay *= 1000;
        millisInDay += internalGet(MILLISECOND); // now have millis

        return millisInDay;
    }


    /**
     * This method can assume EXTENDED_YEAR has been set.
     * @param millis milliseconds of the date fields (local midnight millis)
     * @param millisInDay milliseconds of the time fields; may be out
     * or range.
     * @return total zone offset (raw + DST) for the given moment
     * @deprecated ICU 60
     */
    @Deprecated
    protected int computeZoneOffset(long millis, int millisInDay) {
        int[] offsets = new int[2];
        long wall = millis + millisInDay;
        if (zone instanceof BasicTimeZone) {
            int duplicatedTimeOpt = (repeatedWallTime == WALLTIME_FIRST) ? BasicTimeZone.LOCAL_FORMER : BasicTimeZone.LOCAL_LATTER;
            int nonExistingTimeOpt = (skippedWallTime == WALLTIME_FIRST) ? BasicTimeZone.LOCAL_LATTER : BasicTimeZone.LOCAL_FORMER;
            ((BasicTimeZone)zone).getOffsetFromLocal(wall, nonExistingTimeOpt, duplicatedTimeOpt, offsets);
        } else {
            // By default, TimeZone#getOffset behaves WALLTIME_LAST for both.
            zone.getOffset(wall, true, offsets);

            boolean sawRecentNegativeShift = false;
            if (repeatedWallTime == WALLTIME_FIRST) {
                // Check if the given wall time falls into repeated time range
                long tgmt = wall - (offsets[0] + offsets[1]);

                // Any negative zone transition within last 6 hours?
                // Note: The maximum historic negative zone transition is -3 hours in the tz database.
                // 6 hour window would be sufficient for this purpose.
                int offsetBefore6 = zone.getOffset(tgmt - 6*60*60*1000);
                int offsetDelta = (offsets[0] + offsets[1]) - offsetBefore6;

                assert offsetDelta > -6*60*60*1000 : offsetDelta;
                if (offsetDelta < 0) {
                    sawRecentNegativeShift = true;
                    // Negative shift within last 6 hours. When WALLTIME_FIRST is used and the given wall time falls
                    // into the repeated time range, use offsets before the transition.
                    // Note: If it does not fall into the repeated time range, offsets remain unchanged below.
                    zone.getOffset(wall + offsetDelta, true, offsets);
                }
            }
            if (!sawRecentNegativeShift && skippedWallTime == WALLTIME_FIRST) {
                // When skipped wall time option is WALLTIME_FIRST,
                // recalculate offsets from the resolved time (non-wall).
                // When the given wall time falls into skipped wall time,
                // the offsets will be based on the zone offsets AFTER
                // the transition (which means, earliest possibe interpretation).
                long tgmt = wall - (offsets[0] + offsets[1]);
                zone.getOffset(tgmt, false, offsets);
            }
        }
        return offsets[0] + offsets[1];
    }

    /**
     * This method can assume EXTENDED_YEAR has been set.
     * @param millis milliseconds of the date fields (local midnight millis)
     * @param millisInDay milliseconds of the time fields
     * @return total zone offset (raw + DST) for the given moment
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    protected int computeZoneOffset(long millis, long millisInDay) {
        int[] offsets = new int[2];
        long wall = millis + millisInDay;
        if (zone instanceof BasicTimeZone) {
            int duplicatedTimeOpt = (repeatedWallTime == WALLTIME_FIRST) ? BasicTimeZone.LOCAL_FORMER : BasicTimeZone.LOCAL_LATTER;
            int nonExistingTimeOpt = (skippedWallTime == WALLTIME_FIRST) ? BasicTimeZone.LOCAL_LATTER : BasicTimeZone.LOCAL_FORMER;
            ((BasicTimeZone)zone).getOffsetFromLocal(wall, nonExistingTimeOpt, duplicatedTimeOpt, offsets);
        } else {
            // By default, TimeZone#getOffset behaves WALLTIME_LAST for both.
            zone.getOffset(wall, true, offsets);

            boolean sawRecentNegativeShift = false;
            if (repeatedWallTime == WALLTIME_FIRST) {
                // Check if the given wall time falls into repeated time range
                long tgmt = wall - (offsets[0] + offsets[1]);

                // Any negative zone transition within last 6 hours?
                // Note: The maximum historic negative zone transition is -3 hours in the tz database.
                // 6 hour window would be sufficient for this purpose.
                int offsetBefore6 = zone.getOffset(tgmt - 6*60*60*1000);
                int offsetDelta = (offsets[0] + offsets[1]) - offsetBefore6;

                assert offsetDelta > -6*60*60*1000 : offsetDelta;
                if (offsetDelta < 0) {
                    sawRecentNegativeShift = true;
                    // Negative shift within last 6 hours. When WALLTIME_FIRST is used and the given wall time falls
                    // into the repeated time range, use offsets before the transition.
                    // Note: If it does not fall into the repeated time range, offsets remain unchanged below.
                    zone.getOffset(wall + offsetDelta, true, offsets);
                }
            }
            if (!sawRecentNegativeShift && skippedWallTime == WALLTIME_FIRST) {
                // When skipped wall time option is WALLTIME_FIRST,
                // recalculate offsets from the resolved time (non-wall).
                // When the given wall time falls into skipped wall time,
                // the offsets will be based on the zone offsets AFTER
                // the transition (which means, earliest possibe interpretation).
                long tgmt = wall - (offsets[0] + offsets[1]);
                zone.getOffset(tgmt, false, offsets);
            }
        }
        return offsets[0] + offsets[1];
    }

    /**
     * Compute the Julian day number as specified by this calendar's fields.
     * @stable ICU 2.0
     */
    protected int computeJulianDay() {

        // We want to see if any of the date fields is newer than the
        // JULIAN_DAY.  If not, then we use JULIAN_DAY.  If so, then we do
        // the normal resolution.  We only use JULIAN_DAY if it has been
        // set by the user.  This makes it possible for the caller to set
        // the calendar to a time and call clear(MONTH) to reset the MONTH
        // to January.  This is legacy behavior.  Without this,
        // clear(MONTH) has no effect, since the internally set JULIAN_DAY
        // is used.
        if (stamp[JULIAN_DAY] >= MINIMUM_USER_STAMP) {
            int bestStamp = newestStamp(ERA, DAY_OF_WEEK_IN_MONTH, UNSET);
            bestStamp = newestStamp(YEAR_WOY, EXTENDED_YEAR, bestStamp);
            if (bestStamp <= stamp[JULIAN_DAY]) {
                return internalGet(JULIAN_DAY);
            }
        }

        int bestField = resolveFields(getFieldResolutionTable());
        if (bestField < 0) {
            bestField = DAY_OF_MONTH;
        }

        return handleComputeJulianDay(bestField);
    }

    /**
     * Returns the field resolution array for this calendar.  Calendars that
     * define additional fields or change the semantics of existing fields
     * should override this method to adjust the field resolution semantics
     * accordingly.  Other subclasses should not override this method.
     * @see #resolveFields
     * @stable ICU 2.0
     */
    protected int[][][] getFieldResolutionTable() {
        return DATE_PRECEDENCE;
    }

    /**
     * Returns the Julian day number of day before the first day of the
     * given month in the given extended year.  Subclasses should override
     * this method to implement their calendar system.
     * @param eyear the extended year
     * @param month the zero-based month, or 0 if useMonth is false
     * @param useMonth if false, compute the day before the first day of
     * the given year, otherwise, compute the day before the first day of
     * the given month
     * @return the Julian day number of the day before the first
     * day of the given month and year
     * @stable ICU 2.0
     */
    abstract protected int handleComputeMonthStart(int eyear, int month,
            boolean useMonth);

    /**
     * Returns the extended year defined by the current fields.  This will
     * use the EXTENDED_YEAR field or the YEAR and supra-year fields (such
     * as ERA) specific to the calendar system, depending on which set of
     * fields is newer.
     * @return the extended year
     * @stable ICU 2.0
     */
    abstract protected int handleGetExtendedYear();

    // (The following method is not called because all existing subclasses
    // override it.  2003-06-11 ICU 2.6 Alan)
    ///CLOVER:OFF
    /**
     * Returns the number of days in the given month of the given extended
     * year of this calendar system.  Subclasses should override this
     * method if they can provide a more correct or more efficient
     * implementation than the default implementation in Calendar.
     * @stable ICU 2.0
     */
    protected int handleGetMonthLength(int extendedYear, int month) {
        return handleComputeMonthStart(extendedYear, month+1, true) -
                handleComputeMonthStart(extendedYear, month, true);
    }
    ///CLOVER:ON

    /**
     * Returns the number of days in the given extended year of this
     * calendar system.  Subclasses should override this method if they can
     * provide a more correct or more efficient implementation than the
     * default implementation in Calendar.
     * @stable ICU 2.0
     */
    protected int handleGetYearLength(int eyear) {
        return handleComputeMonthStart(eyear+1, 0, false) -
                handleComputeMonthStart(eyear, 0, false);
    }

    /**
     * Subclasses that use additional fields beyond those defined in
     * <code>Calendar</code> should override this method to return an
     * <code>int[]</code> array of the appropriate length.  The length
     * must be at least <code>BASE_FIELD_COUNT</code> and no more than
     * <code>MAX_FIELD_COUNT</code>.
     * @stable ICU 2.0
     */
    protected int[] handleCreateFields() {
        return new int[BASE_FIELD_COUNT];
    }

    /**
     * Subclasses may override this.
     * Called by handleComputeJulianDay.  Returns the default month (0-based) for the year,
     * taking year and era into account.  Defaults to 0 (JANUARY) for Gregorian.
     * @param extendedYear the extendedYear, as returned by handleGetExtendedYear
     * @return the default month
     * @draft ICU 3.6 (retain)
     * @provisional This API might change or be removed in a future release.
     * @see #MONTH
     */
    protected int getDefaultMonthInYear(int extendedYear) {
        return Calendar.JANUARY;
    }

    /**
     * Subclasses may override this.
     * Called by handleComputeJulianDay.  Returns the default day (1-based) for the month,
     * taking currently-set year and era into account.  Defaults to 1 for Gregorian.
     * @param extendedYear the extendedYear, as returned by handleGetExtendedYear
     * @param month the month, as returned by getDefaultMonthInYear
     * @return the default day of the month
     * @draft ICU 3.6 (retain)
     * @provisional This API might change or be removed in a future release.
     * @see #DAY_OF_MONTH
     */
    protected int getDefaultDayInMonth(int extendedYear, int month) {
        return 1;
    }


    /**
     * Subclasses may override this.  This method calls
     * handleGetMonthLength() to obtain the calendar-specific month
     * length.
     * @stable ICU 2.0
     */
    protected int handleComputeJulianDay(int bestField) {

        boolean useMonth = (bestField == DAY_OF_MONTH ||
                bestField == WEEK_OF_MONTH ||
                bestField == DAY_OF_WEEK_IN_MONTH);

        int year;

        if (bestField == WEEK_OF_YEAR && newerField(YEAR_WOY, YEAR) == YEAR_WOY) {
            // Nota Bene!  It is critical that YEAR_WOY be used as the year here, if it is
            // set.  Otherwise, when WOY is the best field, the year may be wrong at the
            // extreme limits of the year.  If YEAR_WOY is not set then it will fall back.
            // TODO: Should resolveField(YEAR_PRECEDENCE) be brought to bear?
            year = internalGet(YEAR_WOY);
        } else {
            year = handleGetExtendedYear();
        }

        internalSet(EXTENDED_YEAR, year);

        int month = useMonth ? internalGet(MONTH, getDefaultMonthInYear(year)) : 0;

        // Get the Julian day of the day BEFORE the start of this year.
        // If useMonth is true, get the day before the start of the month.
        int julianDay = handleComputeMonthStart(year, month, useMonth);

        if (bestField == DAY_OF_MONTH) {
            if(isSet(DAY_OF_MONTH)) {
                return julianDay + internalGet(DAY_OF_MONTH, getDefaultDayInMonth(year, month));
            } else {
                return julianDay + getDefaultDayInMonth(year, month);
            }
        }

        if (bestField == DAY_OF_YEAR) {
            return julianDay + internalGet(DAY_OF_YEAR);
        }

        int firstDOW = getFirstDayOfWeek(); // Localized fdw

        // At this point julianDay is the 0-based day BEFORE the first day of
        // January 1, year 1 of the given calendar.  If julianDay == 0, it
        // specifies (Jan. 1, 1) - 1, in whatever calendar we are using (Julian
        // or Gregorian).

        // At this point we need to process the WEEK_OF_MONTH or
        // WEEK_OF_YEAR, which are similar, or the DAY_OF_WEEK_IN_MONTH.
        // First, perform initial shared computations.  These locate the
        // first week of the period.

        // Get the 0-based localized DOW of day one of the month or year.
        // Valid range 0..6.
        int first = julianDayToDayOfWeek(julianDay + 1) - firstDOW;
        if (first < 0) {
            first += 7;
        }

        // Get zero-based localized DOW, valid range 0..6.  This is the DOW
        // we are looking for.
        int dowLocal = 0;
        switch (resolveFields(DOW_PRECEDENCE)) {
        case DAY_OF_WEEK:
            dowLocal = internalGet(DAY_OF_WEEK) - firstDOW;
            break;
        case DOW_LOCAL:
            dowLocal = internalGet(DOW_LOCAL) - 1;
            break;
        }
        dowLocal = dowLocal % 7;
        if (dowLocal < 0) {
            dowLocal += 7;
        }

        // Find the first target DOW (dowLocal) in the month or year.
        // Actually, it may be just before the first of the month or year.
        // It will be an integer from -5..7.
        int date = 1 - first + dowLocal;

        if (bestField == DAY_OF_WEEK_IN_MONTH) {

            // Adjust the target DOW to be in the month or year.
            if (date < 1) {
                date += 7;
            }

            // The only trickiness occurs if the day-of-week-in-month is
            // negative.
            int dim = internalGet(DAY_OF_WEEK_IN_MONTH, 1);
            if (dim >= 0) {
                date += 7*(dim - 1);

            } else {
                // Move date to the last of this day-of-week in this month,
                // then back up as needed.  If dim==-1, we don't back up at
                // all.  If dim==-2, we back up once, etc.  Don't back up
                // past the first of the given day-of-week in this month.
                // Note that we handle -2, -3, etc. correctly, even though
                // values < -1 are technically disallowed.
                int m = internalGet(MONTH, JANUARY);
                int monthLength = handleGetMonthLength(year, m);
                date += ((monthLength - date) / 7 + dim + 1) * 7;
            }
        } else {
            // assert(bestField == WEEK_OF_MONTH || bestField == WEEK_OF_YEAR)

            // Adjust for minimal days in first week
            if ((7 - first) < getMinimalDaysInFirstWeek()) {
                date += 7;
            }

            // Now adjust for the week number.
            date += 7 * (internalGet(bestField) - 1);
        }

        return julianDay + date;
    }

    /**
     * Compute the Julian day of a month of the Gregorian calendar.
     * Subclasses may call this method to perform a Gregorian calendar
     * fields-&gt;millis computation.  To perform a Gregorian calendar
     * millis-&gt;fields computation, call computeGregorianFields().
     * @param year extended Gregorian year
     * @param month zero-based Gregorian month
     * @return the Julian day number of the day before the first
     * day of the given month in the given extended year
     * @see #computeGregorianFields
     * @stable ICU 2.0
     */
    protected int computeGregorianMonthStart(int year, int month) {

        // If the month is out of range, adjust it into range, and
        // modify the extended year value accordingly.
        if (month < 0 || month > 11) {
            int[] rem = new int[1];
            year += floorDivide(month, 12, rem);
            month = rem[0];
        }

        boolean isLeap = (year%4 == 0) && ((year%100 != 0) || (year%400 == 0));
        int y = year - 1;
        // This computation is actually ... + (JAN_1_1_JULIAN_DAY - 3) + 2.
        // Add 2 because Gregorian calendar starts 2 days after Julian
        // calendar.
        int julianDay = 365*y + floorDivide(y, 4) - floorDivide(y, 100) +
                floorDivide(y, 400) + JAN_1_1_JULIAN_DAY - 1;

        // At this point julianDay indicates the day BEFORE the first day
        // of January 1, <eyear> of the Gregorian calendar.
        if (month != 0) {
            julianDay += GREGORIAN_MONTH_COUNT[month][isLeap?3:2];
        }

        return julianDay;
    }

    //----------------------------------------------------------------------
    // Subclass API
    // For subclasses to override
    //----------------------------------------------------------------------

    // (The following method is not called because all existing subclasses
    // override it.  2003-06-11 ICU 2.6 Alan)
    ///CLOVER:OFF
    /**
     * Subclasses may override this method to compute several fields
     * specific to each calendar system.  These are:
     *
     * <ul><li>ERA
     * <li>YEAR
     * <li>MONTH
     * <li>DAY_OF_MONTH
     * <li>DAY_OF_YEAR
     * <li>EXTENDED_YEAR</ul>
     *
     * Subclasses can refer to the DAY_OF_WEEK and DOW_LOCAL fields, which
     * will be set when this method is called.  Subclasses can also call
     * the getGregorianXxx() methods to obtain Gregorian calendar
     * equivalents for the given Julian day.
     *
     * <p>In addition, subclasses should compute any subclass-specific
     * fields, that is, fields from BASE_FIELD_COUNT to
     * getFieldCount() - 1.
     *
     * <p>The default implementation in <code>Calendar</code> implements
     * a pure proleptic Gregorian calendar.
     * @stable ICU 2.0
     */
    protected void handleComputeFields(int julianDay) {
        internalSet(MONTH, getGregorianMonth());
        internalSet(DAY_OF_MONTH, getGregorianDayOfMonth());
        internalSet(DAY_OF_YEAR, getGregorianDayOfYear());
        int eyear = getGregorianYear();
        internalSet(EXTENDED_YEAR, eyear);
        int era = GregorianCalendar.AD;
        if (eyear < 1) {
            era = GregorianCalendar.BC;
            eyear = 1 - eyear;
        }
        internalSet(ERA, era);
        internalSet(YEAR, eyear);
    }
    ///CLOVER:ON

    //----------------------------------------------------------------------
    // Subclass API
    // For subclasses to call
    //----------------------------------------------------------------------

    /**
     * Returns the extended year on the Gregorian calendar as computed by
     * <code>computeGregorianFields()</code>.
     * @see #computeGregorianFields
     * @stable ICU 2.0
     */
    protected final int getGregorianYear() {
        return gregorianYear;
    }

    /**
     * Returns the month (0-based) on the Gregorian calendar as computed by
     * <code>computeGregorianFields()</code>.
     * @see #computeGregorianFields
     * @stable ICU 2.0
     */
    protected final int getGregorianMonth() {
        return gregorianMonth;
    }

    /**
     * Returns the day of year (1-based) on the Gregorian calendar as
     * computed by <code>computeGregorianFields()</code>.
     * @see #computeGregorianFields
     * @stable ICU 2.0
     */
    protected final int getGregorianDayOfYear() {
        return gregorianDayOfYear;
    }

    /**
     * Returns the day of month (1-based) on the Gregorian calendar as
     * computed by <code>computeGregorianFields()</code>.
     * @see #computeGregorianFields
     * @stable ICU 2.0
     */
    protected final int getGregorianDayOfMonth() {
        return gregorianDayOfMonth;
    }

    /**
     * {@icu} Returns the number of fields defined by this calendar.  Valid field
     * arguments to <code>set()</code> and <code>get()</code> are
     * <code>0..getFieldCount()-1</code>.
     * @stable ICU 2.0
     */
    public final int getFieldCount() {
        return fields.length;
    }

    /**
     * Set a field to a value.  Subclasses should use this method when
     * computing fields.  It sets the time stamp in the
     * <code>stamp[]</code> array to <code>INTERNALLY_SET</code>.  If a
     * field that may not be set by subclasses is passed in, an
     * <code>IllegalArgumentException</code> is thrown.  This prevents
     * subclasses from modifying fields that are intended to be
     * calendar-system invariant.
     * @stable ICU 2.0
     */
    protected final void internalSet(int field, int value) {
        if (((1 << field) & internalSetMask) == 0) {
            throw new IllegalStateException("Subclass cannot set " +
                    fieldName(field));
        }
        fields[field] = value;
        stamp[field] = INTERNALLY_SET;
    }

    private static final int[][] GREGORIAN_MONTH_COUNT = {
        //len len2   st  st2
        {  31,  31,   0,   0 }, // Jan
        {  28,  29,  31,  31 }, // Feb
        {  31,  31,  59,  60 }, // Mar
        {  30,  30,  90,  91 }, // Apr
        {  31,  31, 120, 121 }, // May
        {  30,  30, 151, 152 }, // Jun
        {  31,  31, 181, 182 }, // Jul
        {  31,  31, 212, 213 }, // Aug
        {  30,  30, 243, 244 }, // Sep
        {  31,  31, 273, 274 }, // Oct
        {  30,  30, 304, 305 }, // Nov
        {  31,  31, 334, 335 }  // Dec
        // len  length of month
        // len2 length of month in a leap year
        // st   days in year before start of month
        // st2  days in year before month in leap year
    };

    /**
     * Determines if the given year is a leap year. Returns true if the
     * given year is a leap year.
     * @param year the given year.
     * @return true if the given year is a leap year; false otherwise.
     * @stable ICU 2.0
     */
    protected static final boolean isGregorianLeapYear(int year) {
        return (year%4 == 0) && ((year%100 != 0) || (year%400 == 0));
    }

    /**
     * Returns the length of a month of the Gregorian calendar.
     * @param y the extended year
     * @param m the 0-based month number
     * @return the number of days in the given month
     * @stable ICU 2.0
     */
    protected static final int gregorianMonthLength(int y, int m) {
        return GREGORIAN_MONTH_COUNT[m][isGregorianLeapYear(y)?1:0];
    }

    /**
     * Returns the length of a previous month of the Gregorian calendar.
     * @param y the extended year
     * @param m the 0-based month number
     * @return the number of days in the month previous to the given month
     * @stable ICU 2.0
     */
    protected static final int gregorianPreviousMonthLength(int y, int m) {
        return (m > 0) ? gregorianMonthLength(y, m-1) : 31;
    }

    /**
     * Divide two long integers, returning the floor of the quotient.
     * <p>
     * Unlike the built-in division, this is mathematically well-behaved.
     * E.g., <code>-1/4</code> =&gt; 0
     * but <code>floorDivide(-1,4)</code> =&gt; -1.
     * @param numerator the numerator
     * @param denominator a divisor which must be &gt; 0
     * @return the floor of the quotient.
     * @stable ICU 2.0
     */
    protected static final long floorDivide(long numerator, long denominator) {
        // We do this computation in order to handle
        // a numerator of Long.MIN_VALUE correctly
        return (numerator >= 0) ?
                numerator / denominator :
                    ((numerator + 1) / denominator) - 1;
    }

    /**
     * Divide two integers, returning the floor of the quotient.
     * <p>
     * Unlike the built-in division, this is mathematically well-behaved.
     * E.g., <code>-1/4</code> =&gt; 0
     * but <code>floorDivide(-1,4)</code> =&gt; -1.
     * @param numerator the numerator
     * @param denominator a divisor which must be &gt; 0
     * @return the floor of the quotient.
     * @stable ICU 2.0
     */
    protected static final int floorDivide(int numerator, int denominator) {
        // We do this computation in order to handle
        // a numerator of Integer.MIN_VALUE correctly
        return (numerator >= 0) ?
                numerator / denominator :
                    ((numerator + 1) / denominator) - 1;
    }

    /**
     * Divide two integers, returning the floor of the quotient, and
     * the modulus remainder.
     * <p>
     * Unlike the built-in division, this is mathematically well-behaved.
     * E.g., <code>-1/4</code> =&gt; 0 and <code>-1%4</code> =&gt; -1,
     * but <code>floorDivide(-1,4)</code> =&gt; -1 with <code>remainder[0]</code> =&gt; 3.
     * @param numerator the numerator
     * @param denominator a divisor which must be &gt; 0
     * @param remainder an array of at least one element in which the value
     * <code>numerator mod denominator</code> is returned. Unlike <code>numerator
     * % denominator</code>, this will always be non-negative.
     * @return the floor of the quotient.
     * @stable ICU 2.0
     */
    protected static final int floorDivide(int numerator, int denominator, int[] remainder) {
        if (numerator >= 0) {
            remainder[0] = numerator % denominator;
            return numerator / denominator;
        }
        int quotient = ((numerator + 1) / denominator) - 1;
        remainder[0] = numerator - (quotient * denominator);
        return quotient;
    }

    /**
     * Divide two integers, returning the floor of the quotient, and
     * the modulus remainder.
     * <p>
     * Unlike the built-in division, this is mathematically well-behaved.
     * E.g., <code>-1/4</code> =&gt; 0 and <code>-1%4</code> =&gt; -1,
     * but <code>floorDivide(-1,4)</code> =&gt; -1 with <code>remainder[0]</code> =&gt; 3.
     * @param numerator the numerator
     * @param denominator a divisor which must be &gt; 0
     * @param remainder an array of at least one element in which the value
     * <code>numerator mod denominator</code> is returned. Unlike <code>numerator
     * % denominator</code>, this will always be non-negative.
     * @return the floor of the quotient.
     * @stable ICU 2.0
     */
    protected static final int floorDivide(long numerator, int denominator, int[] remainder) {
        if (numerator >= 0) {
            remainder[0] = (int)(numerator % denominator);
            return (int)(numerator / denominator);
        }
        int quotient = (int)(((numerator + 1) / denominator) - 1);
        remainder[0] = (int)(numerator - ((long)quotient * denominator));
        return quotient;
    }

    private static final String[] FIELD_NAME = {
        "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH",
        "DAY_OF_MONTH", "DAY_OF_YEAR", "DAY_OF_WEEK",
        "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", "HOUR_OF_DAY",
        "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET",
        "DST_OFFSET", "YEAR_WOY", "DOW_LOCAL", "EXTENDED_YEAR",
        "JULIAN_DAY", "MILLISECONDS_IN_DAY",
    };

    /**
     * Returns a string name for a field, for debugging and exceptions.
     * @stable ICU 2.0
     */
    protected String fieldName(int field) {
        try {
            return FIELD_NAME[field];
        } catch (ArrayIndexOutOfBoundsException e) {
            return "Field " + field;
        }
    }

    /**
     * Converts time as milliseconds to Julian day.
     * @param millis the given milliseconds.
     * @return the Julian day number.
     * @stable ICU 2.0
     */
    protected static final int millisToJulianDay(long millis) {
        return (int) (EPOCH_JULIAN_DAY + floorDivide(millis, ONE_DAY));
    }

    /**
     * Converts Julian day to time as milliseconds.
     * @param julian the given Julian day number.
     * @return time as milliseconds.
     * @stable ICU 2.0
     */
    protected static final long julianDayToMillis(int julian) {
        return (julian - EPOCH_JULIAN_DAY) * ONE_DAY;
    }

    /**
     * Returns the day of week, from SUNDAY to SATURDAY, given a Julian day.
     * @stable ICU 2.0
     */
    protected static final int julianDayToDayOfWeek(int julian) {
        // If julian is negative, then julian%7 will be negative, so we adjust
        // accordingly.  Julian day 0 is Monday.
        int dayOfWeek = (julian + MONDAY) % 7;
        if (dayOfWeek < SUNDAY) {
            dayOfWeek += 7;
        }
        return dayOfWeek;
    }

    /**
     * Returns the current milliseconds without recomputing.
     * @stable ICU 2.0
     */
    protected final long internalGetTimeInMillis() {
        return time;
    }

    /**
     * {@icu} Returns the calendar type name string for this Calendar object.
     * The returned string is the legacy ICU calendar attribute value,
     * for example, "gregorian" or "japanese".
     *
     * <p>See type="old type name" for the calendar attribute of locale IDs
     * at http://www.unicode.org/reports/tr35/#Key_Type_Definitions
     *
     * @return legacy calendar type name string
     * @stable ICU 3.8
     */
    public String getType() {
        return "unknown";
    }

    /**
     * Returns if two digit representation of year in this calendar type
     * customarily implies a default century (i.e. 03 -&gt; 2003).
     * The default implementation returns <code>true</code>. A subclass may
     * return <code>false</code> if such practice is not applicable (for example,
     * Chinese calendar and Japanese calendar).
     *
     * @return <code>true</code> if this calendar has a default century.
     * @internal
     * @deprecated This API is ICU internal only.
     */
    @Deprecated
    public boolean haveDefaultCentury() {
        return true;
    }

    // -------- BEGIN ULocale boilerplate --------

    /**
     * {@icu} Returns the locale that was used to create this object, or null.
     * This may may differ from the locale requested at the time of
     * this object's creation.  For example, if an object is created
     * for locale <tt>en_US_CALIFORNIA</tt>, the actual data may be
     * drawn from <tt>en</tt> (the <i>actual</i> locale), and
     * <tt>en_US</tt> may be the most specific locale that exists (the
     * <i>valid</i> locale).
     *
     * <p>Note: This method will be implemented in ICU 3.0; ICU 2.8
     * contains a partial preview implementation.  The * <i>actual</i>
     * locale is returned correctly, but the <i>valid</i> locale is
     * not, in most cases.
     * @param type type of information requested, either {@link
     * com.ibm.icu.util.ULocale#VALID_LOCALE} or {@link
     * com.ibm.icu.util.ULocale#ACTUAL_LOCALE}.
     * @return the information specified by <i>type</i>, or null if
     * this object was not constructed from locale data.
     * @see com.ibm.icu.util.ULocale
     * @see com.ibm.icu.util.ULocale#VALID_LOCALE
     * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
     * @draft ICU 2.8 (retain)
     * @provisional This API might change or be removed in a future release.
     */
    public final ULocale getLocale(ULocale.Type type) {
        return type == ULocale.ACTUAL_LOCALE ?
                this.actualLocale : this.validLocale;
    }

    /**
     * Set information about the locales that were used to create this
     * object.  If the object was not constructed from locale data,
     * both arguments should be set to null.  Otherwise, neither
     * should be null.  The actual locale must be at the same level or
     * less specific than the valid locale.  This method is intended
     * for use by factories or other entities that create objects of
     * this class.
     * @param valid the most specific locale containing any resource
     * data, or null
     * @param actual the locale containing data used to construct this
     * object, or null
     * @see com.ibm.icu.util.ULocale
     * @see com.ibm.icu.util.ULocale#VALID_LOCALE
     * @see com.ibm.icu.util.ULocale#ACTUAL_LOCALE
     */
    final void setLocale(ULocale valid, ULocale actual) {
        // Change the following to an assertion later
        if ((valid == null) != (actual == null)) {
            ///CLOVER:OFF
            throw new IllegalArgumentException();
            ///CLOVER:ON
        }
        // Another check we could do is that the actual locale is at
        // the same level or less specific than the valid locale.
        this.validLocale = valid;
        this.actualLocale = actual;
    }

    /**
     * The most specific locale containing any resource data, or null.
     * @see com.ibm.icu.util.ULocale
     */
    private ULocale validLocale;

    /**
     * The locale containing data used to construct this object, or
     * null.
     * @see com.ibm.icu.util.ULocale
     */
    private ULocale actualLocale;

    // -------- END ULocale boilerplate --------
}
