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