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 */ Calendar()713 protected Calendar() { 714 this(TimeZone.getDefault(), Locale.getDefault()); 715 } 716 Calendar(TimeZone timezone)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 */ Calendar(TimeZone timezone, Locale locale)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 */ add(int field, int value)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 */ after(Object calendar)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 */ before(Object calendar)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 */ clear()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 */ clear(int field)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 shallow copy of this {@code Calendar} with the same properties. 814 */ 815 @Override clone()816 public Object clone() { 817 try { 818 Calendar clone = (Calendar) super.clone(); 819 clone.fields = fields.clone(); 820 clone.isSet = isSet.clone(); 821 clone.zone = (TimeZone) zone.clone(); 822 return clone; 823 } catch (CloneNotSupportedException e) { 824 throw new AssertionError(e); 825 } 826 } 827 828 /** 829 * Computes the time from the fields if the time has not already been set. 830 * Computes the fields from the time if the fields are not already set. 831 * 832 * @throws IllegalArgumentException 833 * if the time is not set and the time cannot be computed 834 * from the current field values. 835 */ complete()836 protected void complete() { 837 if (!isTimeSet) { 838 computeTime(); 839 isTimeSet = true; 840 } 841 if (!areFieldsSet) { 842 computeFields(); 843 areFieldsSet = true; 844 } 845 } 846 847 /** 848 * Computes the {@code Calendar} fields from {@code time}. 849 */ computeFields()850 protected abstract void computeFields(); 851 852 /** 853 * Computes {@code time} from the Calendar fields. 854 * 855 * @throws IllegalArgumentException 856 * if the time cannot be computed from the current field 857 * values. 858 */ computeTime()859 protected abstract void computeTime(); 860 861 /** 862 * Compares the given object to this {@code Calendar} and returns whether they are 863 * equal. The object must be an instance of {@code Calendar} and have the same 864 * properties. 865 * 866 * @return {@code true} if the given object is equal to this {@code Calendar}, {@code false} 867 * otherwise. 868 */ 869 @Override equals(Object object)870 public boolean equals(Object object) { 871 if (this == object) { 872 return true; 873 } 874 if (!(object instanceof Calendar)) { 875 return false; 876 } 877 Calendar cal = (Calendar) object; 878 return getTimeInMillis() == cal.getTimeInMillis() 879 && isLenient() == cal.isLenient() 880 && getFirstDayOfWeek() == cal.getFirstDayOfWeek() 881 && getMinimalDaysInFirstWeek() == cal.getMinimalDaysInFirstWeek() 882 && getTimeZone().equals(cal.getTimeZone()); 883 } 884 885 /** 886 * Returns the value of the given field after computing the field values by 887 * calling {@code complete()} first. 888 * 889 * @throws IllegalArgumentException 890 * if the fields are not set, the time is not set, and the 891 * time cannot be computed from the current field values. 892 * @throws ArrayIndexOutOfBoundsException 893 * if the field is not inside the range of possible fields. 894 * The range is starting at 0 up to {@code FIELD_COUNT}. 895 */ get(int field)896 public int get(int field) { 897 complete(); 898 return fields[field]; 899 } 900 901 /** 902 * Returns the maximum value of the given field for the current date. 903 * For example, the maximum number of days in the current month. 904 */ getActualMaximum(int field)905 public int getActualMaximum(int field) { 906 int value, next; 907 if (getMaximum(field) == (next = getLeastMaximum(field))) { 908 return next; 909 } 910 complete(); 911 long orgTime = time; 912 set(field, next); 913 do { 914 value = next; 915 roll(field, true); 916 next = get(field); 917 } while (next > value); 918 time = orgTime; 919 areFieldsSet = false; 920 return value; 921 } 922 923 /** 924 * Returns the minimum value of the given field for the current date. 925 */ getActualMinimum(int field)926 public int getActualMinimum(int field) { 927 int value, next; 928 if (getMinimum(field) == (next = getGreatestMinimum(field))) { 929 return next; 930 } 931 complete(); 932 long orgTime = time; 933 set(field, next); 934 do { 935 value = next; 936 roll(field, false); 937 next = get(field); 938 } while (next < value); 939 time = orgTime; 940 areFieldsSet = false; 941 return value; 942 } 943 944 /** 945 * Returns an array of locales for which custom {@code Calendar} instances 946 * are available. 947 * <p>Note that Android does not support user-supplied locale service providers. 948 */ getAvailableLocales()949 public static synchronized Locale[] getAvailableLocales() { 950 return ICU.getAvailableCalendarLocales(); 951 } 952 953 /** 954 * Returns the first day of the week for this {@code Calendar}. 955 */ getFirstDayOfWeek()956 public int getFirstDayOfWeek() { 957 return firstDayOfWeek; 958 } 959 960 /** 961 * Returns the greatest minimum value of the given field. This is the 962 * biggest value that {@code getActualMinimum} can return for any possible 963 * time. 964 */ getGreatestMinimum(int field)965 public abstract int getGreatestMinimum(int field); 966 967 /** 968 * Constructs a new instance of the {@code Calendar} subclass appropriate for the 969 * default {@code Locale} and default {@code TimeZone}, set to the current date and time. 970 */ getInstance()971 public static synchronized Calendar getInstance() { 972 return new GregorianCalendar(); 973 } 974 975 /** 976 * Constructs a new instance of the {@code Calendar} subclass appropriate for the 977 * given {@code Locale} and default {@code TimeZone}, set to the current date and time. 978 */ getInstance(Locale locale)979 public static synchronized Calendar getInstance(Locale locale) { 980 return new GregorianCalendar(locale); 981 } 982 983 /** 984 * Constructs a new instance of the {@code Calendar} subclass appropriate for the 985 * default {@code Locale} and given {@code TimeZone}, set to the current date and time. 986 */ getInstance(TimeZone timezone)987 public static synchronized Calendar getInstance(TimeZone timezone) { 988 return new GregorianCalendar(timezone); 989 } 990 991 /** 992 * Constructs a new instance of the {@code Calendar} subclass appropriate for the 993 * given {@code Locale} and given {@code TimeZone}, set to the current date and time. 994 */ getInstance(TimeZone timezone, Locale locale)995 public static synchronized Calendar getInstance(TimeZone timezone, Locale locale) { 996 return new GregorianCalendar(timezone, locale); 997 } 998 999 /** 1000 * Returns the smallest maximum value of the given field. This is the 1001 * smallest value that {@code getActualMaximum()} can return for any 1002 * possible time. 1003 */ getLeastMaximum(int field)1004 public abstract int getLeastMaximum(int field); 1005 1006 /** 1007 * Returns the greatest maximum value of the given field. This returns the 1008 * biggest value that {@code get} can return for the given field. 1009 */ getMaximum(int field)1010 public abstract int getMaximum(int field); 1011 1012 /** 1013 * Returns the minimal days in the first week of the year. 1014 */ getMinimalDaysInFirstWeek()1015 public int getMinimalDaysInFirstWeek() { 1016 return minimalDaysInFirstWeek; 1017 } 1018 1019 /** 1020 * Returns the smallest minimum value of the given field. this returns the 1021 * smallest value that {@code get} can return for the given field. 1022 */ getMinimum(int field)1023 public abstract int getMinimum(int field); 1024 1025 /** 1026 * Returns the time of this {@code Calendar} as a {@code Date} object. 1027 * 1028 * @throws IllegalArgumentException 1029 * if the time is not set and the time cannot be computed 1030 * from the current field values. 1031 */ getTime()1032 public final Date getTime() { 1033 return new Date(getTimeInMillis()); 1034 } 1035 1036 /** 1037 * Returns the time represented by this {@code Calendar}, recomputing the time from its 1038 * fields if necessary. 1039 * 1040 * @throws IllegalArgumentException 1041 * if the time is not set and the time cannot be computed 1042 * from the current field values. 1043 */ getTimeInMillis()1044 public long getTimeInMillis() { 1045 if (!isTimeSet) { 1046 computeTime(); 1047 isTimeSet = true; 1048 } 1049 return time; 1050 } 1051 1052 /** 1053 * Returns the time zone used by this {@code Calendar}. 1054 */ getTimeZone()1055 public TimeZone getTimeZone() { 1056 return zone; 1057 } 1058 1059 @Override hashCode()1060 public int hashCode() { 1061 return (isLenient() ? 1237 : 1231) + getFirstDayOfWeek() 1062 + getMinimalDaysInFirstWeek() + getTimeZone().hashCode(); 1063 } 1064 1065 /** 1066 * Returns the value of the given field without recomputing. 1067 */ internalGet(int field)1068 protected final int internalGet(int field) { 1069 return fields[field]; 1070 } 1071 1072 /** 1073 * Tests whether this {@code Calendar} accepts field values which are outside the valid 1074 * range for the field. 1075 */ isLenient()1076 public boolean isLenient() { 1077 return lenient; 1078 } 1079 1080 /** 1081 * Tests whether the given field is set. Note that the interpretation of "is set" is 1082 * somewhat technical. In particular, it does <i>not</i> mean that the field's value is up 1083 * to date. If you want to know whether a field contains an up-to-date value, you must also 1084 * check {@code areFieldsSet}, making this method somewhat useless unless you're a subclass, 1085 * in which case you can access the {@code isSet} array directly. 1086 * <p> 1087 * A field remains "set" from the first time its value is computed until it's cleared by one 1088 * of the {@code clear} methods. Thus "set" does not mean "valid". You probably want to call 1089 * {@code get} -- which will update fields as necessary -- rather than try to make use of 1090 * this method. 1091 */ isSet(int field)1092 public final boolean isSet(int field) { 1093 return isSet[field]; 1094 } 1095 1096 /** 1097 * Adds the given amount to the given field and wraps the value of 1098 * the field when it goes beyond the maximum or minimum value for the 1099 * current date. Other fields will be adjusted as required to maintain a 1100 * consistent date. 1101 */ roll(int field, int value)1102 public void roll(int field, int value) { 1103 boolean increment = value >= 0; 1104 int count = increment ? value : -value; 1105 for (int i = 0; i < count; i++) { 1106 roll(field, increment); 1107 } 1108 } 1109 1110 /** 1111 * Increment or decrement the given field and wrap the value of the 1112 * field when it goes beyond the maximum or minimum value for the current 1113 * date. Other fields will be adjusted as required to maintain a consistent 1114 * date. 1115 */ roll(int field, boolean increment)1116 public abstract void roll(int field, boolean increment); 1117 1118 /** 1119 * Sets the given field to the given value. 1120 */ set(int field, int value)1121 public void set(int field, int value) { 1122 fields[field] = value; 1123 isSet[field] = true; 1124 areFieldsSet = isTimeSet = false; 1125 if (field > MONTH && field < AM_PM) { 1126 lastDateFieldSet = field; 1127 } 1128 if (field == HOUR || field == HOUR_OF_DAY) { 1129 lastTimeFieldSet = field; 1130 } 1131 if (field == AM_PM) { 1132 lastTimeFieldSet = HOUR; 1133 } 1134 } 1135 1136 /** 1137 * Sets the year, month, and day of the month fields. 1138 * Other fields are not changed; call {@link #clear} first if this is not desired. 1139 * The month value is 0-based, so it may be clearer to use a constant like {@code JANUARY}. 1140 */ set(int year, int month, int day)1141 public final void set(int year, int month, int day) { 1142 set(YEAR, year); 1143 set(MONTH, month); 1144 set(DATE, day); 1145 } 1146 1147 /** 1148 * Sets the year, month, day of the month, hour of day, and minute fields. 1149 * Other fields are not changed; call {@link #clear} first if this is not desired. 1150 * The month value is 0-based, so it may be clearer to use a constant like {@code JANUARY}. 1151 */ set(int year, int month, int day, int hourOfDay, int minute)1152 public final void set(int year, int month, int day, int hourOfDay, int minute) { 1153 set(year, month, day); 1154 set(HOUR_OF_DAY, hourOfDay); 1155 set(MINUTE, minute); 1156 } 1157 1158 /** 1159 * Sets the year, month, day of the month, hour of day, minute, and second fields. 1160 * Other fields are not changed; call {@link #clear} first if this is not desired. 1161 * The month value is 0-based, so it may be clearer to use a constant like {@code JANUARY}. 1162 */ set(int year, int month, int day, int hourOfDay, int minute, int second)1163 public final void set(int year, int month, int day, int hourOfDay, int minute, int second) { 1164 set(year, month, day, hourOfDay, minute); 1165 set(SECOND, second); 1166 } 1167 1168 /** 1169 * Sets the first day of the week for this {@code Calendar}. 1170 * The value should be a day of the week such as {@code MONDAY}. 1171 */ setFirstDayOfWeek(int value)1172 public void setFirstDayOfWeek(int value) { 1173 firstDayOfWeek = value; 1174 } 1175 1176 /** 1177 * Sets whether this {@code Calendar} accepts field values which are outside the valid 1178 * range for the field. 1179 */ setLenient(boolean value)1180 public void setLenient(boolean value) { 1181 lenient = value; 1182 } 1183 1184 /** 1185 * Sets the minimal days in the first week of the year. 1186 */ setMinimalDaysInFirstWeek(int value)1187 public void setMinimalDaysInFirstWeek(int value) { 1188 minimalDaysInFirstWeek = value; 1189 } 1190 1191 /** 1192 * Sets the time of this {@code Calendar}. 1193 */ setTime(Date date)1194 public final void setTime(Date date) { 1195 setTimeInMillis(date.getTime()); 1196 } 1197 1198 /** 1199 * Sets the time of this {@code Calendar} to the given Unix time. See {@link Date} for more 1200 * about what this means. 1201 */ setTimeInMillis(long milliseconds)1202 public void setTimeInMillis(long milliseconds) { 1203 if (!isTimeSet || !areFieldsSet || time != milliseconds) { 1204 time = milliseconds; 1205 isTimeSet = true; 1206 areFieldsSet = false; 1207 complete(); 1208 } 1209 } 1210 1211 /** 1212 * Sets the {@code TimeZone} used by this Calendar. 1213 */ setTimeZone(TimeZone timezone)1214 public void setTimeZone(TimeZone timezone) { 1215 zone = timezone; 1216 areFieldsSet = false; 1217 } 1218 1219 /** 1220 * Returns a string representation of this {@code Calendar}, showing which fields are set. 1221 */ 1222 @Override toString()1223 public String toString() { 1224 StringBuilder result = new StringBuilder(getClass().getName() + 1225 "[time=" + (isTimeSet ? String.valueOf(time) : "?") + 1226 ",areFieldsSet=" + areFieldsSet + 1227 ",lenient=" + lenient + 1228 ",zone=" + zone.getID() + 1229 ",firstDayOfWeek=" + firstDayOfWeek + 1230 ",minimalDaysInFirstWeek=" + minimalDaysInFirstWeek); 1231 for (int i = 0; i < FIELD_COUNT; i++) { 1232 result.append(','); 1233 result.append(FIELD_NAMES[i]); 1234 result.append('='); 1235 if (isSet[i]) { 1236 result.append(fields[i]); 1237 } else { 1238 result.append('?'); 1239 } 1240 } 1241 result.append(']'); 1242 return result.toString(); 1243 } 1244 1245 /** 1246 * Compares the time represented by this {@code Calendar} to that represented by the given 1247 * {@code Calendar}. 1248 * 1249 * @return 0 if the times of the two {@code Calendar}s are equal, -1 if the time of 1250 * this {@code Calendar} is before the other one, 1 if the time of this 1251 * {@code Calendar} is after the other one. 1252 * @throws NullPointerException 1253 * if the argument is null. 1254 * @throws IllegalArgumentException 1255 * if the argument does not include a valid time 1256 * value. 1257 */ compareTo(Calendar anotherCalendar)1258 public int compareTo(Calendar anotherCalendar) { 1259 if (anotherCalendar == null) { 1260 throw new NullPointerException("anotherCalendar == null"); 1261 } 1262 long timeInMillis = getTimeInMillis(); 1263 long anotherTimeInMillis = anotherCalendar.getTimeInMillis(); 1264 if (timeInMillis > anotherTimeInMillis) { 1265 return 1; 1266 } 1267 if (timeInMillis == anotherTimeInMillis) { 1268 return 0; 1269 } 1270 return -1; 1271 } 1272 1273 /** 1274 * Returns a human-readable string for the value of {@code field} 1275 * using the given style and locale. If no string is available, returns null. 1276 * The value is retrieved by invoking {@code get(field)}. 1277 * 1278 * <p>For example, {@code getDisplayName(MONTH, SHORT, Locale.US)} will return "Jan" 1279 * while {@code getDisplayName(MONTH, LONG, Locale.US)} will return "January". 1280 * 1281 * @param field the field 1282 * @param style {@code SHORT} or {@code LONG} 1283 * @param locale the locale 1284 * @return the display name, or null 1285 * @throws NullPointerException if {@code locale == null} 1286 * @throws IllegalArgumentException if {@code field} or {@code style} is invalid 1287 * @since 1.6 1288 */ getDisplayName(int field, int style, Locale locale)1289 public String getDisplayName(int field, int style, Locale locale) { 1290 // TODO: the RI's documentation says ALL_STYLES is invalid, but actually treats it as SHORT. 1291 if (style == ALL_STYLES) { 1292 style = SHORT; 1293 } 1294 String[] array = getDisplayNameArray(field, style, locale); 1295 int value = get(field); 1296 return (array != null) ? array[value] : null; 1297 } 1298 getDisplayNameArray(int field, int style, Locale locale)1299 private String[] getDisplayNameArray(int field, int style, Locale locale) { 1300 if (field < 0 || field >= FIELD_COUNT) { 1301 throw new IllegalArgumentException("bad field " + field); 1302 } 1303 checkStyle(style); 1304 DateFormatSymbols dfs = DateFormatSymbols.getInstance(locale); 1305 switch (field) { 1306 case AM_PM: 1307 return dfs.getAmPmStrings(); 1308 case DAY_OF_WEEK: 1309 return (style == LONG) ? dfs.getWeekdays() : dfs.getShortWeekdays(); 1310 case ERA: 1311 return dfs.getEras(); 1312 case MONTH: 1313 return (style == LONG) ? dfs.getMonths() : dfs.getShortMonths(); 1314 } 1315 return null; 1316 } 1317 checkStyle(int style)1318 private static void checkStyle(int style) { 1319 if (style != ALL_STYLES && style != SHORT && style != LONG) { 1320 throw new IllegalArgumentException("bad style " + style); 1321 } 1322 } 1323 1324 /** 1325 * Returns a map of human-readable strings to corresponding values, 1326 * for the given field, style, and locale. 1327 * Returns null if no strings are available. 1328 * 1329 * <p>For example, {@code getDisplayNames(MONTH, ALL_STYLES, Locale.US)} would 1330 * contain mappings from "Jan" and "January" to {@link #JANUARY}, and so on. 1331 * 1332 * @param field the field 1333 * @param style {@code SHORT}, {@code LONG}, or {@code ALL_STYLES} 1334 * @param locale the locale 1335 * @return the display name, or null 1336 * @throws NullPointerException if {@code locale == null} 1337 * @throws IllegalArgumentException if {@code field} or {@code style} is invalid 1338 * @since 1.6 1339 */ getDisplayNames(int field, int style, Locale locale)1340 public Map<String, Integer> getDisplayNames(int field, int style, Locale locale) { 1341 checkStyle(style); 1342 complete(); 1343 Map<String, Integer> result = new HashMap<String, Integer>(); 1344 if (style == SHORT || style == ALL_STYLES) { 1345 insertValuesInMap(result, getDisplayNameArray(field, SHORT, locale)); 1346 } 1347 if (style == LONG || style == ALL_STYLES) { 1348 insertValuesInMap(result, getDisplayNameArray(field, LONG, locale)); 1349 } 1350 return result.isEmpty() ? null : result; 1351 } 1352 insertValuesInMap(Map<String, Integer> map, String[] values)1353 private static void insertValuesInMap(Map<String, Integer> map, String[] values) { 1354 if (values == null) { 1355 return; 1356 } 1357 for (int i = 0; i < values.length; ++i) { 1358 if (values[i] != null && !values[i].isEmpty()) { 1359 map.put(values[i], i); 1360 } 1361 } 1362 } 1363 1364 private static final ObjectStreamField[] serialPersistentFields = { 1365 new ObjectStreamField("areFieldsSet", boolean.class), 1366 new ObjectStreamField("fields", int[].class), 1367 new ObjectStreamField("firstDayOfWeek", int.class), 1368 new ObjectStreamField("isSet", boolean[].class), 1369 new ObjectStreamField("isTimeSet", boolean.class), 1370 new ObjectStreamField("lenient", boolean.class), 1371 new ObjectStreamField("minimalDaysInFirstWeek", int.class), 1372 new ObjectStreamField("nextStamp", int.class), 1373 new ObjectStreamField("serialVersionOnStream", int.class), 1374 new ObjectStreamField("time", long.class), 1375 new ObjectStreamField("zone", TimeZone.class), 1376 }; 1377 writeObject(ObjectOutputStream stream)1378 private void writeObject(ObjectOutputStream stream) throws IOException { 1379 complete(); 1380 ObjectOutputStream.PutField putFields = stream.putFields(); 1381 putFields.put("areFieldsSet", areFieldsSet); 1382 putFields.put("fields", this.fields); 1383 putFields.put("firstDayOfWeek", firstDayOfWeek); 1384 putFields.put("isSet", isSet); 1385 putFields.put("isTimeSet", isTimeSet); 1386 putFields.put("lenient", lenient); 1387 putFields.put("minimalDaysInFirstWeek", minimalDaysInFirstWeek); 1388 putFields.put("nextStamp", 2 /* MINIMUM_USER_STAMP */); 1389 putFields.put("serialVersionOnStream", 1); 1390 putFields.put("time", time); 1391 putFields.put("zone", zone); 1392 stream.writeFields(); 1393 } 1394 readObject(ObjectInputStream stream)1395 private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { 1396 ObjectInputStream.GetField readFields = stream.readFields(); 1397 areFieldsSet = readFields.get("areFieldsSet", false); 1398 this.fields = (int[]) readFields.get("fields", null); 1399 firstDayOfWeek = readFields.get("firstDayOfWeek", Calendar.SUNDAY); 1400 isSet = (boolean[]) readFields.get("isSet", null); 1401 isTimeSet = readFields.get("isTimeSet", false); 1402 lenient = readFields.get("lenient", true); 1403 minimalDaysInFirstWeek = readFields.get("minimalDaysInFirstWeek", 1); 1404 time = readFields.get("time", 0L); 1405 zone = (TimeZone) readFields.get("zone", null); 1406 } 1407 } 1408