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