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