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