1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.util; 19 20 import java.io.IOException; 21 import java.io.ObjectInputStream; 22 import java.io.ObjectOutputStream; 23 import java.io.ObjectStreamField; 24 import java.io.Serializable; 25 import java.text.DateFormatSymbols; 26 import libcore.icu.ICU; 27 import libcore.icu.LocaleData; 28 29 /** 30 * {@code Calendar} is an abstract base class for converting between a 31 * {@code Date} object and a set of integer fields such as 32 * {@code YEAR}, {@code MONTH}, {@code DAY}, 33 * {@code HOUR}, and so on. (A {@code Date} object represents a 34 * specific instant in time with millisecond precision. See {@link Date} for 35 * information about the {@code Date} class.) 36 * 37 * <p> 38 * Subclasses of {@code Calendar} interpret a {@code Date} 39 * according to the rules of a specific calendar system. 40 * 41 * <p> 42 * Like other locale-sensitive classes, {@code Calendar} provides a class 43 * method, {@code getInstance}, for getting a default instance of 44 * this class for general use. {@code Calendar}'s {@code getInstance} method 45 * returns a calendar whose locale is based on system settings and whose time fields 46 * have been initialized with the current date and time: <blockquote> 47 * 48 * <pre>Calendar rightNow = Calendar.getInstance()</pre> 49 * 50 * </blockquote> 51 * 52 * <p> 53 * A {@code Calendar} object can produce all the time field values needed 54 * to implement the date-time formatting for a particular language and calendar 55 * style (for example, Japanese-Gregorian, Japanese-Traditional). 56 * {@code Calendar} defines the range of values returned by certain 57 * fields, as well as their meaning. For example, the first month of the year 58 * has value {@code MONTH} == {@code JANUARY} for all calendars. 59 * Other values are defined by the concrete subclass, such as {@code ERA} 60 * and {@code YEAR}. See individual field documentation and subclass 61 * documentation for details. 62 * 63 * <p> 64 * When a {@code Calendar} is <em>lenient</em>, it accepts a wider 65 * range of field values than it produces. For example, a lenient 66 * {@code GregorianCalendar} interprets {@code MONTH} == 67 * {@code JANUARY}, {@code DAY_OF_MONTH} == 32 as February 1. A 68 * non-lenient {@code GregorianCalendar} throws an exception when given 69 * out-of-range field settings. When calendars recompute field values for return 70 * by {@code get()}, they normalize them. For example, a 71 * {@code GregorianCalendar} always produces {@code DAY_OF_MONTH} 72 * values between 1 and the length of the month. 73 * 74 * <p> 75 * {@code Calendar} defines a locale-specific seven day week using two 76 * parameters: the first day of the week and the minimal days in first week 77 * (from 1 to 7). These numbers are taken from the locale resource data when a 78 * {@code Calendar} is constructed. They may also be specified explicitly 79 * through the API. 80 * 81 * <p> 82 * When setting or getting the {@code WEEK_OF_MONTH} or 83 * {@code WEEK_OF_YEAR} fields, {@code Calendar} must determine 84 * the first week of the month or year as a reference point. The first week of a 85 * month or year is defined as the earliest seven day period beginning on 86 * {@code getFirstDayOfWeek()} and containing at least 87 * {@code getMinimalDaysInFirstWeek()} days of that month or year. Weeks 88 * numbered ..., -1, 0 precede the first week; weeks numbered 2, 3,... follow 89 * it. Note that the normalized numbering returned by {@code get()} may 90 * be different. For example, a specific {@code Calendar} subclass may 91 * designate the week before week 1 of a year as week <em>n</em> of the 92 * previous year. 93 * 94 * <p> 95 * When computing a {@code Date} from time fields, two special 96 * circumstances may arise: there may be insufficient information to compute the 97 * {@code Date} (such as only year and month but no day in the month), or 98 * there may be inconsistent information (such as "Tuesday, July 15, 1996" -- 99 * July 15, 1996 is actually a Monday). 100 * 101 * <p> 102 * <strong>Insufficient information.</strong> The calendar will use default 103 * information to specify the missing fields. This may vary by calendar; for the 104 * Gregorian calendar, the default for a field is the same as that of the start 105 * of the epoch: i.e., YEAR = 1970, MONTH = JANUARY, DATE = 1, etc. 106 * 107 * <p> 108 * <strong>Inconsistent information.</strong> If fields conflict, the calendar 109 * will give preference to fields set more recently. For example, when 110 * determining the day, the calendar will look for one of the following 111 * combinations of fields. The most recent combination, as determined by the 112 * most recently set single field, will be used. 113 * 114 * <blockquote> 115 * 116 * <pre> 117 * MONTH + DAY_OF_MONTH 118 * MONTH + WEEK_OF_MONTH + DAY_OF_WEEK 119 * MONTH + DAY_OF_WEEK_IN_MONTH + DAY_OF_WEEK 120 * DAY_OF_YEAR 121 * DAY_OF_WEEK + WEEK_OF_YEAR</pre> 122 * 123 * </blockquote> 124 * 125 * For the time of day: 126 * 127 * <blockquote> 128 * 129 * <pre> 130 * HOUR_OF_DAY 131 * AM_PM + HOUR</pre> 132 * 133 * </blockquote> 134 * 135 * <p> 136 * <strong>Note:</strong> There are certain possible ambiguities in 137 * interpretation of certain singular times, which are resolved in the following 138 * ways: 139 * <ol> 140 * <li> 24:00:00 "belongs" to the following day. That is, 23:59 on Dec 31, 1969 141 * < 24:00 on Jan 1, 1970 < 24:01:00 on Jan 1, 1970 form a sequence of 142 * three consecutive minutes in time. 143 * 144 * <li> Although historically not precise, midnight also belongs to "am", and 145 * noon belongs to "pm", so on the same day, we have 12:00 am (midnight) < 12:01 am, 146 * and 12:00 pm (noon) < 12:01 pm 147 * </ol> 148 * 149 * <p> 150 * The date or time format strings are not part of the definition of a calendar, 151 * as those must be modifiable or overridable by the user at runtime. Use 152 * {@link java.text.DateFormat} to format dates. 153 * 154 * <p> 155 * <strong>Field manipulation methods</strong> 156 * 157 * <p> 158 * {@code Calendar} fields can be changed using three methods: 159 * {@code set()}, {@code add()}, and {@code roll()}. 160 * 161 * <p> 162 * <strong>{@code set(f, value)}</strong> changes field {@code f} 163 * to {@code value}. In addition, it sets an internal member variable to 164 * indicate that field {@code f} has been changed. Although field 165 * {@code f} is changed immediately, the calendar's milliseconds is not 166 * recomputed until the next call to {@code get()}, 167 * {@code getTime()}, or {@code getTimeInMillis()} is made. Thus, 168 * multiple calls to {@code set()} do not trigger multiple, unnecessary 169 * computations. As a result of changing a field using {@code set()}, 170 * other fields may also change, depending on the field, the field value, and 171 * the calendar system. In addition, {@code get(f)} will not necessarily 172 * return {@code value} after the fields have been recomputed. The 173 * specifics are determined by the concrete calendar class. 174 * 175 * <p> 176 * <em>Example</em>: Consider a {@code GregorianCalendar} originally 177 * set to August 31, 1999. Calling <code>set(Calendar.MONTH, 178 * Calendar.SEPTEMBER)</code> 179 * sets the calendar to September 31, 1999. This is a temporary internal 180 * representation that resolves to October 1, 1999 if {@code getTime()}is 181 * then called. However, a call to {@code set(Calendar.DAY_OF_MONTH, 30)} 182 * before the call to {@code getTime()} sets the calendar to September 183 * 30, 1999, since no recomputation occurs after {@code set()} itself. 184 * 185 * <p> 186 * <strong>{@code add(f, delta)}</strong> adds {@code delta} to 187 * field {@code f}. This is equivalent to calling <code>set(f, 188 * get(f) + delta)</code> 189 * with two adjustments: 190 * 191 * <blockquote> 192 * <p> 193 * <strong>Add rule 1</strong>. The value of field {@code f} after the 194 * call minus the value of field {@code f} before the call is 195 * {@code delta}, modulo any overflow that has occurred in field 196 * {@code f}. Overflow occurs when a field value exceeds its range and, 197 * as a result, the next larger field is incremented or decremented and the 198 * field value is adjusted back into its range. 199 * 200 * <p> 201 * <strong>Add rule 2</strong>. If a smaller field is expected to be invariant, 202 * but it is impossible for it to be equal to its prior value because of 203 * changes in its minimum or maximum after field {@code f} is changed, 204 * then its value is adjusted to be as close as possible to its expected value. 205 * A smaller field represents a smaller unit of time. {@code HOUR} is a 206 * smaller field than {@code DAY_OF_MONTH}. No adjustment is made to 207 * smaller fields that are not expected to be invariant. The calendar system 208 * determines what fields are expected to be invariant. 209 * </blockquote> 210 * 211 * <p> 212 * In addition, unlike {@code set()}, {@code add()} forces an 213 * immediate recomputation of the calendar's milliseconds and all fields. 214 * 215 * <p> 216 * <em>Example</em>: Consider a {@code GregorianCalendar} originally 217 * set to August 31, 1999. Calling {@code add(Calendar.MONTH, 13)} sets 218 * the calendar to September 30, 2000. <strong>Add rule 1</strong> sets the 219 * {@code MONTH} field to September, since adding 13 months to August 220 * gives September of the next year. Since {@code DAY_OF_MONTH} cannot be 221 * 31 in September in a {@code GregorianCalendar}, <strong>add rule 2</strong> 222 * sets the {@code DAY_OF_MONTH} to 30, the closest possible value. 223 * Although it is a smaller field, {@code DAY_OF_WEEK} is not adjusted by 224 * rule 2, since it is expected to change when the month changes in a 225 * {@code GregorianCalendar}. 226 * 227 * <p> 228 * <strong>{@code roll(f, delta)}</strong> adds {@code delta} to 229 * field {@code f} without changing larger fields. This is equivalent to 230 * calling {@code add(f, delta)} with the following adjustment: 231 * 232 * <blockquote> 233 * <p> 234 * <strong>Roll rule</strong>. Larger fields are unchanged after the call. A 235 * larger field represents a larger unit of time. {@code DAY_OF_MONTH} is 236 * a larger field than {@code HOUR}. 237 * </blockquote> 238 * 239 * <p> 240 * <em>Example</em>: Consider a {@code GregorianCalendar} originally 241 * set to August 31, 1999. Calling <code>roll(Calendar.MONTH, 242 * 8)</code> sets 243 * the calendar to April 30, <strong>1999</strong>. Add rule 1 sets the 244 * {@code MONTH} field to April. Using a {@code GregorianCalendar}, 245 * the {@code DAY_OF_MONTH} cannot be 31 in the month April. Add rule 2 246 * sets it to the closest possible value, 30. Finally, the <strong>roll rule</strong> 247 * maintains the {@code YEAR} field value of 1999. 248 * 249 * <p> 250 * <em>Example</em>: Consider a {@code GregorianCalendar} originally 251 * set to Sunday June 6, 1999. Calling 252 * {@code roll(Calendar.WEEK_OF_MONTH, -1)} sets the calendar to Tuesday 253 * June 1, 1999, whereas calling {@code add(Calendar.WEEK_OF_MONTH, -1)} 254 * sets the calendar to Sunday May 30, 1999. This is because the roll rule 255 * imposes an additional constraint: The {@code MONTH} must not change 256 * when the {@code WEEK_OF_MONTH} is rolled. Taken together with add rule 257 * 1, the resultant date must be between Tuesday June 1 and Saturday June 5. 258 * According to add rule 2, the {@code DAY_OF_WEEK}, an invariant when 259 * changing the {@code WEEK_OF_MONTH}, is set to Tuesday, the closest 260 * possible value to Sunday (where Sunday is the first day of the week). 261 * 262 * <p> 263 * <strong>Usage model</strong>. To motivate the behavior of {@code add()} 264 * and {@code roll()}, consider a user interface component with 265 * increment and decrement buttons for the month, day, and year, and an 266 * underlying {@code GregorianCalendar}. If the interface reads January 267 * 31, 1999 and the user presses the month increment button, what should it 268 * read? If the underlying implementation uses {@code set()}, it might 269 * read March 3, 1999. A better result would be February 28, 1999. Furthermore, 270 * if the user presses the month increment button again, it should read March 271 * 31, 1999, not March 28, 1999. By saving the original date and using either 272 * {@code add()} or {@code roll()}, depending on whether larger 273 * fields should be affected, the user interface can behave as most users will 274 * intuitively expect. 275 * 276 * <p> 277 * <b>Note:</b> You should always use {@code roll} and {@code add} rather than 278 * attempting to perform arithmetic operations directly on the fields of a 279 * <tt>Calendar</tt>. It is quite possible for <tt>Calendar</tt> subclasses 280 * to have fields with non-linear behavior, for example missing months or days 281 * during non-leap years. The subclasses' <tt>add</tt> and <tt>roll</tt> 282 * methods will take this into account, while simple arithmetic manipulations 283 * may give invalid results. 284 * 285 * @see Date 286 * @see GregorianCalendar 287 * @see TimeZone 288 */ 289 public abstract class Calendar implements Serializable, Cloneable, Comparable<Calendar> { 290 291 private static final long serialVersionUID = -1807547505821590642L; 292 293 /** 294 * True iff the values in {@code fields[]} correspond to {@code time}. Despite the name, this 295 * is effectively "are the values in fields[] up-to-date?" --- {@code fields[]} may contain 296 * non-zero values and {@code isSet[]} may contain {@code true} values even when 297 * {@code areFieldsSet} is false. 298 * Accessing the fields via {@code get} will ensure the fields are up-to-date. 299 */ 300 protected boolean areFieldsSet; 301 302 /** 303 * Contains broken-down field values for the current value of {@code time} if 304 * {@code areFieldsSet} is true, or stale data corresponding to some previous value otherwise. 305 * Accessing the fields via {@code get} will ensure the fields are up-to-date. 306 * The array length is always {@code FIELD_COUNT}. 307 */ 308 protected int[] fields; 309 310 /** 311 * Whether the corresponding element in {@code field[]} has been set. Initially, these are all 312 * false. The first time the fields are computed, these are set to true and remain set even if 313 * the data becomes stale: you <i>must</i> check {@code areFieldsSet} if you want to know 314 * whether the value is up-to-date. 315 * Note that {@code isSet} is <i>not</i> a safe alternative to accessing this array directly, 316 * and will likewise return stale data! 317 * The array length is always {@code FIELD_COUNT}. 318 */ 319 protected boolean[] isSet; 320 321 /** 322 * Whether {@code time} corresponds to the values in {@code fields[]}. If false, {@code time} 323 * is out-of-date with respect to changes {@code fields[]}. 324 * Accessing the time via {@code getTimeInMillis} will always return the correct value. 325 */ 326 protected boolean isTimeSet; 327 328 /** 329 * A time in milliseconds since January 1, 1970. See {@code isTimeSet}. 330 * Accessing the time via {@code getTimeInMillis} will always return the correct value. 331 */ 332 protected long time; 333 334 transient int lastTimeFieldSet; 335 336 transient int lastDateFieldSet; 337 338 private boolean lenient; 339 340 private int firstDayOfWeek; 341 342 private int minimalDaysInFirstWeek; 343 344 private TimeZone zone; 345 346 /** 347 * Value of the {@code MONTH} field indicating the first month of the 348 * year. 349 */ 350 public static final int JANUARY = 0; 351 352 /** 353 * Value of the {@code MONTH} field indicating the second month of 354 * the year. 355 */ 356 public static final int FEBRUARY = 1; 357 358 /** 359 * Value of the {@code MONTH} field indicating the third month of the 360 * year. 361 */ 362 public static final int MARCH = 2; 363 364 /** 365 * Value of the {@code MONTH} field indicating the fourth month of 366 * the year. 367 */ 368 public static final int APRIL = 3; 369 370 /** 371 * Value of the {@code MONTH} field indicating the fifth month of the 372 * year. 373 */ 374 public static final int MAY = 4; 375 376 /** 377 * Value of the {@code MONTH} field indicating the sixth month of the 378 * year. 379 */ 380 public static final int JUNE = 5; 381 382 /** 383 * Value of the {@code MONTH} field indicating the seventh month of 384 * the year. 385 */ 386 public static final int JULY = 6; 387 388 /** 389 * Value of the {@code MONTH} field indicating the eighth month of 390 * the year. 391 */ 392 public static final int AUGUST = 7; 393 394 /** 395 * Value of the {@code MONTH} field indicating the ninth month of the 396 * year. 397 */ 398 public static final int SEPTEMBER = 8; 399 400 /** 401 * Value of the {@code MONTH} field indicating the tenth month of the 402 * year. 403 */ 404 public static final int OCTOBER = 9; 405 406 /** 407 * Value of the {@code MONTH} field indicating the eleventh month of 408 * the year. 409 */ 410 public static final int NOVEMBER = 10; 411 412 /** 413 * Value of the {@code MONTH} field indicating the twelfth month of 414 * the year. 415 */ 416 public static final int DECEMBER = 11; 417 418 /** 419 * Value of the {@code MONTH} field indicating the thirteenth month 420 * of the year. Although {@code GregorianCalendar} does not use this 421 * value, lunar calendars do. 422 */ 423 public static final int UNDECIMBER = 12; 424 425 /** 426 * Value of the {@code DAY_OF_WEEK} field indicating Sunday. 427 */ 428 public static final int SUNDAY = 1; 429 430 /** 431 * Value of the {@code DAY_OF_WEEK} field indicating Monday. 432 */ 433 public static final int MONDAY = 2; 434 435 /** 436 * Value of the {@code DAY_OF_WEEK} field indicating Tuesday. 437 */ 438 public static final int TUESDAY = 3; 439 440 /** 441 * Value of the {@code DAY_OF_WEEK} field indicating Wednesday. 442 */ 443 public static final int WEDNESDAY = 4; 444 445 /** 446 * Value of the {@code DAY_OF_WEEK} field indicating Thursday. 447 */ 448 public static final int THURSDAY = 5; 449 450 /** 451 * Value of the {@code DAY_OF_WEEK} field indicating Friday. 452 */ 453 public static final int FRIDAY = 6; 454 455 /** 456 * Value of the {@code DAY_OF_WEEK} field indicating Saturday. 457 */ 458 public static final int SATURDAY = 7; 459 460 /** 461 * Field number for {@code get} and {@code set} indicating the 462 * era, e.g., AD or BC in the Julian calendar. This is a calendar-specific 463 * value; see subclass documentation. 464 * 465 * @see GregorianCalendar#AD 466 * @see GregorianCalendar#BC 467 */ 468 public static final int ERA = 0; 469 470 /** 471 * Field number for {@code get} and {@code set} indicating the 472 * year. This is a calendar-specific value; see subclass documentation. 473 */ 474 public static final int YEAR = 1; 475 476 /** 477 * Field number for {@code get} and {@code set} indicating the 478 * month. This is a calendar-specific value. The first month of the year is 479 * {@code JANUARY}; the last depends on the number of months in a 480 * year. 481 * 482 * @see #JANUARY 483 * @see #FEBRUARY 484 * @see #MARCH 485 * @see #APRIL 486 * @see #MAY 487 * @see #JUNE 488 * @see #JULY 489 * @see #AUGUST 490 * @see #SEPTEMBER 491 * @see #OCTOBER 492 * @see #NOVEMBER 493 * @see #DECEMBER 494 * @see #UNDECIMBER 495 */ 496 public static final int MONTH = 2; 497 498 /** 499 * Field number for {@code get} and {@code set} indicating the 500 * week number within the current year. The first week of the year, as 501 * defined by {@code getFirstDayOfWeek()} and 502 * {@code getMinimalDaysInFirstWeek()}, has value 1. Subclasses 503 * define the value of {@code WEEK_OF_YEAR} for days before the first 504 * week of the year. 505 * 506 * @see #getFirstDayOfWeek 507 * @see #getMinimalDaysInFirstWeek 508 */ 509 public static final int WEEK_OF_YEAR = 3; 510 511 /** 512 * Field number for {@code get} and {@code set} indicating the 513 * week number within the current month. The first week of the month, as 514 * defined by {@code getFirstDayOfWeek()} and 515 * {@code getMinimalDaysInFirstWeek()}, has value 1. Subclasses 516 * define the value of {@code WEEK_OF_MONTH} for days before the 517 * first week of the month. 518 * 519 * @see #getFirstDayOfWeek 520 * @see #getMinimalDaysInFirstWeek 521 */ 522 public static final int WEEK_OF_MONTH = 4; 523 524 /** 525 * Field number for {@code get} and {@code set} indicating the 526 * day of the month. This is a synonym for {@code DAY_OF_MONTH}. The 527 * first day of the month has value 1. 528 * 529 * @see #DAY_OF_MONTH 530 */ 531 public static final int DATE = 5; 532 533 /** 534 * Field number for {@code get} and {@code set} indicating the 535 * day of the month. This is a synonym for {@code DATE}. The first 536 * day of the month has value 1. 537 * 538 * @see #DATE 539 */ 540 public static final int DAY_OF_MONTH = 5; 541 542 /** 543 * Field number for {@code get} and {@code set} indicating the 544 * day number within the current year. The first day of the year has value 545 * 1. 546 */ 547 public static final int DAY_OF_YEAR = 6; 548 549 /** 550 * Field number for {@code get} and {@code set} indicating the 551 * day of the week. This field takes values {@code SUNDAY}, 552 * {@code MONDAY}, {@code TUESDAY}, {@code WEDNESDAY}, 553 * {@code THURSDAY}, {@code FRIDAY}, and 554 * {@code SATURDAY}. 555 * 556 * @see #SUNDAY 557 * @see #MONDAY 558 * @see #TUESDAY 559 * @see #WEDNESDAY 560 * @see #THURSDAY 561 * @see #FRIDAY 562 * @see #SATURDAY 563 */ 564 public static final int DAY_OF_WEEK = 7; 565 566 /** 567 * Field number for {@code get} and {@code set} indicating the 568 * ordinal number of the day of the week within the current month. Together 569 * with the {@code DAY_OF_WEEK} field, this uniquely specifies a day 570 * within a month. Unlike {@code WEEK_OF_MONTH} and 571 * {@code WEEK_OF_YEAR}, this field's value does <em>not</em> 572 * depend on {@code getFirstDayOfWeek()} or 573 * {@code getMinimalDaysInFirstWeek()}. {@code DAY_OF_MONTH 1} 574 * through {@code 7} always correspond to <code>DAY_OF_WEEK_IN_MONTH 575 * 1</code>; 576 * {@code 8} through {@code 15} correspond to 577 * {@code DAY_OF_WEEK_IN_MONTH 2}, and so on. 578 * {@code DAY_OF_WEEK_IN_MONTH 0} indicates the week before 579 * {@code DAY_OF_WEEK_IN_MONTH 1}. Negative values count back from 580 * the end of the month, so the last Sunday of a month is specified as 581 * {@code DAY_OF_WEEK = SUNDAY, DAY_OF_WEEK_IN_MONTH = -1}. Because 582 * negative values count backward they will usually be aligned differently 583 * within the month than positive values. For example, if a month has 31 584 * days, {@code DAY_OF_WEEK_IN_MONTH -1} will overlap 585 * {@code DAY_OF_WEEK_IN_MONTH 5} and the end of {@code 4}. 586 * 587 * @see #DAY_OF_WEEK 588 * @see #WEEK_OF_MONTH 589 */ 590 public static final int DAY_OF_WEEK_IN_MONTH = 8; 591 592 /** 593 * Field number for {@code get} and {@code set} indicating 594 * whether the {@code HOUR} is before or after noon. E.g., at 595 * 10:04:15.250 PM the {@code AM_PM} is {@code PM}. 596 * 597 * @see #AM 598 * @see #PM 599 * @see #HOUR 600 */ 601 public static final int AM_PM = 9; 602 603 /** 604 * Field number for {@code get} and {@code set} indicating the 605 * hour of the morning or afternoon. {@code HOUR} is used for the 606 * 12-hour clock. E.g., at 10:04:15.250 PM the {@code HOUR} is 10. 607 * 608 * @see #AM_PM 609 * @see #HOUR_OF_DAY 610 */ 611 public static final int HOUR = 10; 612 613 /** 614 * Field number for {@code get} and {@code set} indicating the 615 * hour of the day. {@code HOUR_OF_DAY} is used for the 24-hour 616 * clock. E.g., at 10:04:15.250 PM the {@code HOUR_OF_DAY} is 22. 617 * 618 * @see #HOUR 619 */ 620 public static final int HOUR_OF_DAY = 11; 621 622 /** 623 * Field number for {@code get} and {@code set} indicating the 624 * minute within the hour. E.g., at 10:04:15.250 PM the {@code MINUTE} 625 * is 4. 626 */ 627 public static final int MINUTE = 12; 628 629 /** 630 * Field number for {@code get} and {@code set} indicating the 631 * second within the minute. E.g., at 10:04:15.250 PM the 632 * {@code SECOND} is 15. 633 */ 634 public static final int SECOND = 13; 635 636 /** 637 * Field number for {@code get} and {@code set} indicating the 638 * millisecond within the second. E.g., at 10:04:15.250 PM the 639 * {@code MILLISECOND} is 250. 640 */ 641 public static final int MILLISECOND = 14; 642 643 /** 644 * Field number for {@code get} and {@code set} indicating the 645 * raw (non-DST) offset from GMT in milliseconds. 646 * Equivalent to {@link java.util.TimeZone#getRawOffset}. 647 * 648 * <p>To determine the total offset from GMT at the time represented 649 * by this calendar, you will need to add the {@code ZONE_OFFSET} and 650 * {@code DST_OFFSET} fields. 651 */ 652 public static final int ZONE_OFFSET = 15; 653 654 /** 655 * Field number for {@code get} and {@code set} indicating the 656 * daylight savings offset from the {@code ZONE_OFFSET} in milliseconds. 657 * Equivalent to {@link java.util.TimeZone#getDSTSavings} if the represented time 658 * falls inside DST, or 0 otherwise. 659 * 660 * <p>To determine the total offset from GMT at the time represented 661 * by this calendar, you will need to add the {@code ZONE_OFFSET} and 662 * {@code DST_OFFSET} fields. 663 */ 664 public static final int DST_OFFSET = 16; 665 666 /** 667 * This is the total number of fields in this calendar. 668 */ 669 public static final int FIELD_COUNT = 17; 670 671 /** 672 * Value of the {@code AM_PM} field indicating the period of the day 673 * from midnight to just before noon. 674 */ 675 public static final int AM = 0; 676 677 /** 678 * Value of the {@code AM_PM} field indicating the period of the day 679 * from noon to just before midnight. 680 */ 681 public static final int PM = 1; 682 683 /** 684 * Requests both {@code SHORT} and {@code LONG} styles in the map returned by 685 * {@link #getDisplayNames}. 686 * @since 1.6 687 */ 688 public static final int ALL_STYLES = 0; 689 690 /** 691 * Requests short names (such as "Jan") from 692 * {@link #getDisplayName} or {@link #getDisplayNames}. 693 * @since 1.6 694 */ 695 public static final int SHORT = 1; 696 697 /** 698 * Requests long names (such as "January") from 699 * {@link #getDisplayName} or {@link #getDisplayNames}. 700 * @since 1.6 701 */ 702 public static final int LONG = 2; 703 704 private static final String[] FIELD_NAMES = { "ERA", "YEAR", "MONTH", 705 "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH", "DAY_OF_YEAR", 706 "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", 707 "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", 708 "ZONE_OFFSET", "DST_OFFSET" }; 709 710 /** 711 * Constructs a {@code Calendar} instance using the default {@code TimeZone} and {@code Locale}. 712 */ 713 protected Calendar() { 714 this(TimeZone.getDefault(), Locale.getDefault()); 715 } 716 717 Calendar(TimeZone timezone) { 718 fields = new int[FIELD_COUNT]; 719 isSet = new boolean[FIELD_COUNT]; 720 areFieldsSet = isTimeSet = false; 721 setLenient(true); 722 setTimeZone(timezone); 723 } 724 725 /** 726 * Constructs a {@code Calendar} instance using the given {@code TimeZone} and {@code Locale}. 727 */ 728 protected Calendar(TimeZone timezone, Locale locale) { 729 this(timezone); 730 locale = LocaleData.mapInvalidAndNullLocales(locale); 731 LocaleData localeData = LocaleData.get(locale); 732 setFirstDayOfWeek(localeData.firstDayOfWeek.intValue()); 733 setMinimalDaysInFirstWeek(localeData.minimalDaysInFirstWeek.intValue()); 734 } 735 736 737 /** 738 * Adds the given amount to a {@code Calendar} field. 739 * 740 * @param field 741 * the {@code Calendar} field to modify. 742 * @param value 743 * the amount to add to the field. 744 * @throws IllegalArgumentException 745 * if {@code field} is {@code DST_OFFSET} or {@code 746 * ZONE_OFFSET}. 747 */ 748 public abstract void add(int field, int value); 749 750 /** 751 * Returns whether the {@code Date} represented by this {@code Calendar} instance is after the {@code Date} 752 * represented by the parameter. The comparison is not dependent on the time 753 * zones of the {@code Calendar}. 754 * 755 * @param calendar 756 * the {@code Calendar} instance to compare. 757 * @return {@code true} when this Calendar is after calendar, {@code false} otherwise. 758 * @throws IllegalArgumentException 759 * if the time is not set and the time cannot be computed 760 * from the current field values. 761 */ 762 public boolean after(Object calendar) { 763 if (!(calendar instanceof Calendar)) { 764 return false; 765 } 766 return getTimeInMillis() > ((Calendar) calendar).getTimeInMillis(); 767 } 768 769 /** 770 * Returns whether the {@code Date} represented by this {@code Calendar} instance is before the 771 * {@code Date} represented by the parameter. The comparison is not dependent on the 772 * time zones of the {@code Calendar}. 773 * 774 * @param calendar 775 * the {@code Calendar} instance to compare. 776 * @return {@code true} when this Calendar is before calendar, {@code false} otherwise. 777 * @throws IllegalArgumentException 778 * if the time is not set and the time cannot be computed 779 * from the current field values. 780 */ 781 public boolean before(Object calendar) { 782 if (!(calendar instanceof Calendar)) { 783 return false; 784 } 785 return getTimeInMillis() < ((Calendar) calendar).getTimeInMillis(); 786 } 787 788 /** 789 * Clears the values of all the time fields, marking them all unset and assigning 790 * them all a value of zero. The actual field values will be determined the next 791 * time the fields are accessed. 792 */ 793 public final void clear() { 794 for (int i = 0; i < FIELD_COUNT; i++) { 795 fields[i] = 0; 796 isSet[i] = false; 797 } 798 areFieldsSet = isTimeSet = false; 799 } 800 801 /** 802 * Clears the value in the given time field, marking it unset and assigning 803 * it a value of zero. The actual field value will be determined the next 804 * time the field is accessed. 805 */ 806 public final void clear(int field) { 807 fields[field] = 0; 808 isSet[field] = false; 809 areFieldsSet = isTimeSet = false; 810 } 811 812 /** 813 * Returns a partially deep copy of this {@code Calendar}; all fields from 814 * from the {@code Calendar} class are cloned (deep copy) but fields from 815 * subclasses aren't (shallow copy). 816 */ 817 @Override 818 public Object clone() { 819 try { 820 Calendar clone = (Calendar) super.clone(); 821 clone.fields = fields.clone(); 822 clone.isSet = isSet.clone(); 823 clone.zone = (TimeZone) zone.clone(); 824 return clone; 825 } catch (CloneNotSupportedException e) { 826 throw new AssertionError(e); 827 } 828 } 829 830 /** 831 * Computes the time from the fields if the time has not already been set. 832 * Computes the fields from the time if the fields are not already set. 833 * 834 * @throws IllegalArgumentException 835 * if the time is not set and the time cannot be computed 836 * from the current field values. 837 */ 838 protected void complete() { 839 if (!isTimeSet) { 840 computeTime(); 841 isTimeSet = true; 842 } 843 if (!areFieldsSet) { 844 computeFields(); 845 areFieldsSet = true; 846 } 847 } 848 849 /** 850 * Computes the {@code Calendar} fields from {@code time}. 851 */ 852 protected abstract void computeFields(); 853 854 /** 855 * Computes {@code time} from the Calendar fields. 856 * 857 * @throws IllegalArgumentException 858 * if the time cannot be computed from the current field 859 * values. 860 */ 861 protected abstract void computeTime(); 862 863 /** 864 * Compares the given object to this {@code Calendar} and returns whether they are 865 * equal. The object must be an instance of {@code Calendar} and have the same 866 * properties. 867 * 868 * @return {@code true} if the given object is equal to this {@code Calendar}, {@code false} 869 * otherwise. 870 */ 871 @Override 872 public boolean equals(Object object) { 873 if (this == object) { 874 return true; 875 } 876 if (!(object instanceof Calendar)) { 877 return false; 878 } 879 Calendar cal = (Calendar) object; 880 return getTimeInMillis() == cal.getTimeInMillis() 881 && isLenient() == cal.isLenient() 882 && getFirstDayOfWeek() == cal.getFirstDayOfWeek() 883 && getMinimalDaysInFirstWeek() == cal.getMinimalDaysInFirstWeek() 884 && getTimeZone().equals(cal.getTimeZone()); 885 } 886 887 /** 888 * Returns the value of the given field after computing the field values by 889 * calling {@code complete()} first. 890 * 891 * @throws IllegalArgumentException 892 * if the fields are not set, the time is not set, and the 893 * time cannot be computed from the current field values. 894 * @throws ArrayIndexOutOfBoundsException 895 * if the field is not inside the range of possible fields. 896 * The range is starting at 0 up to {@code FIELD_COUNT}. 897 */ 898 public int get(int field) { 899 complete(); 900 return fields[field]; 901 } 902 903 /** 904 * Returns the maximum value of the given field for the current date. 905 * For example, the maximum number of days in the current month. 906 */ 907 public int getActualMaximum(int field) { 908 int value, next; 909 if (getMaximum(field) == (next = getLeastMaximum(field))) { 910 return next; 911 } 912 complete(); 913 long orgTime = time; 914 set(field, next); 915 do { 916 value = next; 917 roll(field, true); 918 next = get(field); 919 } while (next > value); 920 time = orgTime; 921 areFieldsSet = false; 922 return value; 923 } 924 925 /** 926 * Returns the minimum value of the given field for the current date. 927 */ 928 public int getActualMinimum(int field) { 929 int value, next; 930 if (getMinimum(field) == (next = getGreatestMinimum(field))) { 931 return next; 932 } 933 complete(); 934 long orgTime = time; 935 set(field, next); 936 do { 937 value = next; 938 roll(field, false); 939 next = get(field); 940 } while (next < value); 941 time = orgTime; 942 areFieldsSet = false; 943 return value; 944 } 945 946 /** 947 * Returns an array of locales for which custom {@code Calendar} instances 948 * are available. 949 * <p>Note that Android does not support user-supplied locale service providers. 950 */ 951 public static synchronized Locale[] getAvailableLocales() { 952 return ICU.getAvailableCalendarLocales(); 953 } 954 955 /** 956 * Returns the first day of the week for this {@code Calendar}. 957 */ 958 public int getFirstDayOfWeek() { 959 return firstDayOfWeek; 960 } 961 962 /** 963 * Returns the greatest minimum value of the given field. This is the 964 * biggest value that {@code getActualMinimum} can return for any possible 965 * time. 966 */ 967 public abstract int getGreatestMinimum(int field); 968 969 /** 970 * Constructs a new instance of the {@code Calendar} subclass appropriate for the 971 * default {@code Locale} and default {@code TimeZone}, set to the current date and time. 972 */ 973 public static synchronized Calendar getInstance() { 974 return new GregorianCalendar(); 975 } 976 977 /** 978 * Constructs a new instance of the {@code Calendar} subclass appropriate for the 979 * given {@code Locale} and default {@code TimeZone}, set to the current date and time. 980 */ 981 public static synchronized Calendar getInstance(Locale locale) { 982 return new GregorianCalendar(locale); 983 } 984 985 /** 986 * Constructs a new instance of the {@code Calendar} subclass appropriate for the 987 * default {@code Locale} and given {@code TimeZone}, set to the current date and time. 988 */ 989 public static synchronized Calendar getInstance(TimeZone timezone) { 990 return new GregorianCalendar(timezone); 991 } 992 993 /** 994 * Constructs a new instance of the {@code Calendar} subclass appropriate for the 995 * given {@code Locale} and given {@code TimeZone}, set to the current date and time. 996 */ 997 public static synchronized Calendar getInstance(TimeZone timezone, Locale locale) { 998 return new GregorianCalendar(timezone, locale); 999 } 1000 1001 /** 1002 * Returns the smallest maximum value of the given field. This is the 1003 * smallest value that {@code getActualMaximum()} can return for any 1004 * possible time. 1005 */ 1006 public abstract int getLeastMaximum(int field); 1007 1008 /** 1009 * Returns the greatest maximum value of the given field. This returns the 1010 * biggest value that {@code get} can return for the given field. 1011 */ 1012 public abstract int getMaximum(int field); 1013 1014 /** 1015 * Returns the minimal days in the first week of the year. 1016 */ 1017 public int getMinimalDaysInFirstWeek() { 1018 return minimalDaysInFirstWeek; 1019 } 1020 1021 /** 1022 * Returns the smallest minimum value of the given field. this returns the 1023 * smallest value that {@code get} can return for the given field. 1024 */ 1025 public abstract int getMinimum(int field); 1026 1027 /** 1028 * Returns the time of this {@code Calendar} as a {@code Date} object. 1029 * 1030 * @throws IllegalArgumentException 1031 * if the time is not set and the time cannot be computed 1032 * from the current field values. 1033 */ 1034 public final Date getTime() { 1035 return new Date(getTimeInMillis()); 1036 } 1037 1038 /** 1039 * Returns the time represented by this {@code Calendar}, recomputing the time from its 1040 * fields if necessary. 1041 * 1042 * @throws IllegalArgumentException 1043 * if the time is not set and the time cannot be computed 1044 * from the current field values. 1045 */ 1046 public long getTimeInMillis() { 1047 if (!isTimeSet) { 1048 computeTime(); 1049 isTimeSet = true; 1050 } 1051 return time; 1052 } 1053 1054 /** 1055 * Returns the time zone used by this {@code Calendar}. 1056 */ 1057 public TimeZone getTimeZone() { 1058 return zone; 1059 } 1060 1061 @Override 1062 public int hashCode() { 1063 return (isLenient() ? 1237 : 1231) + getFirstDayOfWeek() 1064 + getMinimalDaysInFirstWeek() + getTimeZone().hashCode(); 1065 } 1066 1067 /** 1068 * Returns the value of the given field without recomputing. 1069 */ 1070 protected final int internalGet(int field) { 1071 return fields[field]; 1072 } 1073 1074 /** 1075 * Tests whether this {@code Calendar} accepts field values which are outside the valid 1076 * range for the field. 1077 */ 1078 public boolean isLenient() { 1079 return lenient; 1080 } 1081 1082 /** 1083 * Tests whether the given field is set. Note that the interpretation of "is set" is 1084 * somewhat technical. In particular, it does <i>not</i> mean that the field's value is up 1085 * to date. If you want to know whether a field contains an up-to-date value, you must also 1086 * check {@code areFieldsSet}, making this method somewhat useless unless you're a subclass, 1087 * in which case you can access the {@code isSet} array directly. 1088 * <p> 1089 * A field remains "set" from the first time its value is computed until it's cleared by one 1090 * of the {@code clear} methods. Thus "set" does not mean "valid". You probably want to call 1091 * {@code get} -- which will update fields as necessary -- rather than try to make use of 1092 * this method. 1093 */ 1094 public final boolean isSet(int field) { 1095 return isSet[field]; 1096 } 1097 1098 /** 1099 * Adds the given amount to the given field and wraps the value of 1100 * the field when it goes beyond the maximum or minimum value for the 1101 * current date. Other fields will be adjusted as required to maintain a 1102 * consistent date. 1103 */ 1104 public void roll(int field, int value) { 1105 boolean increment = value >= 0; 1106 int count = increment ? value : -value; 1107 for (int i = 0; i < count; i++) { 1108 roll(field, increment); 1109 } 1110 } 1111 1112 /** 1113 * Increment or decrement the given field and wrap the value of the 1114 * field when it goes beyond the maximum or minimum value for the current 1115 * date. Other fields will be adjusted as required to maintain a consistent 1116 * date. 1117 */ 1118 public abstract void roll(int field, boolean increment); 1119 1120 /** 1121 * Sets the given field to the given value. 1122 */ 1123 public void set(int field, int value) { 1124 fields[field] = value; 1125 isSet[field] = true; 1126 areFieldsSet = isTimeSet = false; 1127 if (field > MONTH && field < AM_PM) { 1128 lastDateFieldSet = field; 1129 } 1130 if (field == HOUR || field == HOUR_OF_DAY) { 1131 lastTimeFieldSet = field; 1132 } 1133 if (field == AM_PM) { 1134 lastTimeFieldSet = HOUR; 1135 } 1136 } 1137 1138 /** 1139 * Sets the year, month, and day of the month fields. 1140 * Other fields are not changed; call {@link #clear} first if this is not desired. 1141 * The month value is 0-based, so it may be clearer to use a constant like {@code JANUARY}. 1142 */ 1143 public final void set(int year, int month, int day) { 1144 set(YEAR, year); 1145 set(MONTH, month); 1146 set(DATE, day); 1147 } 1148 1149 /** 1150 * Sets the year, month, day of the month, hour of day, and minute fields. 1151 * Other fields are not changed; call {@link #clear} first if this is not desired. 1152 * The month value is 0-based, so it may be clearer to use a constant like {@code JANUARY}. 1153 */ 1154 public final void set(int year, int month, int day, int hourOfDay, int minute) { 1155 set(year, month, day); 1156 set(HOUR_OF_DAY, hourOfDay); 1157 set(MINUTE, minute); 1158 } 1159 1160 /** 1161 * Sets the year, month, day of the month, hour of day, minute, and second fields. 1162 * Other fields are not changed; call {@link #clear} first if this is not desired. 1163 * The month value is 0-based, so it may be clearer to use a constant like {@code JANUARY}. 1164 */ 1165 public final void set(int year, int month, int day, int hourOfDay, int minute, int second) { 1166 set(year, month, day, hourOfDay, minute); 1167 set(SECOND, second); 1168 } 1169 1170 /** 1171 * Sets the first day of the week for this {@code Calendar}. 1172 * The value should be a day of the week such as {@code MONDAY}. 1173 */ 1174 public void setFirstDayOfWeek(int value) { 1175 firstDayOfWeek = value; 1176 } 1177 1178 /** 1179 * Sets whether this {@code Calendar} accepts field values which are outside the valid 1180 * range for the field. 1181 */ 1182 public void setLenient(boolean value) { 1183 lenient = value; 1184 } 1185 1186 /** 1187 * Sets the minimal days in the first week of the year. 1188 */ 1189 public void setMinimalDaysInFirstWeek(int value) { 1190 minimalDaysInFirstWeek = value; 1191 } 1192 1193 /** 1194 * Sets the time of this {@code Calendar}. 1195 */ 1196 public final void setTime(Date date) { 1197 setTimeInMillis(date.getTime()); 1198 } 1199 1200 /** 1201 * Sets the time of this {@code Calendar} to the given Unix time. See {@link Date} for more 1202 * about what this means. 1203 */ 1204 public void setTimeInMillis(long milliseconds) { 1205 if (!isTimeSet || !areFieldsSet || time != milliseconds) { 1206 time = milliseconds; 1207 isTimeSet = true; 1208 areFieldsSet = false; 1209 complete(); 1210 } 1211 } 1212 1213 /** 1214 * Sets the {@code TimeZone} used by this Calendar. 1215 */ 1216 public void setTimeZone(TimeZone timezone) { 1217 zone = timezone; 1218 areFieldsSet = false; 1219 } 1220 1221 /** 1222 * Returns a string representation of this {@code Calendar}, showing which fields are set. 1223 */ 1224 @Override 1225 public String toString() { 1226 StringBuilder result = new StringBuilder(getClass().getName() + 1227 "[time=" + (isTimeSet ? String.valueOf(time) : "?") + 1228 ",areFieldsSet=" + areFieldsSet + 1229 ",lenient=" + lenient + 1230 ",zone=" + zone.getID() + 1231 ",firstDayOfWeek=" + firstDayOfWeek + 1232 ",minimalDaysInFirstWeek=" + minimalDaysInFirstWeek); 1233 for (int i = 0; i < FIELD_COUNT; i++) { 1234 result.append(','); 1235 result.append(FIELD_NAMES[i]); 1236 result.append('='); 1237 if (isSet[i]) { 1238 result.append(fields[i]); 1239 } else { 1240 result.append('?'); 1241 } 1242 } 1243 result.append(']'); 1244 return result.toString(); 1245 } 1246 1247 /** 1248 * Compares the time represented by this {@code Calendar} to that represented by the given 1249 * {@code Calendar}. 1250 * 1251 * @return 0 if the times of the two {@code Calendar}s are equal, -1 if the time of 1252 * this {@code Calendar} is before the other one, 1 if the time of this 1253 * {@code Calendar} is after the other one. 1254 * @throws NullPointerException 1255 * if the argument is null. 1256 * @throws IllegalArgumentException 1257 * if the argument does not include a valid time 1258 * value. 1259 */ 1260 public int compareTo(Calendar anotherCalendar) { 1261 if (anotherCalendar == null) { 1262 throw new NullPointerException("anotherCalendar == null"); 1263 } 1264 long timeInMillis = getTimeInMillis(); 1265 long anotherTimeInMillis = anotherCalendar.getTimeInMillis(); 1266 if (timeInMillis > anotherTimeInMillis) { 1267 return 1; 1268 } 1269 if (timeInMillis == anotherTimeInMillis) { 1270 return 0; 1271 } 1272 return -1; 1273 } 1274 1275 /** 1276 * Returns a human-readable string for the value of {@code field} 1277 * using the given style and locale. If no string is available, returns null. 1278 * The value is retrieved by invoking {@code get(field)}. 1279 * 1280 * <p>For example, {@code getDisplayName(MONTH, SHORT, Locale.US)} will return "Jan" 1281 * while {@code getDisplayName(MONTH, LONG, Locale.US)} will return "January". 1282 * 1283 * @param field the field 1284 * @param style {@code SHORT} or {@code LONG} 1285 * @param locale the locale 1286 * @return the display name, or null 1287 * @throws NullPointerException if {@code locale == null} 1288 * @throws IllegalArgumentException if {@code field} or {@code style} is invalid 1289 * @since 1.6 1290 */ 1291 public String getDisplayName(int field, int style, Locale locale) { 1292 // TODO: the RI's documentation says ALL_STYLES is invalid, but actually treats it as SHORT. 1293 if (style == ALL_STYLES) { 1294 style = SHORT; 1295 } 1296 String[] array = getDisplayNameArray(field, style, locale); 1297 int value = get(field); 1298 return (array != null) ? array[value] : null; 1299 } 1300 1301 private String[] getDisplayNameArray(int field, int style, Locale locale) { 1302 if (field < 0 || field >= FIELD_COUNT) { 1303 throw new IllegalArgumentException("bad field " + field); 1304 } 1305 checkStyle(style); 1306 DateFormatSymbols dfs = DateFormatSymbols.getInstance(locale); 1307 switch (field) { 1308 case AM_PM: 1309 return dfs.getAmPmStrings(); 1310 case DAY_OF_WEEK: 1311 return (style == LONG) ? dfs.getWeekdays() : dfs.getShortWeekdays(); 1312 case ERA: 1313 return dfs.getEras(); 1314 case MONTH: 1315 return (style == LONG) ? dfs.getMonths() : dfs.getShortMonths(); 1316 } 1317 return null; 1318 } 1319 1320 private static void checkStyle(int style) { 1321 if (style != ALL_STYLES && style != SHORT && style != LONG) { 1322 throw new IllegalArgumentException("bad style " + style); 1323 } 1324 } 1325 1326 /** 1327 * Returns a map of human-readable strings to corresponding values, 1328 * for the given field, style, and locale. 1329 * Returns null if no strings are available. 1330 * 1331 * <p>For example, {@code getDisplayNames(MONTH, ALL_STYLES, Locale.US)} would 1332 * contain mappings from "Jan" and "January" to {@link #JANUARY}, and so on. 1333 * 1334 * @param field the field 1335 * @param style {@code SHORT}, {@code LONG}, or {@code ALL_STYLES} 1336 * @param locale the locale 1337 * @return the display name, or null 1338 * @throws NullPointerException if {@code locale == null} 1339 * @throws IllegalArgumentException if {@code field} or {@code style} is invalid 1340 * @since 1.6 1341 */ 1342 public Map<String, Integer> getDisplayNames(int field, int style, Locale locale) { 1343 checkStyle(style); 1344 complete(); 1345 Map<String, Integer> result = new HashMap<String, Integer>(); 1346 if (style == SHORT || style == ALL_STYLES) { 1347 insertValuesInMap(result, getDisplayNameArray(field, SHORT, locale)); 1348 } 1349 if (style == LONG || style == ALL_STYLES) { 1350 insertValuesInMap(result, getDisplayNameArray(field, LONG, locale)); 1351 } 1352 return result.isEmpty() ? null : result; 1353 } 1354 1355 private static void insertValuesInMap(Map<String, Integer> map, String[] values) { 1356 if (values == null) { 1357 return; 1358 } 1359 for (int i = 0; i < values.length; ++i) { 1360 if (values[i] != null && !values[i].isEmpty()) { 1361 map.put(values[i], i); 1362 } 1363 } 1364 } 1365 1366 private static final ObjectStreamField[] serialPersistentFields = { 1367 new ObjectStreamField("areFieldsSet", boolean.class), 1368 new ObjectStreamField("fields", int[].class), 1369 new ObjectStreamField("firstDayOfWeek", int.class), 1370 new ObjectStreamField("isSet", boolean[].class), 1371 new ObjectStreamField("isTimeSet", boolean.class), 1372 new ObjectStreamField("lenient", boolean.class), 1373 new ObjectStreamField("minimalDaysInFirstWeek", int.class), 1374 new ObjectStreamField("nextStamp", int.class), 1375 new ObjectStreamField("serialVersionOnStream", int.class), 1376 new ObjectStreamField("time", long.class), 1377 new ObjectStreamField("zone", TimeZone.class), 1378 }; 1379 1380 private void writeObject(ObjectOutputStream stream) throws IOException { 1381 complete(); 1382 ObjectOutputStream.PutField putFields = stream.putFields(); 1383 putFields.put("areFieldsSet", areFieldsSet); 1384 putFields.put("fields", this.fields); 1385 putFields.put("firstDayOfWeek", firstDayOfWeek); 1386 putFields.put("isSet", isSet); 1387 putFields.put("isTimeSet", isTimeSet); 1388 putFields.put("lenient", lenient); 1389 putFields.put("minimalDaysInFirstWeek", minimalDaysInFirstWeek); 1390 putFields.put("nextStamp", 2 /* MINIMUM_USER_STAMP */); 1391 putFields.put("serialVersionOnStream", 1); 1392 putFields.put("time", time); 1393 putFields.put("zone", zone); 1394 stream.writeFields(); 1395 } 1396 1397 private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { 1398 ObjectInputStream.GetField readFields = stream.readFields(); 1399 areFieldsSet = readFields.get("areFieldsSet", false); 1400 this.fields = (int[]) readFields.get("fields", null); 1401 firstDayOfWeek = readFields.get("firstDayOfWeek", Calendar.SUNDAY); 1402 isSet = (boolean[]) readFields.get("isSet", null); 1403 isTimeSet = readFields.get("isTimeSet", false); 1404 lenient = readFields.get("lenient", true); 1405 minimalDaysInFirstWeek = readFields.get("minimalDaysInFirstWeek", 1); 1406 time = readFields.get("time", 0L); 1407 zone = (TimeZone) readFields.get("zone", null); 1408 } 1409 } 1410