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