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