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