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