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