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