| Calendar.java |
1 /*
2 * %W% %E%
3 *
4 * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
5 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6 */
7
8 /*
9 * (C) Copyright Taligent, Inc. 1996-1998 - All Rights Reserved
10 * (C) Copyright IBM Corp. 1996-1998 - All Rights Reserved
11 *
12 * The original version of this source code and documentation is copyrighted
13 * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
14 * materials are provided under terms of a License Agreement between Taligent
15 * and Sun. This technology is protected by multiple US and International
16 * patents. This notice and attribution to Taligent may not be removed.
17 * Taligent is a registered trademark of Taligent, Inc.
18 *
19 */
20
21 package java.util;
22
23 import java.io.IOException;
24 import java.io.ObjectInputStream;
25 import java.io.ObjectOutputStream;
26 import java.io.OptionalDataException;
27 import java.io.Serializable;
28 import java.security.AccessControlContext;
29 import java.security.AccessController;
30 import java.security.PermissionCollection;
31 import java.security.PrivilegedActionException;
32 import java.security.PrivilegedExceptionAction;
33 import java.security.ProtectionDomain;
34 import java.text.DateFormat;
35 import java.text.DateFormatSymbols;
36 import sun.util.BuddhistCalendar;
37 import sun.util.calendar.ZoneInfo;
38 import sun.util.resources.LocaleData;
39
40 /**
41 * The <code>Calendar</code> class is an abstract class that provides methods
42 * for converting between a specific instant in time and a set of {@link
43 * #fields calendar fields} such as <code>YEAR</code>, <code>MONTH</code>,
44 * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, and so on, and for
45 * manipulating the calendar fields, such as getting the date of the next
46 * week. An instant in time can be represented by a millisecond value that is
47 * an offset from the <a name="Epoch"><em>Epoch</em></a>, January 1, 1970
48 * 00:00:00.000 GMT (Gregorian).
49 *
50 * <p>The class also provides additional fields and methods for
51 * implementing a concrete calendar system outside the package. Those
52 * fields and methods are defined as <code>protected</code>.
53 *
54 * <p>
55 * Like other locale-sensitive classes, <code>Calendar</code> provides a
56 * class method, <code>getInstance</code>, for getting a generally useful
57 * object of this type. <code>Calendar</code>'s <code>getInstance</code> method
58 * returns a <code>Calendar</code> object whose
59 * calendar fields have been initialized with the current date and time:
60 * <blockquote>
61 * <pre>
62 * Calendar rightNow = Calendar.getInstance();
63 * </pre>
64 * </blockquote>
65 *
66 * <p>A <code>Calendar</code> object can produce all the calendar field values
67 * needed to implement the date-time formatting for a particular language and
68 * calendar style (for example, Japanese-Gregorian, Japanese-Traditional).
69 * <code>Calendar</code> defines the range of values returned by
70 * certain calendar fields, as well as their meaning. For example,
71 * the first month of the calendar system has value <code>MONTH ==
72 * JANUARY</code> for all calendars. Other values are defined by the
73 * concrete subclass, such as <code>ERA</code>. See individual field
74 * documentation and subclass documentation for details.
75 *
76 * <h4>Getting and Setting Calendar Field Values</h4>
77 *
78 * <p>The calendar field values can be set by calling the <code>set</code>
79 * methods. Any field values set in a <code>Calendar</code> will not be
80 * interpreted until it needs to calculate its time value (milliseconds from
81 * the Epoch) or values of the calendar fields. Calling the
82 * <code>get</code>, <code>getTimeInMillis</code>, <code>getTime</code>,
83 * <code>add</code> and <code>roll</code> involves such calculation.
84 *
85 * <h4>Leniency</h4>
86 *
87 * <p><code>Calendar</code> has two modes for interpreting the calendar
88 * fields, <em>lenient</em> and <em>non-lenient</em>. When a
89 * <code>Calendar</code> is in lenient mode, it accepts a wider range of
90 * calendar field values than it produces. When a <code>Calendar</code>
91 * recomputes calendar field values for return by <code>get()</code>, all of
92 * the calendar fields are normalized. For example, a lenient
93 * <code>GregorianCalendar</code> interprets <code>MONTH == JANUARY</code>,
94 * <code>DAY_OF_MONTH == 32</code> as February 1.
95
96 * <p>When a <code>Calendar</code> is in non-lenient mode, it throws an
97 * exception if there is any inconsistency in its calendar fields. For
98 * example, a <code>GregorianCalendar</code> always produces
99 * <code>DAY_OF_MONTH</code> values between 1 and the length of the month. A
100 * non-lenient <code>GregorianCalendar</code> throws an exception upon
101 * calculating its time or calendar field values if any out-of-range field
102 * value has been set.
103 *
104 * <h4>First Week</h4>
105 *
106 * <code>Calendar</code> defines a locale-specific seven day week using two
107 * parameters: the first day of the week and the minimal days in first week
108 * (from 1 to 7). These numbers are taken from the locale resource data when a
109 * <code>Calendar</code> is constructed. They may also be specified explicitly
110 * through the methods for setting their values.
111 *
112 * <p>When setting or getting the <code>WEEK_OF_MONTH</code> or
113 * <code>WEEK_OF_YEAR</code> fields, <code>Calendar</code> must determine the
114 * first week of the month or year as a reference point. The first week of a
115 * month or year is defined as the earliest seven day period beginning on
116 * <code>getFirstDayOfWeek()</code> and containing at least
117 * <code>getMinimalDaysInFirstWeek()</code> days of that month or year. Weeks
118 * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow
119 * it. Note that the normalized numbering returned by <code>get()</code> may be
120 * different. For example, a specific <code>Calendar</code> subclass may
121 * designate the week before week 1 of a year as week <code><i>n</i></code> of
122 * the previous year.
123 *
124 * <h4>Calendar Fields Resolution</h4>
125 *
126 * When computing a date and time from the calendar fields, there
127 * may be insufficient information for the computation (such as only
128 * year and month with no day of month), or there may be inconsistent
129 * information (such as Tuesday, July 15, 1996 (Gregorian) -- July 15,
130 * 1996 is actually a Monday). <code>Calendar</code> will resolve
131 * calendar field values to determine the date and time in the
132 * following way.
133 *
134 * <p>If there is any conflict in calendar field values,
135 * <code>Calendar</code> gives priorities to calendar fields that have been set
136 * more recently. The following are the default combinations of the
137 * calendar fields. The most recent combination, as determined by the
138 * most recently set single field, will be used.
139 *
140 * <p><a name="date_resolution">For the date fields</a>:
141 * <blockquote>
142 * <pre>
143 * YEAR + MONTH + DAY_OF_MONTH
144 * YEAR + MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
145 * YEAR + MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
146 * YEAR + DAY_OF_YEAR
147 * YEAR + DAY_OF_WEEK + WEEK_OF_YEAR
148 * </pre></blockquote>
149 *
150 * <a name="time_resolution">For the time of day fields</a>:
151 * <blockquote>
152 * <pre>
153 * HOUR_OF_DAY
154 * AM_PM + HOUR
155 * </pre></blockquote>
156 *
157 * <p>If there are any calendar fields whose values haven't been set in the selected
158 * field combination, <code>Calendar</code> uses their default values. The default
159 * value of each field may vary by concrete calendar systems. For example, in
160 * <code>GregorianCalendar</code>, the default of a field is the same as that
161 * of the start of the Epoch: i.e., <code>YEAR = 1970</code>, <code>MONTH =
162 * JANUARY</code>, <code>DAY_OF_MONTH = 1</code>, etc.
163 *
164 * <p>
165 * <strong>Note:</strong> There are certain possible ambiguities in
166 * interpretation of certain singular times, which are resolved in the
167 * following ways:
168 * <ol>
169 * <li> 23:59 is the last minute of the day and 00:00 is the first
170 * minute of the next day. Thus, 23:59 on Dec 31, 1999 < 00:00 on
171 * Jan 1, 2000 < 00:01 on Jan 1, 2000.
172 *
173 * <li> Although historically not precise, midnight also belongs to "am",
174 * and noon belongs to "pm", so on the same day,
175 * 12:00 am (midnight) < 12:01 am, and 12:00 pm (noon) < 12:01 pm
176 * </ol>
177 *
178 * <p>
179 * The date or time format strings are not part of the definition of a
180 * calendar, as those must be modifiable or overridable by the user at
181 * runtime. Use {@link DateFormat}
182 * to format dates.
183 *
184 * <h4>Field Manipulation</h4>
185 *
186 * The calendar fields can be changed using three methods:
187 * <code>set()</code>, <code>add()</code>, and <code>roll()</code>.</p>
188 *
189 * <p><strong><code>set(f, value)</code></strong> changes calendar field
190 * <code>f</code> to <code>value</code>. In addition, it sets an
191 * internal member variable to indicate that calendar field <code>f</code> has
192 * been changed. Although calendar field <code>f</code> is changed immediately,
193 * the calendar's time value in milliseconds is not recomputed until the next call to
194 * <code>get()</code>, <code>getTime()</code>, <code>getTimeInMillis()</code>,
195 * <code>add()</code>, or <code>roll()</code> is made. Thus, multiple calls to
196 * <code>set()</code> do not trigger multiple, unnecessary
197 * computations. As a result of changing a calendar field using
198 * <code>set()</code>, other calendar fields may also change, depending on the
199 * calendar field, the calendar field value, and the calendar system. In addition,
200 * <code>get(f)</code> will not necessarily return <code>value</code> set by
201 * the call to the <code>set</code> method
202 * after the calendar fields have been recomputed. The specifics are determined by
203 * the concrete calendar class.</p>
204 *
205 * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
206 * originally set to August 31, 1999. Calling <code>set(Calendar.MONTH,
207 * Calendar.SEPTEMBER)</code> sets the date to September 31,
208 * 1999. This is a temporary internal representation that resolves to
209 * October 1, 1999 if <code>getTime()</code>is then called. However, a
210 * call to <code>set(Calendar.DAY_OF_MONTH, 30)</code> before the call to
211 * <code>getTime()</code> sets the date to September 30, 1999, since
212 * no recomputation occurs after <code>set()</code> itself.</p>
213 *
214 * <p><strong><code>add(f, delta)</code></strong> adds <code>delta</code>
215 * to field <code>f</code>. This is equivalent to calling <code>set(f,
216 * get(f) + delta)</code> with two adjustments:</p>
217 *
218 * <blockquote>
219 * <p><strong>Add rule 1</strong>. The value of field <code>f</code>
220 * after the call minus the value of field <code>f</code> before the
221 * call is <code>delta</code>, modulo any overflow that has occurred in
222 * field <code>f</code>. Overflow occurs when a field value exceeds its
223 * range and, as a result, the next larger field is incremented or
224 * decremented and the field value is adjusted back into its range.</p>
225 *
226 * <p><strong>Add rule 2</strong>. If a smaller field is expected to be
227 * invariant, but it is impossible for it to be equal to its
228 * prior value because of changes in its minimum or maximum after field
229 * <code>f</code> is changed or other constraints, such as time zone
230 * offset changes, then its value is adjusted to be as close
231 * as possible to its expected value. A smaller field represents a
232 * smaller unit of time. <code>HOUR</code> is a smaller field than
233 * <code>DAY_OF_MONTH</code>. No adjustment is made to smaller fields
234 * that are not expected to be invariant. The calendar system
235 * determines what fields are expected to be invariant.</p>
236 * </blockquote>
237 *
238 * <p>In addition, unlike <code>set()</code>, <code>add()</code> forces
239 * an immediate recomputation of the calendar's milliseconds and all
240 * fields.</p>
241 *
242 * <p><em>Example</em>: Consider a <code>GregorianCalendar</code>
243 * originally set to August 31, 1999. Calling <code>add(Calendar.MONTH,
244 * 13)</code> sets the calendar to September 30, 2000. <strong>Add rule
245 * 1</strong> sets the <code>MONTH</code> field to September, since
246 * adding 13 months to August gives September of the next year. Since
247 * <code>DAY_OF_MONTH</code> cannot be 31 in September in a
248 * <code>GregorianCalendar</code>, <strong>add rule 2</strong> sets the
249 * <code>DAY_OF_MONTH</code> to 30, the closest possible value. Although
250 * it is a smaller field, <code>DAY_OF_WEEK</code> is not adjusted by
251 * rule 2, since it is expected to change when the month changes in a
252 * <code>GregorianCalendar</code>.</p>
253 *
254 * <p><strong><code>roll(f, delta)</code></strong> adds
255 * <code>delta</code> to field <code>f</code> without changing larger
256 * fields. This is equivalent to calling <code>add(f, delta)</code> with
257 * the following adjustment:</p>
258 *
259 * <blockquote>
260 * <p><strong>Roll rule</strong>. Larger fields are unchanged after the
261 * call. A larger field represents a larger unit of
262 * time. <code>DAY_OF_MONTH</code> is a larger field than
263 * <code>HOUR</code>.</p>
264 * </blockquote>
265 *
266 * <p><em>Example</em>: See {@link java.util.GregorianCalendar#roll(int, int)}.
267 *
268 * <p><strong>Usage model</strong>. To motivate the behavior of
269 * <code>add()</code> and <code>roll()</code>, consider a user interface
270 * component with increment and decrement buttons for the month, day, and
271 * year, and an underlying <code>GregorianCalendar</code>. If the
272 * interface reads January 31, 1999 and the user presses the month
273 * increment button, what should it read? If the underlying
274 * implementation uses <code>set()</code>, it might read March 3, 1999. A
275 * better result would be February 28, 1999. Furthermore, if the user
276 * presses the month increment button again, it should read March 31,
277 * 1999, not March 28, 1999. By saving the original date and using either
278 * <code>add()</code> or <code>roll()</code>, depending on whether larger
279 * fields should be affected, the user interface can behave as most users
280 * will intuitively expect.</p>
281 *
282 * @see java.lang.System#currentTimeMillis()
283 * @see Date
284 * @see GregorianCalendar
285 * @see TimeZone
286 * @see java.text.DateFormat
287 * @version %I%, %G%
288 * @author Mark Davis, David Goldsmith, Chen-Lieh Huang, Alan Liu
289 * @since JDK1.1
290 */
291 public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> {
292
293 // Data flow in Calendar
294 // ---------------------
295
296 // The current time is represented in two ways by Calendar: as UTC
297 // milliseconds from the epoch (1 January 1970 0:00 UTC), and as local
298 // fields such as MONTH, HOUR, AM_PM, etc. It is possible to compute the
299 // millis from the fields, and vice versa. The data needed to do this
300 // conversion is encapsulated by a TimeZone object owned by the Calendar.
301 // The data provided by the TimeZone object may also be overridden if the
302 // user sets the ZONE_OFFSET and/or DST_OFFSET fields directly. The class
303 // keeps track of what information was most recently set by the caller, and
304 // uses that to compute any other information as needed.
305
306 // If the user sets the fields using set(), the data flow is as follows.
307 // This is implemented by the Calendar subclass's computeTime() method.
308 // During this process, certain fields may be ignored. The disambiguation
309 // algorithm for resolving which fields to pay attention to is described
310 // in the class documentation.
311
312 // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
313 // |
314 // | Using Calendar-specific algorithm
315 // V
316 // local standard millis
317 // |
318 // | Using TimeZone or user-set ZONE_OFFSET / DST_OFFSET
319 // V
320 // UTC millis (in time data member)
321
322 // If the user sets the UTC millis using setTime() or setTimeInMillis(),
323 // the data flow is as follows. This is implemented by the Calendar
324 // subclass's computeFields() method.
325
326 // UTC millis (in time data member)
327 // |
328 // | Using TimeZone getOffset()
329 // V
330 // local standard millis
331 // |
332 // | Using Calendar-specific algorithm
333 // V
334 // local fields (YEAR, MONTH, DATE, HOUR, MINUTE, etc.)
335
336 // In general, a round trip from fields, through local and UTC millis, and
337 // back out to fields is made when necessary. This is implemented by the
338 // complete() method. Resolving a partial set of fields into a UTC millis
339 // value allows all remaining fields to be generated from that value. If
340 // the Calendar is lenient, the fields are also renormalized to standard
341 // ranges when they are regenerated.
342
343 /**
344 * Field number for <code>get</code> and <code>set</code> indicating the
345 * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific
346 * value; see subclass documentation.
347 *
348 * @see GregorianCalendar#AD
349 * @see GregorianCalendar#BC
350 */
351 public final static int ERA = 0;
352
353 /**
354 * Field number for <code>get</code> and <code>set</code> indicating the
355 * year. This is a calendar-specific value; see subclass documentation.
356 */
357 public final static int YEAR = 1;
358
359 /**
360 * Field number for <code>get</code> and <code>set</code> indicating the
361 * month. This is a calendar-specific value. The first month of
362 * the year in the Gregorian and Julian calendars is
363 * <code>JANUARY</code> which is 0; the last depends on the number
364 * of months in a year.
365 *
366 * @see #JANUARY
367 * @see #FEBRUARY
368 * @see #MARCH
369 * @see #APRIL
370 * @see #MAY
371 * @see #JUNE
372 * @see #JULY
373 * @see #AUGUST
374 * @see #SEPTEMBER
375 * @see #OCTOBER
376 * @see #NOVEMBER
377 * @see #DECEMBER
378 * @see #UNDECIMBER
379 */
380 public final static int MONTH = 2;
381
382 /**
383 * Field number for <code>get</code> and <code>set</code> indicating the
384 * week number within the current year. The first week of the year, as
385 * defined by <code>getFirstDayOfWeek()</code> and
386 * <code>getMinimalDaysInFirstWeek()</code>, has value 1. Subclasses define
387 * the value of <code>WEEK_OF_YEAR</code> for days before the first week of
388 * the year.
389 *
390 * @see #getFirstDayOfWeek
391 * @see #getMinimalDaysInFirstWeek
392 */
393 public final static int WEEK_OF_YEAR = 3;
394
395 /**
396 * Field number for <code>get</code> and <code>set</code> indicating the
397 * week number within the current month. The first week of the month, as
398 * defined by <code>getFirstDayOfWeek()</code> and
399 * <code>getMinimalDaysInFirstWeek()</code>, has value 1. Subclasses define
400 * the value of <code>WEEK_OF_MONTH</code> for days before the first week of
401 * the month.
402 *
403 * @see #getFirstDayOfWeek
404 * @see #getMinimalDaysInFirstWeek
405 */
406 public final static int WEEK_OF_MONTH = 4;
407
408 /**
409 * Field number for <code>get</code> and <code>set</code> indicating the
410 * day of the month. This is a synonym for <code>DAY_OF_MONTH</code>.
411 * The first day of the month has value 1.
412 *
413 * @see #DAY_OF_MONTH
414 */
415 public final static int DATE = 5;
416
417 /**
418 * Field number for <code>get</code> and <code>set</code> indicating the
419 * day of the month. This is a synonym for <code>DATE</code>.
420 * The first day of the month has value 1.
421 *
422 * @see #DATE
423 */
424 public final static int DAY_OF_MONTH = 5;
425
426 /**
427 * Field number for <code>get</code> and <code>set</code> indicating the day
428 * number within the current year. The first day of the year has value 1.
429 */
430 public final static int DAY_OF_YEAR = 6;
431
432 /**
433 * Field number for <code>get</code> and <code>set</code> indicating the day
434 * of the week. This field takes values <code>SUNDAY</code>,
435 * <code>MONDAY</code>, <code>TUESDAY</code>, <code>WEDNESDAY</code>,
436 * <code>THURSDAY</code>, <code>FRIDAY</code>, and <code>SATURDAY</code>.
437 *
438 * @see #SUNDAY
439 * @see #MONDAY
440 * @see #TUESDAY
441 * @see #WEDNESDAY
442 * @see #THURSDAY
443 * @see #FRIDAY
444 * @see #SATURDAY
445 */
446 public final static int DAY_OF_WEEK = 7;
447
448 /**
449 * Field number for <code>get</code> and <code>set</code> indicating the
450 * ordinal number of the day of the week within the current month. Together
451 * with the <code>DAY_OF_WEEK</code> field, this uniquely specifies a day
452 * within a month. Unlike <code>WEEK_OF_MONTH</code> and
453 * <code>WEEK_OF_YEAR</code>, this field's value does <em>not</em> depend on
454 * <code>getFirstDayOfWeek()</code> or
455 * <code>getMinimalDaysInFirstWeek()</code>. <code>DAY_OF_MONTH 1</code>
456 * through <code>7</code> always correspond to <code>DAY_OF_WEEK_IN_MONTH
457 * 1</code>; <code>8</code> through <code>14</code> correspond to
458 * <code>DAY_OF_WEEK_IN_MONTH 2</code>, and so on.
459 * <code>DAY_OF_WEEK_IN_MONTH 0</code> indicates the week before
460 * <code>DAY_OF_WEEK_IN_MONTH 1</code>. Negative values count back from the
461 * end of the month, so the last Sunday of a month is specified as
462 * <code>DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1</code>. Because
463 * negative values count backward they will usually be aligned differently
464 * within the month than positive values. For example, if a month has 31
465 * days, <code>DAY_OF_WEEK_IN_MONTH -1</code> will overlap
466 * <code>DAY_OF_WEEK_IN_MONTH 5</code> and the end of <code>4</code>.
467 *
468 * @see #DAY_OF_WEEK
469 * @see #WEEK_OF_MONTH
470 */
471 public final static int DAY_OF_WEEK_IN_MONTH = 8;
472
473 /**
474 * Field number for <code>get</code> and <code>set</code> indicating
475 * whether the <code>HOUR</code> is before or after noon.
476 * E.g., at 10:04:15.250 PM the <code>AM_PM</code> is <code>PM</code>.
477 *
478 * @see #AM
479 * @see #PM
480 * @see #HOUR
481 */
482 public final static int AM_PM = 9;
483
484 /**
485 * Field number for <code>get</code> and <code>set</code> indicating the
486 * hour of the morning or afternoon. <code>HOUR</code> is used for the
487 * 12-hour clock (0 - 11). Noon and midnight are represented by 0, not by 12.
488 * E.g., at 10:04:15.250 PM the <code>HOUR</code> is 10.
489 *
490 * @see #AM_PM
491 * @see #HOUR_OF_DAY
492 */
493 public final static int HOUR = 10;
494
495 /**
496 * Field number for <code>get</code> and <code>set</code> indicating the
497 * hour of the day. <code>HOUR_OF_DAY</code> is used for the 24-hour clock.
498 * E.g., at 10:04:15.250 PM the <code>HOUR_OF_DAY</code> is 22.
499 *
500 * @see #HOUR
501 */
502 public final static int HOUR_OF_DAY = 11;
503
504 /**
505 * Field number for <code>get</code> and <code>set</code> indicating the
506 * minute within the hour.
507 * E.g., at 10:04:15.250 PM the <code>MINUTE</code> is 4.
508 */
509 public final static int MINUTE = 12;
510
511 /**
512 * Field number for <code>get</code> and <code>set</code> indicating the
513 * second within the minute.
514 * E.g., at 10:04:15.250 PM the <code>SECOND</code> is 15.
515 */
516 public final static int SECOND = 13;
517
518 /**
519 * Field number for <code>get</code> and <code>set</code> indicating the
520 * millisecond within the second.
521 * E.g., at 10:04:15.250 PM the <code>MILLISECOND</code> is 250.
522 */
523 public final static int MILLISECOND = 14;
524
525 /**
526 * Field number for <code>get</code> and <code>set</code>
527 * indicating the raw offset from GMT in milliseconds.
528 * <p>
529 * This field reflects the correct GMT offset value of the time
530 * zone of this <code>Calendar</code> if the
531 * <code>TimeZone</code> implementation subclass supports
532 * historical GMT offset changes.
533 */
534 public final static int ZONE_OFFSET = 15;
535
536 /**
537 * Field number for <code>get</code> and <code>set</code> indicating the
538 * daylight savings offset in milliseconds.
539 * <p>
540 * This field reflects the correct daylight saving offset value of
541 * the time zone of this <code>Calendar</code> if the
542 * <code>TimeZone</code> implementation subclass supports
543 * historical Daylight Saving Time schedule changes.
544 */
545 public final static int DST_OFFSET = 16;
546
547 /**
548 * The number of distinct fields recognized by <code>get</code> and <code>set</code>.
549 * Field numbers range from <code>0..FIELD_COUNT-1</code>.
550 */
551 public final static int FIELD_COUNT = 17;
552
553 /**
554 * Value of the {@link #DAY_OF_WEEK} field indicating
555 * Sunday.
556 */
557 public final static int SUNDAY = 1;
558
559 /**
560 * Value of the {@link #DAY_OF_WEEK} field indicating
561 * Monday.
562 */
563 public final static int MONDAY = 2;
564
565 /**
566 * Value of the {@link #DAY_OF_WEEK} field indicating
567 * Tuesday.
568 */
569 public final static int TUESDAY = 3;
570
571 /**
572 * Value of the {@link #DAY_OF_WEEK} field indicating
573 * Wednesday.
574 */
575 public final static int WEDNESDAY = 4;
576
577 /**
578 * Value of the {@link #DAY_OF_WEEK} field indicating
579 * Thursday.
580 */
581 public final static int THURSDAY = 5;
582
583 /**
584 * Value of the {@link #DAY_OF_WEEK} field indicating
585 * Friday.
586 */
587 public final static int FRIDAY = 6;
588
589 /**
590 * Value of the {@link #DAY_OF_WEEK} field indicating
591 * Saturday.
592 */
593 public final static int SATURDAY = 7;
594
595 /**
596 * Value of the {@link #MONTH} field indicating the
597 * first month of the year in the Gregorian and Julian calendars.
598 */
599 public final static int JANUARY = 0;
600
601 /**
602 * Value of the {@link #MONTH} field indicating the
603 * second month of the year in the Gregorian and Julian calendars.
604 */
605 public final static int FEBRUARY = 1;
606
607 /**
608 * Value of the {@link #MONTH} field indicating the
609 * third month of the year in the Gregorian and Julian calendars.
610 */
611 public final static int MARCH = 2;
612
613 /**
614 * Value of the {@link #MONTH} field indicating the
615 * fourth month of the year in the Gregorian and Julian calendars.
616 */
617 public final static int APRIL = 3;
618
619 /**
620 * Value of the {@link #MONTH} field indicating the
621 * fifth month of the year in the Gregorian and Julian calendars.
622 */
623 public final static int MAY = 4;
624
625 /**
626 * Value of the {@link #MONTH} field indicating the
627 * sixth month of the year in the Gregorian and Julian calendars.
628 */
629 public final static int JUNE = 5;
630
631 /**
632 * Value of the {@link #MONTH} field indicating the
633 * seventh month of the year in the Gregorian and Julian calendars.
634 */
635 public final static int JULY = 6;
636
637 /**
638 * Value of the {@link #MONTH} field indicating the
639 * eighth month of the year in the Gregorian and Julian calendars.
640 */
641 public final static int AUGUST = 7;
642
643 /**
644 * Value of the {@link #MONTH} field indicating the
645 * ninth month of the year in the Gregorian and Julian calendars.
646 */
647 public final static int SEPTEMBER = 8;
648
649 /**
650 * Value of the {@link #MONTH} field indicating the
651 * tenth month of the year in the Gregorian and Julian calendars.
652 */
653 public final static int OCTOBER = 9;
654
655 /**
656 * Value of the {@link #MONTH} field indicating the
657 * eleventh month of the year in the Gregorian and Julian calendars.
658 */
659 public final static int NOVEMBER = 10;
660
661 /**
662 * Value of the {@link #MONTH} field indicating the
663 * twelfth month of the year in the Gregorian and Julian calendars.
664 */
665 public final static int DECEMBER = 11;
666
667 /**
668 * Value of the {@link #MONTH} field indicating the
669 * thirteenth month of the year. Although <code>GregorianCalendar</code>
670 * does not use this value, lunar calendars do.
671 */
672 public final static int UNDECIMBER = 12;
673
674 /**
675 * Value of the {@link #AM_PM} field indicating the
676 * period of the day from midnight to just before noon.
677 */
678 public final static int AM = 0;
679
680 /**
681 * Value of the {@link #AM_PM} field indicating the
682 * period of the day from noon to just before midnight.
683 */
684 public final static int PM = 1;
685
686 /**
687 * A style specifier for {@link #getDisplayNames(int, int, Locale)
688 * getDisplayNames} indicating names in all styles, such as
689 * "January" and "Jan".
690 *
691 * @see #SHORT
692 * @see #LONG
693 * @since 1.6
694 */
695 public static final int ALL_STYLES = 0;
696
697 /**
698 * A style specifier for {@link #getDisplayName(int, int, Locale)
699 * getDisplayName} and {@link #getDisplayNames(int, int, Locale)
700 * getDisplayNames} indicating a short name, such as "Jan".
701 *
702 * @see #LONG
703 * @since 1.6
704 */
705 public static final int SHORT = 1;
706
707 /**
708 * A style specifier for {@link #getDisplayName(int, int, Locale)
709 * getDisplayName} and {@link #getDisplayNames(int, int, Locale)
710 * getDisplayNames} indicating a long name, such as "January".
711 *
712 * @see #SHORT
713 * @since 1.6
714 */
715 public static final int LONG = 2;
716
717 // Internal notes:
718 // Calendar contains two kinds of time representations: current "time" in
719 // milliseconds, and a set of calendar "fields" representing the current time.
720 // The two representations are usually in sync, but can get out of sync
721 // as follows.
722 // 1. Initially, no fields are set, and the time is invalid.
723 // 2. If the time is set, all fields are computed and in sync.
724 // 3. If a single field is set, the time is invalid.
725 // Recomputation of the time and fields happens when the object needs
726 // to return a result to the user, or use a result for a computation.
727
728 /**
729 * The calendar field values for the currently set time for this calendar.
730 * This is an array of <code>FIELD_COUNT</code> integers, with index values
731 * <code>ERA</code> through <code>DST_OFFSET</code>.
732 * @serial
733 */
734 protected int fields[];
735
736 /**
737 * The flags which tell if a specified calendar field for the calendar is set.
738 * A new object has no fields set. After the first call to a method
739 * which generates the fields, they all remain set after that.
740 * This is an array of <code>FIELD_COUNT</code> booleans, with index values
741 * <code>ERA</code> through <code>DST_OFFSET</code>.
742 * @serial
743 */
744 protected boolean isSet[];
745
746 /**
747 * Pseudo-time-stamps which specify when each field was set. There
748 * are two special values, UNSET and COMPUTED. Values from
749 * MINIMUM_USER_SET to Integer.MAX_VALUE are legal user set values.
750 */
751 transient private int stamp[];
752
753 /**
754 * The currently set time for this calendar, expressed in milliseconds after
755 * January 1, 1970, 0:00:00 GMT.
756 * @see #isTimeSet
757 * @serial
758 */
759 protected long time;
760
761 /**
762 * True if then the value of <code>time</code> is valid.
763 * The time is made invalid by a change to an item of <code>field[]</code>.
764 * @see #time
765 * @serial
766 */
767 protected boolean isTimeSet;
768
769 /**
770 * True if <code>fields[]</code> are in sync with the currently set time.
771 * If false, then the next attempt to get the value of a field will
772 * force a recomputation of all fields from the current value of
773 * <code>time</code>.
774 * @serial
775 */
776 protected boolean areFieldsSet;
777
778 /**
779 * True if all fields have been set.
780 * @serial
781 */
782 transient boolean areAllFieldsSet;
783
784 /**
785 * <code>True</code> if this calendar allows out-of-range field values during computation
786 * of <code>time</code> from <code>fields[]</code>.
787 * @see #setLenient
788 * @see #isLenient
789 * @serial
790 */
791 private boolean lenient = true;
792
793 /**
794 * The <code>TimeZone</code> used by this calendar. <code>Calendar</code>
795 * uses the time zone data to translate between locale and GMT time.
796 * @serial
797 */
798 private TimeZone zone;
799
800 /**
801 * <code>True</code> if zone references to a shared TimeZone object.
802 */
803 transient private boolean sharedZone = false;
804
805 /**
806 * The first day of the week, with possible values <code>SUNDAY</code>,
807 * <code>MONDAY</code>, etc. This is a locale-dependent value.
808 * @serial
809 */
810 private int firstDayOfWeek;
811
812 /**
813 * The number of days required for the first week in a month or year,
814 * with possible values from 1 to 7. This is a locale-dependent value.
815 * @serial
816 */
817 private int minimalDaysInFirstWeek;
818
819 /**
820 * Cache to hold the firstDayOfWeek and minimalDaysInFirstWeek
821 * of a Locale.
822 */
823 private static Hashtable<Locale, int[]> cachedLocaleData = new Hashtable<Locale, int[]>(3);
824
825 // Special values of stamp[]
826 /**
827 * The corresponding fields[] has no value.
828 */
829 private static final int UNSET = 0;
830
831 /**
832 * The value of the corresponding fields[] has been calculated internally.
833 */
834 private static final int COMPUTED = 1;
835
836 /**
837 * The value of the corresponding fields[] has been set externally. Stamp
838 * values which are greater than 1 represents the (pseudo) time when the
839 * corresponding fields[] value was set.
840 */
841 private static final int MINIMUM_USER_STAMP = 2;
842
843 /**
844 * The mask value that represents all of the fields.
845 */
846 static final int ALL_FIELDS = (1 << FIELD_COUNT) - 1;
847
848 /**
849 * The next available value for <code>stamp[]</code>, an internal array.
850 * This actually should not be written out to the stream, and will probably
851 * be removed from the stream in the near future. In the meantime,
852 * a value of <code>MINIMUM_USER_STAMP</code> should be used.
853 * @serial
854 */
855 private int nextStamp = MINIMUM_USER_STAMP;
856
857 // the internal serial version which says which version was written
858 // - 0 (default) for version up to JDK 1.1.5
859 // - 1 for version from JDK 1.1.6, which writes a correct 'time' value
860 // as well as compatible values for other fields. This is a
861 // transitional format.
862 // - 2 (not implemented yet) a future version, in which fields[],
863 // areFieldsSet, and isTimeSet become transient, and isSet[] is
864 // removed. In JDK 1.1.6 we write a format compatible with version 2.
865 static final int currentSerialVersion = 1;
866
867 /**
868 * The version of the serialized data on the stream. Possible values:
869 * <dl>
870 * <dt><b>0</b> or not present on stream</dt>
871 * <dd>
872 * JDK 1.1.5 or earlier.
873 * </dd>
874 * <dt><b>1</b></dt>
875 * <dd>
876 * JDK 1.1.6 or later. Writes a correct 'time' value
877 * as well as compatible values for other fields. This is a
878 * transitional format.
879 * </dd>
880 * </dl>
881 * When streaming out this class, the most recent format
882 * and the highest allowable <code>serialVersionOnStream</code>
883 * is written.
884 * @serial
885 * @since JDK1.1.6
886 */
887 private int serialVersionOnStream = currentSerialVersion;
888
889 // Proclaim serialization compatibility with JDK 1.1
890 static final long serialVersionUID = -1807547505821590642L;
891
892 // Mask values for calendar fields
893 final static int ERA_MASK = (1 << ERA);
894 final static int YEAR_MASK = (1 << YEAR);
895 final static int MONTH_MASK = (1 << MONTH);
896 final static int WEEK_OF_YEAR_MASK = (1 << WEEK_OF_YEAR);
897 final static int WEEK_OF_MONTH_MASK = (1 << WEEK_OF_MONTH);
898 final static int DAY_OF_MONTH_MASK = (1 << DAY_OF_MONTH);
899 final static int DATE_MASK = DAY_OF_MONTH_MASK;
900 final static int DAY_OF_YEAR_MASK = (1 << DAY_OF_YEAR);
901 final static int DAY_OF_WEEK_MASK = (1 << DAY_OF_WEEK);
902 final static int DAY_OF_WEEK_IN_MONTH_MASK = (1 << DAY_OF_WEEK_IN_MONTH);
903 final static int AM_PM_MASK = (1 << AM_PM);
904 final static int HOUR_MASK = (1 << HOUR);
905 final static int HOUR_OF_DAY_MASK = (1 << HOUR_OF_DAY);
906 final static int MINUTE_MASK = (1 << MINUTE);
907 final static int SECOND_MASK = (1 << SECOND);
908 final static int MILLISECOND_MASK = (1 << MILLISECOND);
909 final static int ZONE_OFFSET_MASK = (1 << ZONE_OFFSET);
910 final static int DST_OFFSET_MASK = (1 << DST_OFFSET);
911
912 /**
913 * Constructs a Calendar with the default time zone
914 * and locale.
915 * @see TimeZone#getDefault
916 */
917 protected Calendar()
918 {
919 this(TimeZone.getDefaultRef(), Locale.getDefault());
920 sharedZone = true;
921 }
922
923 /**
924 * Constructs a calendar with the specified time zone and locale.
925 *
926 * @param zone the time zone to use
927 * @param aLocale the locale for the week data
928 */
929 protected Calendar(TimeZone zone, Locale aLocale)
930 {
931 fields = new int[FIELD_COUNT];
932 isSet = new boolean[FIELD_COUNT];
933 stamp = new int[FIELD_COUNT];
934
935 this.zone = zone;
936 setWeekCountData(aLocale);
937 }
938
939 /**
940 * Gets a calendar using the default time zone and locale. The
941 * <code>Calendar</code> returned is based on the current time
942 * in the default time zone with the default locale.
943 *
944 * @return a Calendar.
945 */
946 public static Calendar getInstance()
947 {
948 Calendar cal = createCalendar(TimeZone.getDefaultRef(), Locale.getDefault());
949 cal.sharedZone = true;
950 return cal;
951 }
952
953 /**
954 * Gets a calendar using the specified time zone and default locale.
955 * The <code>Calendar</code> returned is based on the current time
956 * in the given time zone with the default locale.
957 *
958 * @param zone the time zone to use
959 * @return a Calendar.
960 */
961 public static Calendar getInstance(TimeZone zone)
962 {
963 return createCalendar(zone, Locale.getDefault());
964 }
965
966 /**
967 * Gets a calendar using the default time zone and specified locale.
968 * The <code>Calendar</code> returned is based on the current time
969 * in the default time zone with the given locale.
970 *
971 * @param aLocale the locale for the week data
972 * @return a Calendar.
973 */
974 public static Calendar getInstance(Locale aLocale)
975 {
976 Calendar cal = createCalendar(TimeZone.getDefaultRef(), aLocale);
977 cal.sharedZone = true;
978 return cal;
979 }
980
981 /**
982 * Gets a calendar with the specified time zone and locale.
983 * The <code>Calendar</code> returned is based on the current time
984 * in the given time zone with the given locale.
985 *
986 * @param zone the time zone to use
987 * @param aLocale the locale for the week data
988 * @return a Calendar.
989 */
990 public static Calendar getInstance(TimeZone zone,
991 Locale aLocale)
992 {
993 return createCalendar(zone, aLocale);
994 }
995
996 private static Calendar createCalendar(TimeZone zone,
997 Locale aLocale)
998 {
999 // If the specified locale is a Thai locale, returns a BuddhistCalendar
1000 // instance.
1001 if ("th".equals(aLocale.getLanguage())
1002 && ("TH".equals(aLocale.getCountry()))) {
1003 return new sun.util.BuddhistCalendar(zone, aLocale);
1004 } else if ("JP".equals(aLocale.getVariant())
1005 && "JP".equals(aLocale.getCountry())
1006 && "ja".equals(aLocale.getLanguage())) {
1007 return new JapaneseImperialCalendar(zone, aLocale);
1008 }
1009
1010 // else create the default calendar
1011 return new GregorianCalendar(zone, aLocale);
1012 }
1013
1014 /**
1015 * Returns an array of all locales for which the <code>getInstance</code>
1016 * methods of this class can return localized instances.
1017 * The array returned must contain at least a <code>Locale</code>
1018 * instance equal to {@link java.util.Locale#US Locale.US}.
1019 *
1020 * @return An array of locales for which localized
1021 * <code>Calendar</code> instances are available.
1022 */
1023 public static synchronized Locale[] getAvailableLocales()
1024 {
1025 return DateFormat.getAvailableLocales();
1026 }
1027
1028 /**
1029 * Converts the current calendar field values in {@link #fields fields[]}
1030 * to the millisecond time value
1031 * {@link #time}.
1032 *
1033 * @see #complete()
1034 * @see #computeFields()
1035 */
1036 protected abstract void computeTime();
1037
1038 /**
1039 * Converts the current millisecond time value {@link #time}
1040 * to calendar field values in {@link #fields fields[]}.
1041 * This allows you to sync up the calendar field values with
1042 * a new time that is set for the calendar. The time is <em>not</em>
1043 * recomputed first; to recompute the time, then the fields, call the
1044 * {@link #complete()} method.
1045 *
1046 * @see #computeTime()
1047 */
1048 protected abstract void computeFields();
1049
1050 /**
1051 * Returns a <code>Date</code> object representing this
1052 * <code>Calendar</code>'s time value (millisecond offset from the <a
1053 * href="#Epoch">Epoch</a>").
1054 *
1055 * @return a <code>Date</code> representing the time value.
1056 * @see #setTime(Date)
1057 * @see #getTimeInMillis()
1058 */
1059 public final Date getTime() {
1060 return new Date(getTimeInMillis());
1061 }
1062
1063 /**
1064 * Sets this Calendar's time with the given <code>Date</code>.
1065 * <p>
1066 * Note: Calling <code>setTime()</code> with
1067 * <code>Date(Long.MAX_VALUE)</code> or <code>Date(Long.MIN_VALUE)</code>
1068 * may yield incorrect field values from <code>get()</code>.
1069 *
1070 * @param date the given Date.
1071 * @see #getTime()
1072 * @see #setTimeInMillis(long)
1073 */
1074 public final void setTime(Date date) {
1075 setTimeInMillis(date.getTime());
1076 }
1077
1078 /**
1079 * Returns this Calendar's time value in milliseconds.
1080 *
1081 * @return the current time as UTC milliseconds from the epoch.
1082 * @see #getTime()
1083 * @see #setTimeInMillis(long)
1084 */
1085 public long getTimeInMillis() {
1086 if (!isTimeSet) {
1087 updateTime();
1088 }
1089 return time;
1090 }
1091
1092 /**
1093 * Sets this Calendar's current time from the given long value.
1094 *
1095 * @param millis the new time in UTC milliseconds from the epoch.
1096 * @see #setTime(Date)
1097 * @see #getTimeInMillis()
1098 */
1099 public void setTimeInMillis(long millis) {
1100 // If we don't need to recalculate the calendar field values,
1101 // do nothing.
1102 if (time == millis && isTimeSet && areFieldsSet && areAllFieldsSet
1103 && (zone instanceof ZoneInfo) && !((ZoneInfo)zone).isDirty()) {
1104 return;
1105 }
1106 time = millis;
1107 isTimeSet = true;
1108 areFieldsSet = false;
1109 computeFields();
1110 areAllFieldsSet = areFieldsSet = true;
1111 }
1112
1113 /**
1114 * Returns the value of the given calendar field. In lenient mode,
1115 * all calendar fields are normalized. In non-lenient mode, all
1116 * calendar fields are validated and this method throws an
1117 * exception if any calendar fields have out-of-range values. The
1118 * normalization and validation are handled by the
1119 * {@link #complete()} method, which process is calendar
1120 * system dependent.
1121 *
1122 * @param field the given calendar field.
1123 * @return the value for the given calendar field.
1124 * @throws ArrayIndexOutOfBoundsException if the specified field is out of range
1125 * (<code>field < 0 || field >= FIELD_COUNT</code>).
1126 * @see #set(int,int)
1127 * @see #complete()
1128 */
1129 public int get(int field)
1130 {
1131 complete();
1132 return internalGet(field);
1133 }
1134
1135 /**
1136 * Returns the value of the given calendar field. This method does
1137 * not involve normalization or validation of the field value.
1138 *
1139 * @param field the given calendar field.
1140 * @return the value for the given calendar field.
1141 * @see #get(int)
1142 */
1143 protected final int internalGet(int field)
1144 {
1145 return fields[field];
1146 }
1147
1148 /**
1149 * Sets the value of the given calendar field. This method does
1150 * not affect any setting state of the field in this
1151 * <code>Calendar</code> instance.
1152 *
1153 * @throws IndexOutOfBoundsException if the specified field is out of range
1154 * (<code>field < 0 || field >= FIELD_COUNT</code>).
1155 * @see #areFieldsSet
1156 * @see #isTimeSet
1157 * @see #areAllFieldsSet
1158 * @see #set(int,int)
1159 */
1160 final void internalSet(int field, int value)
1161 {
1162 fields[field] = value;
1163 }
1164
1165 /**
1166 * Sets the given calendar field to the given value. The value is not
1167 * interpreted by this method regardless of the leniency mode.
1168 *
1169 * @param field the given calendar field.
1170 * @param value the value to be set for the given calendar field.
1171 * @throws ArrayIndexOutOfBoundsException if the specified field is out of range
1172 * (<code>field < 0 || field >= FIELD_COUNT</code>).
1173 * in non-lenient mode.
1174 * @see #set(int,int,int)
1175 * @see #set(int,int,int,int,int)
1176 * @see #set(int,int,int,int,int,int)
1177 * @see #get(int)
1178 */
1179 public void set(int field, int value)
1180 {
1181 if (isLenient() && areFieldsSet && !areAllFieldsSet) {
1182 computeFields();
1183 }
1184 internalSet(field, value);
1185 isTimeSet = false;
1186 areFieldsSet = false;
1187 isSet[field] = true;
1188 stamp[field] = nextStamp++;
1189 if (nextStamp == Integer.MAX_VALUE) {
1190 adjustStamp();
1191 }
1192 }
1193
1194 /**
1195 * Sets the values for the calendar fields <code>YEAR</code>,
1196 * <code>MONTH</code>, and <code>DAY_OF_MONTH</code>.
1197 * Previous values of other calendar fields are retained. If this is not desired,
1198 * call {@link #clear()} first.
1199 *
1200 * @param year the value used to set the <code>YEAR</code> calendar field.
1201 * @param month the value used to set the <code>MONTH</code> calendar field.
1202 * Month value is 0-based. e.g., 0 for January.
1203 * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field.
1204 * @see #set(int,int)
1205 * @see #set(int,int,int,int,int)
1206 * @see #set(int,int,int,int,int,int)
1207 */
1208 public final void set(int year, int month, int date)
1209 {
1210 set(YEAR, year);
1211 set(MONTH, month);
1212 set(DATE, date);
1213 }
1214
1215 /**
1216 * Sets the values for the calendar fields <code>YEAR</code>,
1217 * <code>MONTH</code>, <code>DAY_OF_MONTH</code>,
1218 * <code>HOUR_OF_DAY</code>, and <code>MINUTE</code>.
1219 * Previous values of other fields are retained. If this is not desired,
1220 * call {@link #clear()} first.
1221 *
1222 * @param year the value used to set the <code>YEAR</code> calendar field.
1223 * @param month the value used to set the <code>MONTH</code> calendar field.
1224 * Month value is 0-based. e.g., 0 for January.
1225 * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field.
1226 * @param hourOfDay the value used to set the <code>HOUR_OF_DAY</code> calendar field.
1227 * @param minute the value used to set the <code>MINUTE</code> calendar field.
1228 * @see #set(int,int)
1229 * @see #set(int,int,int)
1230 * @see #set(int,int,int,int,int,int)
1231 */
1232 public final void set(int year, int month, int date, int hourOfDay, int minute)
1233 {
1234 set(YEAR, year);
1235 set(MONTH, month);
1236 set(DATE, date);
1237 set(HOUR_OF_DAY, hourOfDay);
1238 set(MINUTE, minute);
1239 }
1240
1241 /**
1242 * Sets the values for the fields <code>YEAR</code>, <code>MONTH</code>,
1243 * <code>DAY_OF_MONTH</code>, <code>HOUR</code>, <code>MINUTE</code>, and
1244 * <code>SECOND</code>.
1245 * Previous values of other fields are retained. If this is not desired,
1246 * call {@link #clear()} first.
1247 *
1248 * @param year the value used to set the <code>YEAR</code> calendar field.
1249 * @param month the value used to set the <code>MONTH</code> calendar field.
1250 * Month value is 0-based. e.g., 0 for January.
1251 * @param date the value used to set the <code>DAY_OF_MONTH</code> calendar field.
1252 * @param hourOfDay the value used to set the <code>HOUR_OF_DAY</code> calendar field.
1253 * @param minute the value used to set the <code>MINUTE</code> calendar field.
1254 * @param second the value used to set the <code>SECOND</code> calendar field.
1255 * @see #set(int,int)
1256 * @see #set(int,int,int)
1257 * @see #set(int,int,int,int,int)
1258 */
1259 public final void set(int year, int month, int date, int hourOfDay, int minute,
1260 int second)
1261 {
1262 set(YEAR, year);
1263 set(MONTH, month);
1264 set(DATE, date);
1265 set(HOUR_OF_DAY, hourOfDay);
1266 set(MINUTE, minute);
1267 set(SECOND, second);
1268 }
1269
1270 /**
1271 * Sets all the calendar field values and the time value
1272 * (millisecond offset from the <a href="#Epoch">Epoch</a>) of
1273 * this <code>Calendar</code> undefined. This means that {@link
1274 * #isSet(int) isSet()} will return <code>false</code> for all the
1275 * calendar fields, and the date and time calculations will treat
1276 * the fields as if they had never been set. A
1277 * <code>Calendar</code> implementation class may use its specific
1278 * default field values for date/time calculations. For example,
1279 * <code>GregorianCalendar</code> uses 1970 if the
1280 * <code>YEAR</code> field value is undefined.
1281 *
1282 * @see #clear(int)
1283 */
1284 public final void clear()
1285 {
1286 for (int i = 0; i < fields.length; ) {
1287 stamp[i] = fields[i] = 0; // UNSET == 0
1288 isSet[i++] = false;
1289 }
1290 areAllFieldsSet = areFieldsSet = false;
1291 isTimeSet = false;
1292 }
1293
1294 /**
1295 * Sets the given calendar field value and the time value
1296 * (millisecond offset from the <a href="#Epoch">Epoch</a>) of
1297 * this <code>Calendar</code> undefined. This means that {@link
1298 * #isSet(int) isSet(field)} will return <code>false</code>, and
1299 * the date and time calculations will treat the field as if it
1300 * had never been set. A <code>Calendar</code> implementation
1301 * class may use the field's specific default value for date and
1302 * time calculations.
1303 *
1304 * <p>The {@link #HOUR_OF_DAY}, {@link #HOUR} and {@link #AM_PM}
1305 * fields are handled independently and the <a
1306 * href="#time_resolution">the resolution rule for the time of
1307 * day</a> is applied. Clearing one of the fields doesn't reset
1308 * the hour of day value of this <code>Calendar</code>. Use {@link
1309 * #set(int,int) set(Calendar.HOUR_OF_DAY, 0)} to reset the hour
1310 * value.
1311 *
1312 * @param field the calendar field to be cleared.
1313 * @see #clear()
1314 */
1315 public final void clear(int field)
1316 {
1317 fields[field] = 0;
1318 stamp[field] = UNSET;
1319 isSet[field] = false;
1320
1321 areAllFieldsSet = areFieldsSet = false;
1322 isTimeSet = false;
1323 }
1324
1325 /**
1326 * Determines if the given calendar field has a value set,
1327 * including cases that the value has been set by internal fields
1328 * calculations triggered by a <code>get</code> method call.
1329 *
1330 * @return <code>true</code> if the given calendar field has a value set;
1331 * <code>false</code> otherwise.
1332 */
1333 public final boolean isSet(int field)
1334 {
1335 return stamp[field] != UNSET;
1336 }
1337
1338 /**
1339 * Returns the string representation of the calendar
1340 * <code>field</code> value in the given <code>style</code> and
1341 * <code>locale</code>. If no string representation is
1342 * applicable, <code>null</code> is returned. This method calls
1343 * {@link Calendar#get(int) get(field)} to get the calendar
1344 * <code>field</code> value if the string representation is
1345 * applicable to the given calendar <code>field</code>.
1346 *
1347 * <p>For example, if this <code>Calendar</code> is a
1348 * <code>GregorianCalendar</code> and its date is 2005-01-01, then
1349 * the string representation of the {@link #MONTH} field would be
1350 * "January" in the long style in an English locale or "Jan" in
1351 * the short style. However, no string representation would be
1352 * available for the {@link #DAY_OF_MONTH} field, and this method
1353 * would return <code>null</code>.
1354 *
1355 * <p>The default implementation supports the calendar fields for
1356 * which a {@link DateFormatSymbols} has names in the given
1357 * <code>locale</code>.
1358 *
1359 * @param field
1360 * the calendar field for which the string representation
1361 * is returned
1362 * @param style
1363 * the style applied to the string representation; one of
1364 * {@link #SHORT} or {@link #LONG}.
1365 * @param locale
1366 * the locale for the string representation
1367 * @return the string representation of the given
1368 * <code>field</code> in the given <code>style</code>, or
1369 * <code>null</code> if no string representation is
1370 * applicable.
1371 * @exception IllegalArgumentException
1372 * if <code>field</code> or <code>style</code> is invalid,
1373 * or if this <code>Calendar</code> is non-lenient and any
1374 * of the calendar fields have invalid values
1375 * @exception NullPointerException
1376 * if <code>locale</code> is null
1377 * @since 1.6
1378 */
1379 public String getDisplayName(int field, int style, Locale locale) {
1380 if (!checkDisplayNameParams(field, style, ALL_STYLES, LONG, locale,
1381 ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) {
1382 return null;
1383 }
1384
1385 DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale);
1386 String[] strings = getFieldStrings(field, style, symbols);
1387 if (strings != null) {
1388 int fieldValue = get(field);
1389 if (fieldValue < strings.length) {
1390 return strings[fieldValue];
1391 }
1392 }
1393 return null;
1394 }
1395
1396 /**
1397 * Returns a <code>Map</code> containing all names of the calendar
1398 * <code>field</code> in the given <code>style</code> and
1399 * <code>locale</code> and their corresponding field values. For
1400 * example, if this <code>Calendar</code> is a {@link
1401 * GregorianCalendar}, the returned map would contain "Jan" to
1402 * {@link #JANUARY}, "Feb" to {@link #FEBRUARY}, and so on, in the
1403 * {@linkplain #SHORT short} style in an English locale.
1404 *
1405 * <p>The values of other calendar fields may be taken into
1406 * account to determine a set of display names. For example, if
1407 * this <code>Calendar</code> is a lunisolar calendar system and
1408 * the year value given by the {@link #YEAR} field has a leap
1409 * month, this method would return month names containing the leap
1410 * month name, and month names are mapped to their values specific
1411 * for the year.
1412 *
1413 * <p>The default implementation supports display names contained in
1414 * a {@link DateFormatSymbols}. For example, if <code>field</code>
1415 * is {@link #MONTH} and <code>style</code> is {@link
1416 * #ALL_STYLES}, this method returns a <code>Map</code> containing
1417 * all strings returned by {@link DateFormatSymbols#getShortMonths()}
1418 * and {@link DateFormatSymbols#getMonths()}.
1419 *
1420 * @param field
1421 * the calendar field for which the display names are returned
1422 * @param style
1423 * the style applied to the display names; one of {@link
1424 * #SHORT}, {@link #LONG}, or {@link #ALL_STYLES}.
1425 * @param locale
1426 * the locale for the display names
1427 * @return a <code>Map</code> containing all display names in
1428 * <code>style</code> and <code>locale</code> and their
1429 * field values, or <code>null</code> if no display names
1430 * are defined for <code>field</code>
1431 * @exception IllegalArgumentException
1432 * if <code>field</code> or <code>style</code> is invalid,
1433 * or if this <code>Calendar</code> is non-lenient and any
1434 * of the calendar fields have invalid values
1435 * @exception NullPointerException
1436 * if <code>locale</code> is null
1437 * @since 1.6
1438 */
1439 public Map<String, Integer> getDisplayNames(int field, int style, Locale locale) {
1440 if (!checkDisplayNameParams(field, style, ALL_STYLES, LONG, locale,
1441 ERA_MASK|MONTH_MASK|DAY_OF_WEEK_MASK|AM_PM_MASK)) {
1442 return null;
1443 }
1444
1445 // ALL_STYLES
1446 if (style == ALL_STYLES) {
1447 Map<String,Integer> shortNames = getDisplayNamesImpl(field, SHORT, locale);
1448 if (field == ERA || field == AM_PM) {
1449 return shortNames;
1450 }
1451 Map<String,Integer> longNames = getDisplayNamesImpl(field, LONG, locale);
1452 if (shortNames == null) {
1453 return longNames;
1454 }
1455 if (longNames != null) {
1456 shortNames.putAll(longNames);
1457 }
1458 return shortNames;
1459 }
1460
1461 // SHORT or LONG
1462 return getDisplayNamesImpl(field, style, locale);
1463 }
1464
1465 private Map<String,Integer> getDisplayNamesImpl(int field, int style, Locale locale) {
1466 DateFormatSymbols symbols = DateFormatSymbols.getInstance(locale);
1467 String[] strings = getFieldStrings(field, style, symbols);
1468 if (strings != null) {
1469 Map<String,Integer> names = new HashMap<String,Integer>();
1470 for (int i = 0; i < strings.length; i++) {
1471 if (strings[i].length() == 0) {
1472 continue;
1473 }
1474 names.put(strings[i], i);
1475 }
1476 return names;
1477 }
1478 return null;
1479 }
1480
1481 boolean checkDisplayNameParams(int field, int style, int minStyle, int maxStyle,
1482 Locale locale, int fieldMask) {
1483 if (field < 0 || field >= fields.length ||
1484 style < minStyle || style > maxStyle) {
1485 throw new IllegalArgumentException();
1486 }
1487 if (locale == null) {
1488 throw new NullPointerException();
1489 }
1490 return isFieldSet(fieldMask, field);
1491 }
1492
1493 private String[] getFieldStrings(int field, int style, DateFormatSymbols symbols) {
1494 String[] strings = null;
1495 switch (field) {
1496 case ERA:
1497 strings = symbols.getEras();
1498 break;
1499
1500 case MONTH:
1501 strings = (style == LONG) ? symbols.getMonths() : symbols.getShortMonths();
1502 break;
1503
1504 case DAY_OF_WEEK:
1505 strings = (style == LONG) ? symbols.getWeekdays() : symbols.getShortWeekdays();
1506 break;
1507
1508 case AM_PM:
1509 strings = symbols.getAmPmStrings();
1510 break;
1511 }
1512 return strings;
1513 }
1514
1515 /**
1516 * Fills in any unset fields in the calendar fields. First, the {@link
1517 * #computeTime()} method is called if the time value (millisecond offset
1518 * from the <a href="#Epoch">Epoch</a>) has not been calculated from
1519 * calendar field values. Then, the {@link #computeFields()} method is
1520 * called to calculate all calendar field values.
1521 */
1522 protected void complete()
1523 {
1524 if (!isTimeSet)
1525 updateTime();
1526 if (!areFieldsSet || !areAllFieldsSet) {
1527 computeFields(); // fills in unset fields
1528 areAllFieldsSet = areFieldsSet = true;
1529 }
1530 }
1531
1532 /**
1533 * Returns whether the value of the specified calendar field has been set
1534 * externally by calling one of the setter methods rather than by the
1535 * internal time calculation.
1536 *
1537 * @return <code>true</code> if the field has been set externally,
1538 * <code>false</code> otherwise.
1539 * @exception IndexOutOfBoundsException if the specified
1540 * <code>field</code> is out of range
1541 * (<code>field < 0 || field >= FIELD_COUNT</code>).
1542 * @see #selectFields()
1543 * @see #setFieldsComputed(int)
1544 */
1545 final boolean isExternallySet(int field) {
1546 return stamp[field] >= MINIMUM_USER_STAMP;
1547 }
1548
1549 /**
1550 * Returns a field mask (bit mask) indicating all calendar fields that
1551 * have the state of externally or internally set.
1552 *
1553 * @return a bit mask indicating set state fields
1554 */
1555 final int getSetStateFields() {
1556 int mask = 0;
1557 for (int i = 0; i < fields.length; i++) {
1558 if (stamp[i] != UNSET) {
1559 mask |= 1 << i;
1560 }
1561 }
1562 return mask;
1563 }
1564
1565 /**
1566 * Sets the state of the specified calendar fields to
1567 * <em>computed</em>. This state means that the specified calendar fields
1568 * have valid values that have been set by internal time calculation
1569 * rather than by calling one of the setter methods.
1570 *
1571 * @param fieldMask the field to be marked as computed.
1572 * @exception IndexOutOfBoundsException if the specified
1573 * <code>field</code> is out of range
1574 * (<code>field < 0 || field >= FIELD_COUNT</code>).
1575 * @see #isExternallySet(int)
1576 * @see #selectFields()
1577 */
1578 final void setFieldsComputed(int fieldMask) {
1579 if (fieldMask == ALL_FIELDS) {
1580 for (int i = 0; i < fields.length; i++) {
1581 stamp[i] = COMPUTED;
1582 isSet[i] = true;
1583 }
1584 areFieldsSet = areAllFieldsSet = true;
1585 } else {
1586 for (int i = 0; i < fields.length; i++) {
1587 if ((fieldMask & 1) == 1) {
1588 stamp[i] = COMPUTED;
1589 isSet[i] = true;
1590 } else {
1591 if (areAllFieldsSet && !isSet[i]) {
1592 areAllFieldsSet = false;
1593 }
1594 }
1595 fieldMask >>>= 1;
1596 }
1597 }
1598 }
1599
1600 /**
1601 * Sets the state of the calendar fields that are <em>not</em> specified
1602 * by <code>fieldMask</code> to <em>unset</em>. If <code>fieldMask</code>
1603 * specifies all the calendar fields, then the state of this
1604 * <code>Calendar</code> becomes that all the calendar fields are in sync
1605 * with the time value (millisecond offset from the Epoch).
1606 *
1607 * @param fieldMask the field mask indicating which calendar fields are in
1608 * sync with the time value.
1609 * @exception IndexOutOfBoundsException if the specified
1610 * <code>field</code> is out of range
1611 * (<code>field < 0 || field >= FIELD_COUNT</code>).
1612 * @see #isExternallySet(int)
1613 * @see #selectFields()
1614 */
1615 final void setFieldsNormalized(int fieldMask) {
1616 if (fieldMask != ALL_FIELDS) {
1617 for (int i = 0; i < fields.length; i++) {
1618 if ((fieldMask & 1) == 0) {
1619 stamp[i] = fields[i] = 0; // UNSET == 0
1620 isSet[i] = false;
1621 }
1622 fieldMask >>= 1;
1623 }
1624 }
1625
1626 // Some or all of the fields are in sync with the
1627 // milliseconds, but the stamp values are not normalized yet.
1628 areFieldsSet = true;
1629 areAllFieldsSet = false;
1630 }
1631
1632 /**
1633 * Returns whether the calendar fields are partially in sync with the time
1634 * value or fully in sync but not stamp values are not normalized yet.
1635 */
1636 final boolean isPartiallyNormalized() {
1637 return areFieldsSet && !areAllFieldsSet;
1638 }
1639
1640 /**
1641 * Returns whether the calendar fields are fully in sync with the time
1642 * value.
1643 */
1644 final boolean isFullyNormalized() {
1645 return areFieldsSet && areAllFieldsSet;
1646 }
1647
1648 /**
1649 * Marks this Calendar as not sync'd.
1650 */
1651 final void setUnnormalized() {
1652 areFieldsSet = areAllFieldsSet = false;
1653 }
1654
1655 /**
1656 * Returns whether the specified <code>field</code> is on in the
1657 * <code>fieldMask</code>.
1658 */
1659 static final boolean isFieldSet(int fieldMask, int field) {
1660 return (fieldMask & (1 << field)) != 0;
1661 }
1662
1663 /**
1664 * Returns a field mask indicating which calendar field values
1665 * to be used to calculate the time value. The calendar fields are
1666 * returned as a bit mask, each bit of which corresponds to a field, i.e.,
1667 * the mask value of <code>field</code> is <code>(1 <<
1668 * field)</code>. For example, 0x26 represents the <code>YEAR</code>,
1669 * <code>MONTH</code>, and <code>DAY_OF_MONTH</code> fields (i.e., 0x26 is
1670 * equal to
1671 * <code>(1<<YEAR)|(1<<MONTH)|(1<<DAY_OF_MONTH))</code>.
1672 *
1673 * <p>This method supports the calendar fields resolution as described in
1674 * the class description. If the bit mask for a given field is on and its
1675 * field has not been set (i.e., <code>isSet(field)</code> is
1676 * <code>false</code>), then the default value of the field has to be
1677 * used, which case means that the field has been selected because the
1678 * selected combination involves the field.
1679 *
1680 * @return a bit mask of selected fields
1681 * @see #isExternallySet(int)
1682 * @see #setInternallySetState(int)
1683 */
1684 final int selectFields() {
1685 // This implementation has been taken from the GregorianCalendar class.
1686
1687 // The YEAR field must always be used regardless of its SET
1688 // state because YEAR is a mandatory field to determine the date
1689 // and the default value (EPOCH_YEAR) may change through the
1690 // normalization process.
1691 int fieldMask = YEAR_MASK;
1692
1693 if (stamp[ERA] != UNSET) {
1694 fieldMask |= ERA_MASK;
1695 }
1696 // Find the most recent group of fields specifying the day within
1697 // the year. These may be any of the following combinations:
1698 // MONTH + DAY_OF_MONTH
1699 // MONTH + WEEK_OF_MONTH + DAY_OF_WEEK
1700 // MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK
1701 // DAY_OF_YEAR
1702 // WEEK_OF_YEAR + DAY_OF_WEEK
1703 // We look for the most recent of the fields in each group to determine
1704 // the age of the group. For groups involving a week-related field such
1705 // as WEEK_OF_MONTH, DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR, both the
1706 // week-related field and the DAY_OF_WEEK must be set for the group as a
1707 // whole to be considered. (See bug 4153860 - liu 7/24/98.)
1708 int dowStamp = stamp[DAY_OF_WEEK];
1709 int monthStamp = stamp[MONTH];
1710 int domStamp = stamp[DAY_OF_MONTH];
1711 int womStamp = aggregateStamp(stamp[WEEK_OF_MONTH], dowStamp);
1712 int dowimStamp = aggregateStamp(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp);
1713 int doyStamp = stamp[DAY_OF_YEAR];
1714 int woyStamp = aggregateStamp(stamp[WEEK_OF_YEAR], dowStamp);
1715
1716 int bestStamp = domStamp;
1717 if (womStamp > bestStamp) {
1718 bestStamp = womStamp;
1719 }
1720 if (dowimStamp > bestStamp) {
1721 bestStamp = dowimStamp;
1722 }
1723 if (doyStamp > bestStamp) {
1724 bestStamp = doyStamp;
1725 }
1726 if (woyStamp > bestStamp) {
1727 bestStamp = woyStamp;
1728 }
1729
1730 /* No complete combination exists. Look for WEEK_OF_MONTH,
1731 * DAY_OF_WEEK_IN_MONTH, or WEEK_OF_YEAR alone. Treat DAY_OF_WEEK alone
1732 * as DAY_OF_WEEK_IN_MONTH.
1733 */
1734 if (bestStamp == UNSET) {
1735 womStamp = stamp[WEEK_OF_MONTH];
1736 dowimStamp = Math.max(stamp[DAY_OF_WEEK_IN_MONTH], dowStamp);
1737 woyStamp = stamp[WEEK_OF_YEAR];
1738 bestStamp = Math.max(Math.max(womStamp, dowimStamp), woyStamp);
1739
1740 /* Treat MONTH alone or no fields at all as DAY_OF_MONTH. This may
1741 * result in bestStamp = domStamp = UNSET if no fields are set,
1742 * which indicates DAY_OF_MONTH.
1743 */
1744 if (bestStamp == UNSET) {
1745 bestStamp = domStamp = monthStamp;
1746 }
1747 }
1748
1749 if (bestStamp == domStamp ||
1750 (bestStamp == womStamp && stamp[WEEK_OF_MONTH] >= stamp[WEEK_OF_YEAR]) ||
1751 (bestStamp == dowimStamp && stamp[DAY_OF_WEEK_IN_MONTH] >= stamp[WEEK_OF_YEAR])) {
1752 fieldMask |= MONTH_MASK;
1753 if (bestStamp == domStamp) {
1754 fieldMask |= DAY_OF_MONTH_MASK;
1755 } else {
1756 assert (bestStamp == womStamp || bestStamp == dowimStamp);
1757 if (dowStamp != UNSET) {
1758 fieldMask |= DAY_OF_WEEK_MASK;
1759 }
1760 if (bestStamp == womStamp) {
1761 fieldMask |= WEEK_OF_MONTH_MASK;
1762 } else {
1763 assert (bestStamp == dowimStamp);
1764 if (stamp[DAY_OF_WEEK_IN_MONTH] != UNSET) {
1765 fieldMask |= DAY_OF_WEEK_IN_MONTH_MASK;
1766 }
1767 }
1768 }
1769 } else {
1770 assert (bestStamp == doyStamp || bestStamp == woyStamp ||
1771 bestStamp == UNSET);
1772 if (bestStamp == doyStamp) {
1773 fieldMask |= DAY_OF_YEAR_MASK;
1774 } else {
1775 assert (bestStamp == woyStamp);
1776 if (dowStamp != UNSET) {
1777 fieldMask |= DAY_OF_WEEK_MASK;
1778 }
1779 fieldMask |= WEEK_OF_YEAR_MASK;
1780 }
1781 }
1782
1783 // Find the best set of fields specifying the time of day. There
1784 // are only two possibilities here; the HOUR_OF_DAY or the
1785 // AM_PM and the HOUR.
1786 int hourOfDayStamp = stamp[HOUR_OF_DAY];
1787 int hourStamp = aggregateStamp(stamp[HOUR], stamp[AM_PM]);
1788 bestStamp = (hourStamp > hourOfDayStamp) ? hourStamp : hourOfDayStamp;
1789
1790 // if bestStamp is still UNSET, then take HOUR or AM_PM. (See 4846659)
1791 if (bestStamp == UNSET) {
1792 bestStamp = Math.max(stamp[HOUR], stamp[AM_PM]);
1793 }
1794
1795 // Hours
1796 if (bestStamp != UNSET) {
1797 if (bestStamp == hourOfDayStamp) {
1798 fieldMask |= HOUR_OF_DAY_MASK;
1799 } else {
1800 fieldMask |= HOUR_MASK;
1801 if (stamp[AM_PM] != UNSET) {
1802 fieldMask |= AM_PM_MASK;
1803 }
1804 }
1805 }
1806 if (stamp[MINUTE] != UNSET) {
1807 fieldMask |= MINUTE_MASK;
1808 }
1809 if (stamp[SECOND] != UNSET) {
1810 fieldMask |= SECOND_MASK;
1811 }
1812 if (stamp[MILLISECOND] != UNSET) {
1813 fieldMask |= MILLISECOND_MASK;
1814 }
1815 if (stamp[ZONE_OFFSET] >= MINIMUM_USER_STAMP) {
1816 fieldMask |= ZONE_OFFSET_MASK;
1817 }
1818 if (stamp[DST_OFFSET] >= MINIMUM_USER_STAMP) {
1819 fieldMask |= DST_OFFSET_MASK;
1820 }
1821
1822 return fieldMask;
1823 }
1824
1825 /**
1826 * Returns the pseudo-time-stamp for two fields, given their
1827 * individual pseudo-time-stamps. If either of the fields
1828 * is unset, then the aggregate is unset. Otherwise, the
1829 * aggregate is the later of the two stamps.
1830 */
1831 private static final int aggregateStamp(int stamp_a, int stamp_b) {
1832 if (stamp_a == UNSET || stamp_b == UNSET) {
1833 return UNSET;
1834 }
1835 return (stamp_a > stamp_b) ? stamp_a : stamp_b;
1836 }
1837
1838 /**
1839 * Compares this <code>Calendar</code> to the specified
1840 * <code>Object</code>. The result is <code>true</code> if and only if
1841 * the argument is a <code>Calendar</code> object of the same calendar
1842 * system that represents the same time value (millisecond offset from the
1843 * <a href="#Epoch">Epoch</a>) under the same
1844 * <code>Calendar</code> parameters as this object.
1845 *
1846 * <p>The <code>Calendar</code> parameters are the values represented
1847 * by the <code>isLenient</code>, <code>getFirstDayOfWeek</code>,
1848 * <code>getMinimalDaysInFirstWeek</code> and <code>getTimeZone</code>
1849 * methods. If there is any difference in those parameters
1850 * between the two <code>Calendar</code>s, this method returns
1851 * <code>false</code>.
1852 *
1853 * <p>Use the {@link #compareTo(Calendar) compareTo} method to
1854 * compare only the time values.
1855 *
1856 * @param obj the object to compare with.
1857 * @return <code>true</code> if this object is equal to <code>obj</code>;
1858 * <code>false</code> otherwise.
1859 */
1860 public boolean equals(Object obj) {
1861 if (this == obj)
1862 return true;
1863 try {
1864 Calendar that = (Calendar)obj;
1865 return compareTo(getMillisOf(that)) == 0 &&
1866 lenient == that.lenient &&
1867 firstDayOfWeek == that.firstDayOfWeek &&
1868 minimalDaysInFirstWeek == that.minimalDaysInFirstWeek &&
1869 zone.equals(that.zone);
1870 } catch (Exception e) {
1871 // Note: GregorianCalendar.computeTime throws
1872 // IllegalArgumentException if the ERA value is invalid
1873 // even it's in lenient mode.
1874 }
1875 return false;
1876 }
1877
1878 /**
1879 * Returns a hash code for this calendar.
1880 *
1881 * @return a hash code value for this object.
1882 * @since 1.2
1883 */
1884 public int hashCode() {
1885 // 'otheritems' represents the hash code for the previous versions.
1886 int otheritems = (lenient ? 1 : 0)
1887 | (firstDayOfWeek << 1)
1888 | (minimalDaysInFirstWeek << 4)
1889 | (zone.hashCode() << 7);
1890 long t = getMillisOf(this);
1891 return (int) t ^ (int)(t >> 32) ^ otheritems;
1892 }
1893
1894 /**
1895 * Returns whether this <code>Calendar</code> represents a time
1896 * before the time represented by the specified
1897 * <code>Object</code>. This method is equivalent to:
1898 * <pre><blockquote>
1899 * compareTo(when) < 0
1900 * </blockquote></pre>
1901 * if and only if <code>when</code> is a <code>Calendar</code>
1902 * instance. Otherwise, the method returns <code>false</code>.
1903 *
1904 * @param when the <code>Object</code> to be compared
1905 * @return <code>true</code> if the time of this
1906 * <code>Calendar</code> is before the time represented by
1907 * <code>when</code>; <code>false</code> otherwise.
1908 * @see #compareTo(Calendar)
1909 */
1910 public boolean before(Object when) {
1911 return when instanceof Calendar
1912 && compareTo((Calendar)when) < 0;
1913 }
1914
1915 /**
1916 * Returns whether this <code>Calendar</code> represents a time
1917 * after the time represented by the specified
1918 * <code>Object</code>. This method is equivalent to:
1919 * <pre><blockquote>
1920 * compareTo(when) > 0
1921 * </blockquote></pre>
1922 * if and only if <code>when</code> is a <code>Calendar</code>
1923 * instance. Otherwise, the method returns <code>false</code>.
1924 *
1925 * @param when the <code>Object</code> to be compared
1926 * @return <code>true</code> if the time of this <code>Calendar</code> is
1927 * after the time represented by <code>when</code>; <code>false</code>
1928 * otherwise.
1929 * @see #compareTo(Calendar)
1930 */
1931 public boolean after(Object when) {
1932 return when instanceof Calendar
1933 && compareTo((Calendar)when) > 0;
1934 }
1935
1936 /**
1937 * Compares the time values (millisecond offsets from the <a
1938 * href="#Epoch">Epoch</a>) represented by two
1939 * <code>Calendar</code> objects.
1940 *
1941 * @param anotherCalendar the <code>Calendar</code> to be compared.
1942 * @return the value <code>0</code> if the time represented by the argument
1943 * is equal to the time represented by this <code>Calendar</code>; a value
1944 * less than <code>0</code> if the time of this <code>Calendar</code> is
1945 * before the time represented by the argument; and a value greater than
1946 * <code>0</code> if the time of this <code>Calendar</code> is after the
1947 * time represented by the argument.
1948 * @exception NullPointerException if the specified <code>Calendar</code> is
1949 * <code>null</code>.
1950 * @exception IllegalArgumentException if the time value of the
1951 * specified <code>Calendar</code> object can't be obtained due to
1952 * any invalid calendar values.
1953 * @since 1.5
1954 */
1955 public int compareTo(Calendar anotherCalendar) {
1956 return compareTo(getMillisOf(anotherCalendar));
1957 }
1958
1959 /**
1960 * Adds or subtracts the specified amount of time to the given calendar field,
1961 * based on the calendar's rules. For example, to subtract 5 days from
1962 * the current time of the calendar, you can achieve it by calling:
1963 * <p><code>add(Calendar.DAY_OF_MONTH, -5)</code>.
1964 *
1965 * @param field the calendar field.
1966 * @param amount the amount of date or time to be added to the field.
1967 * @see #roll(int,int)
1968 * @see #set(int,int)
1969 */
1970 abstract public void add(int field, int amount);
1971
1972 /**
1973 * Adds or subtracts (up/down) a single unit of time on the given time
1974 * field without changing larger fields. For example, to roll the current
1975 * date up by one day, you can achieve it by calling:
1976 * <p>roll(Calendar.DATE, true).
1977 * When rolling on the year or Calendar.YEAR field, it will roll the year
1978 * value in the range between 1 and the value returned by calling
1979 * <code>getMaximum(Calendar.YEAR)</code>.
1980 * When rolling on the month or Calendar.MONTH field, other fields like
1981 * date might conflict and, need to be changed. For instance,
1982 * rolling the month on the date 01/31/96 will result in 02/29/96.
1983 * When rolling on the hour-in-day or Calendar.HOUR_OF_DAY field, it will
1984 * roll the hour value in the range between 0 and 23, which is zero-based.
1985 *
1986 * @param field the time field.
1987 * @param up indicates if the value of the specified time field is to be
1988 * rolled up or rolled down. Use true if rolling up, false otherwise.
1989 * @see Calendar#add(int,int)
1990 * @see Calendar#set(int,int)
1991 */
1992 abstract public void roll(int field, boolean up);
1993
1994 /**
1995 * Adds the specified (signed) amount to the specified calendar field
1996 * without changing larger fields. A negative amount means to roll
1997 * down.
1998 *
1999 * <p>NOTE: This default implementation on <code>Calendar</code> just repeatedly calls the
2000 * version of {@link #roll(int,boolean) roll()} that rolls by one unit. This may not
2001 * always do the right thing. For example, if the <code>DAY_OF_MONTH</code> field is 31,
2002 * rolling through February will leave it set to 28. The <code>GregorianCalendar</code>
2003 * version of this function takes care of this problem. Other subclasses
2004 * should also provide overrides of this function that do the right thing.
2005 *
2006 * @param field the calendar field.
2007 * @param amount the signed amount to add to the calendar <code>field</code>.
2008 * @since 1.2
2009 * @see #roll(int,boolean)
2010 * @see #add(int,int)
2011 * @see #set(int,int)
2012 */
2013 public void roll(int field, int amount)
2014 {
2015 while (amount > 0) {
2016 roll(field, true);
2017 amount--;
2018 }
2019 while (amount < 0) {
2020 roll(field, false);
2021 amount++;
2022 }
2023 }
2024
2025 /**
2026 * Sets the time zone with the given time zone value.
2027 *
2028 * @param value the given time zone.
2029 */
2030 public void setTimeZone(TimeZone value)
2031 {
2032 zone = value;
2033 sharedZone = false;
2034 /* Recompute the fields from the time using the new zone. This also
2035 * works if isTimeSet is false (after a call to set()). In that case
2036 * the time will be computed from the fields using the new zone, then
2037 * the fields will get recomputed from that. Consider the sequence of
2038 * calls: cal.setTimeZone(EST); cal.set(HOUR, 1); cal.setTimeZone(PST).
2039 * Is cal set to 1 o'clock EST or 1 o'clock PST? Answer: PST. More
2040 * generally, a call to setTimeZone() affects calls to set() BEFORE AND
2041 * AFTER it up to the next call to complete().
2042 */
2043 areAllFieldsSet = areFieldsSet = false;
2044 }
2045
2046 /**
2047 * Gets the time zone.
2048 *
2049 * @return the time zone object associated with this calendar.
2050 */
2051 public TimeZone getTimeZone()
2052 {
2053 // If the TimeZone object is shared by other Calendar instances, then
2054 // create a clone.
2055 if (sharedZone) {
2056 zone = (TimeZone) zone.clone();
2057 sharedZone = false;
2058 }
2059 return zone;
2060 }
2061
2062 /**
2063 * Returns the time zone (without cloning).
2064 */
2065 TimeZone getZone() {
2066 return zone;
2067 }
2068
2069 /**
2070 * Sets the sharedZone flag to <code>shared</code>.
2071 */
2072 void setZoneShared(boolean shared) {
2073 sharedZone = shared;
2074 }
2075
2076 /**
2077 * Specifies whether or not date/time interpretation is to be lenient. With
2078 * lenient interpretation, a date such as "February 942, 1996" will be
2079 * treated as being equivalent to the 941st day after February 1, 1996.
2080 * With strict (non-lenient) interpretation, such dates will cause an exception to be
2081 * thrown. The default is lenient.
2082 *
2083 * @param lenient <code>true</code> if the lenient mode is to be turned
2084 * on; <code>false</code> if it is to be turned off.
2085 * @see #isLenient()
2086 * @see java.text.DateFormat#setLenient
2087 */
2088 public void setLenient(boolean lenient)
2089 {
2090 this.lenient = lenient;
2091 }
2092
2093 /**
2094 * Tells whether date/time interpretation is to be lenient.
2095 *
2096 * @return <code>true</code> if the interpretation mode of this calendar is lenient;
2097 * <code>false</code> otherwise.
2098 * @see #setLenient(boolean)
2099 */
2100 public boolean isLenient()
2101 {
2102 return lenient;
2103 }
2104
2105 /**
2106 * Sets what the first day of the week is; e.g., <code>SUNDAY</code> in the U.S.,
2107 * <code>MONDAY</code> in France.
2108 *
2109 * @param value the given first day of the week.
2110 * @see #getFirstDayOfWeek()
2111 * @see #getMinimalDaysInFirstWeek()
2112 */
2113 public void setFirstDayOfWeek(int value)
2114 {
2115 if (firstDayOfWeek == value) {
2116 return;
2117 }
2118 firstDayOfWeek = value;
2119 invalidateWeekFields();
2120 }
2121
2122 /**
2123 * Gets what the first day of the week is; e.g., <code>SUNDAY</code> in the U.S.,
2124 * <code>MONDAY</code> in France.
2125 *
2126 * @return the first day of the week.
2127 * @see #setFirstDayOfWeek(int)
2128 * @see #getMinimalDaysInFirstWeek()
2129 */
2130 public int getFirstDayOfWeek()
2131 {
2132 return firstDayOfWeek;
2133 }
2134
2135 /**
2136 * Sets what the minimal days required in the first week of the year are;
2137 * For example, if the first week is defined as one that contains the first
2138 * day of the first month of a year, call this method with value 1. If it
2139 * must be a full week, use value 7.
2140 *
2141 * @param value the given minimal days required in the first week
2142 * of the year.
2143 * @see #getMinimalDaysInFirstWeek()
2144 */
2145 public void setMinimalDaysInFirstWeek(int value)
2146 {
2147 if (minimalDaysInFirstWeek == value) {
2148 return;
2149 }
2150 minimalDaysInFirstWeek = value;
2151 invalidateWeekFields();
2152 }
2153
2154 /**
2155 * Gets what the minimal days required in the first week of the year are;
2156 * e.g., if the first week is defined as one that contains the first day
2157 * of the first month of a year, this method returns 1. If
2158 * the minimal days required must be a full week, this method
2159 * returns 7.
2160 *
2161 * @return the minimal days required in the first week of the year.
2162 * @see #setMinimalDaysInFirstWeek(int)
2163 */
2164 public int getMinimalDaysInFirstWeek()
2165 {
2166 return minimalDaysInFirstWeek;
2167 }
2168
2169 /**
2170 * Returns the minimum value for the given calendar field of this
2171 * <code>Calendar</code> instance. The minimum value is defined as
2172 * the smallest value returned by the {@link #get(int) get} method
2173 * for any possible time value. The minimum value depends on
2174 * calendar system specific parameters of the instance.
2175 *
2176 * @param field the calendar field.
2177 * @return the minimum value for the given calendar field.
2178 * @see #getMaximum(int)
2179 * @see #getGreatestMinimum(int)
2180 * @see #getLeastMaximum(int)
2181 * @see #getActualMinimum(int)
2182 * @see #getActualMaximum(int)
2183 */
2184 abstract public int getMinimum(int field);
2185
2186 /**
2187 * Returns the maximum value for the given calendar field of this
2188 * <code>Calendar</code> instance. The maximum value is defined as
2189 * the largest value returned by the {@link #get(int) get} method
2190 * for any possible time value. The maximum value depends on
2191 * calendar system specific parameters of the instance.
2192 *
2193 * @param field the calendar field.
2194 * @return the maximum value for the given calendar field.
2195 * @see #getMinimum(int)
2196 * @see #getGreatestMinimum(int)
2197 * @see #getLeastMaximum(int)
2198 * @see #getActualMinimum(int)
2199 * @see #getActualMaximum(int)
2200 */
2201 abstract public int getMaximum(int field);
2202
2203 /**
2204 * Returns the highest minimum value for the given calendar field
2205 * of this <code>Calendar</code> instance. The highest minimum
2206 * value is defined as the largest value returned by {@link
2207 * #getActualMinimum(int)} for any possible time value. The
2208 * greatest minimum value depends on calendar system specific
2209 * parameters of the instance.
2210 *
2211 * @param field the calendar field.
2212 * @return the highest minimum value for the given calendar field.
2213 * @see #getMinimum(int)
2214 * @see #getMaximum(int)
2215 * @see #getLeastMaximum(int)
2216 * @see #getActualMinimum(int)
2217 * @see #getActualMaximum(int)
2218 */
2219 abstract public int getGreatestMinimum(int field);
2220
2221 /**
2222 * Returns the lowest maximum value for the given calendar field
2223 * of this <code>Calendar</code> instance. The lowest maximum
2224 * value is defined as the smallest value returned by {@link
2225 * #getActualMaximum(int)} for any possible time value. The least
2226 * maximum value depends on calendar system specific parameters of
2227 * the instance. For example, a <code>Calendar</code> for the
2228 * Gregorian calendar system returns 28 for the
2229 * <code>DAY_OF_MONTH</code> field, because the 28th is the last
2230 * day of the shortest month of this calendar, February in a
2231 * common year.
2232 *
2233 * @param field the calendar field.
2234 * @return the lowest maximum value for the given calendar field.
2235 * @see #getMinimum(int)
2236 * @see #getMaximum(int)
2237 * @see #getGreatestMinimum(int)
2238 * @see #getActualMinimum(int)
2239 * @see #getActualMaximum(int)
2240 */
2241 abstract public int getLeastMaximum(int field);
2242
2243 /**
2244 * Returns the minimum value that the specified calendar field
2245 * could have, given the time value of this <code>Calendar</code>.
2246 *
2247 * <p>The default implementation of this method uses an iterative
2248 * algorithm to determine the actual minimum value for the
2249 * calendar field. Subclasses should, if possible, override this
2250 * with a more efficient implementation - in many cases, they can
2251 * simply return <code>getMinimum()</code>.
2252 *
2253 * @param field the calendar field
2254 * @return the minimum of the given calendar field for the time
2255 * value of this <code>Calendar</code>
2256 * @see #getMinimum(int)
2257 * @see #getMaximum(int)
2258 * @see #getGreatestMinimum(int)
2259 * @see #getLeastMaximum(int)
2260 * @see #getActualMaximum(int)
2261 * @since 1.2
2262 */
2263 public int getActualMinimum(int field) {
2264 int fieldValue = getGreatestMinimum(field);
2265 int endValue = getMinimum(field);
2266
2267 // if we know that the minimum value is always the same, just return it
2268 if (fieldValue == endValue) {
2269 return fieldValue;
2270 }
2271
2272 // clone the calendar so we don't mess with the real one, and set it to
2273 // accept anything for the field values
2274 Calendar work = (Calendar)this.clone();
2275 work.setLenient(true);
2276
2277 // now try each value from getLeastMaximum() to getMaximum() one by one until
2278 // we get a value that normalizes to another value. The last value that
2279 // normalizes to itself is the actual minimum for the current date
2280 int result = fieldValue;
2281
2282 do {
2283 work.set(field, fieldValue);
2284 if (work.get(field) != fieldValue) {
2285 break;
2286 } else {
2287 result = fieldValue;
2288 fieldValue--;
2289 }
2290 } while (fieldValue >= endValue);
2291
2292 return result;
2293 }
2294
2295 /**
2296 * Returns the maximum value that the specified calendar field
2297 * could have, given the time value of this
2298 * <code>Calendar</code>. For example, the actual maximum value of
2299 * the <code>MONTH</code> field is 12 in some years, and 13 in
2300 * other years in the Hebrew calendar system.
2301 *
2302 * <p>The default implementation of this method uses an iterative
2303 * algorithm to determine the actual maximum value for the
2304 * calendar field. Subclasses should, if possible, override this
2305 * with a more efficient implementation.
2306 *
2307 * @param field the calendar field
2308 * @return the maximum of the given calendar field for the time
2309 * value of this <code>Calendar</code>
2310 * @see #getMinimum(int)
2311 * @see #getMaximum(int)
2312 * @see #getGreatestMinimum(int)
2313 * @see #getLeastMaximum(int)
2314 * @see #getActualMinimum(int)
2315 * @since 1.2
2316 */
2317 public int getActualMaximum(int field) {
2318 int fieldValue = getLeastMaximum(field);
2319 int endValue = getMaximum(field);
2320
2321 // if we know that the maximum value is always the same, just return it.
2322 if (fieldValue == endValue) {
2323 return fieldValue;
2324 }
2325
2326 // clone the calendar so we don't mess with the real one, and set it to
2327 // accept anything for the field values.
2328 Calendar work = (Calendar)this.clone();
2329 work.setLenient(true);
2330
2331 // if we're counting weeks, set the day of the week to Sunday. We know the
2332 // last week of a month or year will contain the first day of the week.
2333 if (field == WEEK_OF_YEAR || field == WEEK_OF_MONTH)
2334 work.set(DAY_OF_WEEK, firstDayOfWeek);
2335
2336 // now try each value from getLeastMaximum() to getMaximum() one by one until
2337 // we get a value that normalizes to another value. The last value that
2338 // normalizes to itself is the actual maximum for the current date
2339 int result = fieldValue;
2340
2341 do {
2342 work.set(field, fieldValue);
2343 if (work.get(field) != fieldValue) {
2344 break;
2345 } else {
2346 result = fieldValue;
2347 fieldValue++;
2348 }
2349 } while (fieldValue <= endValue);
2350
2351 return result;
2352 }
2353
2354 /**
2355 * Creates and returns a copy of this object.
2356 *
2357 * @return a copy of this object.
2358 */
2359 public Object clone()
2360 {
2361 try {
2362 Calendar other = (Calendar) super.clone();
2363
2364 other.fields = new int[FIELD_COUNT];
2365 other.isSet = new boolean[FIELD_COUNT];
2366 other.stamp = new int[FIELD_COUNT];
2367 for (int i = 0; i < FIELD_COUNT; i++) {
2368 other.fields[i] = fields[i];
2369 other.stamp[i] = stamp[i];
2370 other.isSet[i] = isSet[i];
2371 }
2372 other.zone = (TimeZone) zone.clone();
2373 return other;
2374 }
2375 catch (CloneNotSupportedException e) {
2376 // this shouldn't happen, since we are Cloneable
2377 throw new InternalError();
2378 }
2379 }
2380
2381 private static final String[] FIELD_NAME = {
2382 "ERA", "YEAR", "MONTH", "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH",
2383 "DAY_OF_YEAR", "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR",
2384 "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", "ZONE_OFFSET",
2385 "DST_OFFSET"
2386 };
2387
2388 /**
2389 * Returns the name of the specified calendar field.
2390 *
2391 * @param field the calendar field
2392 * @return the calendar field name
2393 * @exception IndexOutOfBoundsException if <code>field</code> is negative,
2394 * equal to or greater then <code>FIELD_COUNT</code>.
2395 */
2396 static final String getFieldName(int field) {
2397 return FIELD_NAME[field];
2398 }
2399
2400 /**
2401 * Return a string representation of this calendar. This method
2402 * is intended to be used only for debugging purposes, and the
2403 * format of the returned string may vary between implementations.
2404 * The returned string may be empty but may not be <code>null</code>.
2405 *
2406 * @return a string representation of this calendar.
2407 */
2408 public String toString() {
2409 // NOTE: BuddhistCalendar.toString() interprets the string
2410 // produced by this method so that the Gregorian year number
2411 // is substituted by its B.E. year value. It relies on
2412 // "...,YEAR=<year>,..." or "...,YEAR=?,...".
2413 StringBuilder buffer = new StringBuilder(800);
2414 buffer.append(getClass().getName()).append('[');
2415 appendValue(buffer, "time", isTimeSet, time);
2416 buffer.append(",areFieldsSet=").append(areFieldsSet);
2417 buffer.append(",areAllFieldsSet=").append(areAllFieldsSet);
2418 buffer.append(",lenient=").append(lenient);
2419 buffer.append(",zone=").append(zone);
2420 appendValue(buffer, ",firstDayOfWeek", true, (long) firstDayOfWeek);
2421 appendValue(buffer, ",minimalDaysInFirstWeek", true, (long) minimalDaysInFirstWeek);
2422 for (int i = 0; i < FIELD_COUNT; ++i) {
2423 buffer.append(',');
2424 appendValue(buffer, FIELD_NAME[i], isSet(i), (long) fields[i]);
2425 }
2426 buffer.append(']');
2427 return buffer.toString();
2428 }
2429
2430 // =======================privates===============================
2431
2432 private static final void appendValue(StringBuilder sb, String item, boolean valid, long value) {
2433 sb.append(item).append('=');
2434 if (valid) {
2435 sb.append(value);
2436 } else {
2437 sb.append('?');
2438 }
2439 }
2440
2441 /**
2442 * Both firstDayOfWeek and minimalDaysInFirstWeek are locale-dependent.
2443 * They are used to figure out the week count for a specific date for
2444 * a given locale. These must be set when a Calendar is constructed.
2445 * @param desiredLocale the given locale.
2446 */
2447 private void setWeekCountData(Locale desiredLocale)
2448 {
2449 /* try to get the Locale data from the cache */
2450 int[] data = cachedLocaleData.get(desiredLocale);
2451 if (data == null) { /* cache miss */
2452 ResourceBundle bundle = LocaleData.getCalendarData(desiredLocale);
2453 data = new int[2];
2454 data[0] = Integer.parseInt(bundle.getString("firstDayOfWeek"));
2455 data[1] = Integer.parseInt(bundle.getString("minimalDaysInFirstWeek"));
2456 cachedLocaleData.put(desiredLocale, data);
2457 }
2458 firstDayOfWeek = data[0];
2459 minimalDaysInFirstWeek = data[1];
2460 }
2461
2462 /**
2463 * Recomputes the time and updates the status fields isTimeSet
2464 * and areFieldsSet. Callers should check isTimeSet and only
2465 * call this method if isTimeSet is false.
2466 */
2467 private void updateTime() {
2468 computeTime();
2469 // The areFieldsSet and areAllFieldsSet values are no longer
2470 // controlled here (as of 1.5).
2471 isTimeSet = true;
2472 }
2473
2474 private int compareTo(long t) {
2475 long thisTime = getMillisOf(this);
2476 return (thisTime > t) ? 1 : (thisTime == t) ? 0 : -1;
2477 }
2478
2479 private static final long getMillisOf(Calendar calendar) {
2480 if (calendar.isTimeSet) {
2481 return calendar.time;
2482 }
2483 Calendar cal = (Calendar) calendar.clone();
2484 cal.setLenient(true);
2485 return cal.getTimeInMillis();
2486 }
2487
2488 /**
2489 * Adjusts the stamp[] values before nextStamp overflow. nextStamp
2490 * is set to the next stamp value upon the return.
2491 */
2492 private final void adjustStamp() {
2493 int max = MINIMUM_USER_STAMP;
2494 int newStamp = MINIMUM_USER_STAMP;
2495
2496 for (;;) {
2497 int min = Integer.MAX_VALUE;
2498 for (int i = 0; i < stamp.length; i++) {
2499 int v = stamp[i];
2500 if (v >= newStamp && min > v) {
2501 min = v;
2502 }
2503 if (max < v) {
2504 max = v;
2505 }
2506 }
2507 if (max != min && min == Integer.MAX_VALUE) {
2508 break;
2509 }
2510 for (int i = 0; i < stamp.length; i++) {
2511 if (stamp[i] == min) {
2512 stamp[i] = newStamp;
2513 }
2514 }
2515 newStamp++;
2516 if (min == max) {
2517 break;
2518 }
2519 }
2520 nextStamp = newStamp;
2521 }
2522
2523 /**
2524 * Sets the WEEK_OF_MONTH and WEEK_OF_YEAR fields to new values with the
2525 * new parameter value if they have been calculated internally.
2526 */
2527 private void invalidateWeekFields()
2528 {
2529 if (stamp[WEEK_OF_MONTH] != COMPUTED &&
2530 stamp[WEEK_OF_YEAR] != COMPUTED) {
2531 return;
2532 }
2533
2534 // We have to check the new values of these fields after changing
2535 // firstDayOfWeek and/or minimalDaysInFirstWeek. If the field values
2536 // have been changed, then set the new values. (4822110)
2537 Calendar cal = (Calendar) clone();
2538 cal.setLenient(true);
2539 cal.clear(WEEK_OF_MONTH);
2540 cal.clear(WEEK_OF_YEAR);
2541
2542 if (stamp[WEEK_OF_MONTH] == COMPUTED) {
2543 int weekOfMonth = cal.get(WEEK_OF_MONTH);
2544 if (fields[WEEK_OF_MONTH] != weekOfMonth) {
2545 fields[WEEK_OF_MONTH] = weekOfMonth;
2546 }
2547 }
2548
2549 if (stamp[WEEK_OF_YEAR] == COMPUTED) {
2550 int weekOfYear = cal.get(WEEK_OF_YEAR);
2551 if (fields[WEEK_OF_YEAR] != weekOfYear) {
2552 fields[WEEK_OF_YEAR] = weekOfYear;
2553 }
2554 }
2555 }
2556
2557 /**
2558 * Save the state of this object to a stream (i.e., serialize it).
2559 *
2560 * Ideally, <code>Calendar</code> would only write out its state data and
2561 * the current time, and not write any field data out, such as
2562 * <code>fields[]</code>, <code>isTimeSet</code>, <code>areFieldsSet</code>,
2563 * and <code>isSet[]</code>. <code>nextStamp</code> also should not be part
2564 * of the persistent state. Unfortunately, this didn't happen before JDK 1.1
2565 * shipped. To be compatible with JDK 1.1, we will always have to write out
2566 * the field values and state flags. However, <code>nextStamp</code> can be
2567 * removed from the serialization stream; this will probably happen in the
2568 * near future.
2569 */
2570 private void writeObject(ObjectOutputStream stream)
2571 throws IOException
2572 {
2573 // Try to compute the time correctly, for the future (stream
2574 // version 2) in which we don't write out fields[] or isSet[].
2575 if (!isTimeSet) {
2576 try {
2577 updateTime();
2578 }
2579 catch (IllegalArgumentException e) {}
2580 }
2581
2582 // If this Calendar has a ZoneInfo, save it and set a
2583 // SimpleTimeZone equivalent (as a single DST schedule) for
2584 // backward compatibility.
2585 TimeZone savedZone = null;
2586 if (zone instanceof ZoneInfo) {
2587 SimpleTimeZone stz = ((ZoneInfo)zone).getLastRuleInstance();
2588 if (stz == null) {
2589 stz = new SimpleTimeZone(zone.getRawOffset(), zone.getID());
2590 }
2591 savedZone = zone;
2592 zone = stz;
2593 }
2594
2595 // Write out the 1.1 FCS object.
2596 stream.defaultWriteObject();
2597
2598 // Write out the ZoneInfo object
2599 // 4802409: we write out even if it is null, a temporary workaround
2600 // the real fix for bug 4844924 in corba-iiop
2601 stream.writeObject(savedZone);
2602 if (savedZone != null) {
2603 zone = savedZone;
2604 }
2605 }
2606
2607 private static class CalendarAccessControlContext {
2608 private static final AccessControlContext INSTANCE;
2609 static {
2610 RuntimePermission perm = new RuntimePermission("accessClassInPackage.sun.util.calendar");
2611 PermissionCollection perms = perm.newPermissionCollection();
2612 perms.add(perm);
2613 INSTANCE = new AccessControlContext(new ProtectionDomain[] {
2614 new ProtectionDomain(null, perms)
2615 });
2616 }
2617 }
2618
2619 /**
2620 * Reconstitutes this object from a stream (i.e., deserialize it).
2621 */
2622 private void readObject(ObjectInputStream stream)
2623 throws IOException, ClassNotFoundException
2624 {
2625 final ObjectInputStream input = stream;
2626 input.defaultReadObject();
2627
2628 stamp = new int[FIELD_COUNT];
2629
2630 // Starting with version 2 (not implemented yet), we expect that
2631 // fields[], isSet[], isTimeSet, and areFieldsSet may not be
2632 // streamed out anymore. We expect 'time' to be correct.
2633 if (serialVersionOnStream >= 2)
2634 {
2635 isTimeSet = true;
2636 if (fields == null) fields = new int[FIELD_COUNT];
2637 if (isSet == null) isSet = new boolean[FIELD_COUNT];
2638 }
2639 else if (serialVersionOnStream >= 0)
2640 {
2641 for (int i=0; i<FIELD_COUNT; ++i)
2642 stamp[i] = isSet[i] ? COMPUTED : UNSET;
2643 }
2644
2645 serialVersionOnStream = currentSerialVersion;
2646
2647 // If there's a ZoneInfo object, use it for zone.
2648 ZoneInfo zi = null;
2649 try {
2650 zi = AccessController.doPrivileged(
2651 new PrivilegedExceptionAction<ZoneInfo>() {
2652 public ZoneInfo run() throws Exception {
2653 return (ZoneInfo) input.readObject();
2654 }
2655 },
2656 CalendarAccessControlContext.INSTANCE);
2657 } catch (PrivilegedActionException pae) {
2658 Exception e = pae.getException();
2659 if (!(e instanceof OptionalDataException)) {
2660 if (e instanceof RuntimeException) {
2661 throw (RuntimeException) e;
2662 } else if (e instanceof IOException) {
2663 throw (IOException) e;
2664 } else if (e instanceof ClassNotFoundException) {
2665 throw (ClassNotFoundException) e;
2666 }
2667 throw new RuntimeException(e);
2668 }
2669 }
2670 if (zi != null) {
2671 zone = zi;
2672 }
2673
2674 // If the deserialized object has a SimpleTimeZone, try to
2675 // replace it with a ZoneInfo equivalent (as of 1.4) in order
2676 // to be compatible with the SimpleTimeZone-based
2677 // implementation as much as possible.
2678 if (zone instanceof SimpleTimeZone) {
2679 String id = zone.getID();
2680 TimeZone tz = TimeZone.getTimeZone(id);
2681 if (tz != null && tz.hasSameRules(zone) && tz.getID().equals(id)) {
2682 zone = tz;
2683 }
2684 }
2685 }
2686}
2687