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 offset from GMT in milliseconds. 646 */ 647 public static final int ZONE_OFFSET = 15; 648 649 /** 650 * Field number for {@code get} and {@code set} indicating the 651 * daylight savings offset in milliseconds. 652 */ 653 public static final int DST_OFFSET = 16; 654 655 /** 656 * This is the total number of fields in this calendar. 657 */ 658 public static final int FIELD_COUNT = 17; 659 660 /** 661 * Value of the {@code AM_PM} field indicating the period of the day 662 * from midnight to just before noon. 663 */ 664 public static final int AM = 0; 665 666 /** 667 * Value of the {@code AM_PM} field indicating the period of the day 668 * from noon to just before midnight. 669 */ 670 public static final int PM = 1; 671 672 /** 673 * Requests both {@code SHORT} and {@code LONG} styles in the map returned by 674 * {@link #getDisplayNames}. 675 * @since 1.6 676 */ 677 public static final int ALL_STYLES = 0; 678 679 /** 680 * Requests short names (such as "Jan") from 681 * {@link #getDisplayName} or {@link #getDisplayNames}. 682 * @since 1.6 683 */ 684 public static final int SHORT = 1; 685 686 /** 687 * Requests long names (such as "January") from 688 * {@link #getDisplayName} or {@link #getDisplayNames}. 689 * @since 1.6 690 */ 691 public static final int LONG = 2; 692 693 private static final String[] FIELD_NAMES = { "ERA", "YEAR", "MONTH", 694 "WEEK_OF_YEAR", "WEEK_OF_MONTH", "DAY_OF_MONTH", "DAY_OF_YEAR", 695 "DAY_OF_WEEK", "DAY_OF_WEEK_IN_MONTH", "AM_PM", "HOUR", 696 "HOUR_OF_DAY", "MINUTE", "SECOND", "MILLISECOND", 697 "ZONE_OFFSET", "DST_OFFSET" }; 698 699 /** 700 * Constructs a {@code Calendar} instance using the default {@code TimeZone} and {@code Locale}. 701 */ 702 protected Calendar() { 703 this(TimeZone.getDefault(), Locale.getDefault()); 704 } 705 706 Calendar(TimeZone timezone) { 707 fields = new int[FIELD_COUNT]; 708 isSet = new boolean[FIELD_COUNT]; 709 areFieldsSet = isTimeSet = false; 710 setLenient(true); 711 setTimeZone(timezone); 712 } 713 714 /** 715 * Constructs a {@code Calendar} instance using the specified {@code TimeZone} and {@code Locale}. 716 * 717 * @param timezone 718 * the timezone. 719 * @param locale 720 * the locale. 721 */ 722 protected Calendar(TimeZone timezone, Locale locale) { 723 this(timezone); 724 LocaleData localeData = LocaleData.get(locale); 725 setFirstDayOfWeek(localeData.firstDayOfWeek.intValue()); 726 setMinimalDaysInFirstWeek(localeData.minimalDaysInFirstWeek.intValue()); 727 } 728 729 730 /** 731 * Adds the specified amount to a {@code Calendar} field. 732 * 733 * @param field 734 * the {@code Calendar} field to modify. 735 * @param value 736 * the amount to add to the field. 737 * @throws IllegalArgumentException 738 * if {@code field} is {@code DST_OFFSET} or {@code 739 * ZONE_OFFSET}. 740 */ 741 public abstract void add(int field, int value); 742 743 /** 744 * Returns whether the {@code Date} specified by this {@code Calendar} instance is after the {@code Date} 745 * specified by the parameter. The comparison is not dependent on the time 746 * zones of the {@code Calendar}. 747 * 748 * @param calendar 749 * the {@code Calendar} instance to compare. 750 * @return {@code true} when this Calendar is after calendar, {@code false} otherwise. 751 * @throws IllegalArgumentException 752 * if the time is not set and the time cannot be computed 753 * from the current field values. 754 */ 755 public boolean after(Object calendar) { 756 if (!(calendar instanceof Calendar)) { 757 return false; 758 } 759 return getTimeInMillis() > ((Calendar) calendar).getTimeInMillis(); 760 } 761 762 /** 763 * Returns whether the {@code Date} specified by this {@code Calendar} instance is before the 764 * {@code Date} specified by the parameter. The comparison is not dependent on the 765 * time zones of the {@code Calendar}. 766 * 767 * @param calendar 768 * the {@code Calendar} instance to compare. 769 * @return {@code true} when this Calendar is before calendar, {@code false} otherwise. 770 * @throws IllegalArgumentException 771 * if the time is not set and the time cannot be computed 772 * from the current field values. 773 */ 774 public boolean before(Object calendar) { 775 if (!(calendar instanceof Calendar)) { 776 return false; 777 } 778 return getTimeInMillis() < ((Calendar) calendar).getTimeInMillis(); 779 } 780 781 /** 782 * Clears all of the fields of this {@code Calendar}. All fields are initialized to 783 * zero. 784 */ 785 public final void clear() { 786 for (int i = 0; i < FIELD_COUNT; i++) { 787 fields[i] = 0; 788 isSet[i] = false; 789 } 790 areFieldsSet = isTimeSet = false; 791 } 792 793 /** 794 * Clears the specified field to zero and sets the isSet flag to {@code false}. 795 * 796 * @param field 797 * the field to clear. 798 */ 799 public final void clear(int field) { 800 fields[field] = 0; 801 isSet[field] = false; 802 areFieldsSet = isTimeSet = false; 803 } 804 805 /** 806 * Returns a new {@code Calendar} with the same properties. 807 * 808 * @return a shallow copy of this {@code Calendar}. 809 * 810 * @see java.lang.Cloneable 811 */ 812 @Override 813 public Object clone() { 814 try { 815 Calendar clone = (Calendar) super.clone(); 816 clone.fields = fields.clone(); 817 clone.isSet = isSet.clone(); 818 clone.zone = (TimeZone) zone.clone(); 819 return clone; 820 } catch (CloneNotSupportedException e) { 821 throw new AssertionError(e); 822 } 823 } 824 825 /** 826 * Computes the time from the fields if the time has not already been set. 827 * Computes the fields from the time if the fields are not already set. 828 * 829 * @throws IllegalArgumentException 830 * if the time is not set and the time cannot be computed 831 * from the current field values. 832 */ 833 protected void complete() { 834 if (!isTimeSet) { 835 computeTime(); 836 isTimeSet = true; 837 } 838 if (!areFieldsSet) { 839 computeFields(); 840 areFieldsSet = true; 841 } 842 } 843 844 /** 845 * Computes the {@code Calendar} fields from {@code time}. 846 */ 847 protected abstract void computeFields(); 848 849 /** 850 * Computes {@code time} from the Calendar fields. 851 * 852 * @throws IllegalArgumentException 853 * if the time cannot be computed from the current field 854 * values. 855 */ 856 protected abstract void computeTime(); 857 858 /** 859 * Compares the specified object to this {@code Calendar} and returns whether they are 860 * equal. The object must be an instance of {@code Calendar} and have the same 861 * properties. 862 * 863 * @param object 864 * the object to compare with this object. 865 * @return {@code true} if the specified object is equal to this {@code Calendar}, {@code false} 866 * otherwise. 867 */ 868 @Override 869 public boolean equals(Object object) { 870 if (this == object) { 871 return true; 872 } 873 if (!(object instanceof Calendar)) { 874 return false; 875 } 876 Calendar cal = (Calendar) object; 877 return getTimeInMillis() == cal.getTimeInMillis() 878 && isLenient() == cal.isLenient() 879 && getFirstDayOfWeek() == cal.getFirstDayOfWeek() 880 && getMinimalDaysInFirstWeek() == cal.getMinimalDaysInFirstWeek() 881 && getTimeZone().equals(cal.getTimeZone()); 882 } 883 884 /** 885 * Gets the value of the specified field after computing the field values by 886 * calling {@code complete()} first. 887 * 888 * @param field 889 * the field to get. 890 * @return the value of the specified field. 891 * 892 * @throws IllegalArgumentException 893 * if the fields are not set, the time is not set, and the 894 * time cannot be computed from the current field values. 895 * @throws ArrayIndexOutOfBoundsException 896 * if the field is not inside the range of possible fields. 897 * The range is starting at 0 up to {@code FIELD_COUNT}. 898 */ 899 public int get(int field) { 900 complete(); 901 return fields[field]; 902 } 903 904 /** 905 * Returns the maximum value of the specified field for the current date. 906 * For example, the maximum number of days in the current month. 907 */ 908 public int getActualMaximum(int field) { 909 int value, next; 910 if (getMaximum(field) == (next = getLeastMaximum(field))) { 911 return next; 912 } 913 complete(); 914 long orgTime = time; 915 set(field, next); 916 do { 917 value = next; 918 roll(field, true); 919 next = get(field); 920 } while (next > value); 921 time = orgTime; 922 areFieldsSet = false; 923 return value; 924 } 925 926 /** 927 * Gets the minimum value of the specified field for the current date. 928 * 929 * @param field 930 * the field. 931 * @return the minimum value of the specified field. 932 */ 933 public int getActualMinimum(int field) { 934 int value, next; 935 if (getMinimum(field) == (next = getGreatestMinimum(field))) { 936 return next; 937 } 938 complete(); 939 long orgTime = time; 940 set(field, next); 941 do { 942 value = next; 943 roll(field, false); 944 next = get(field); 945 } while (next < value); 946 time = orgTime; 947 areFieldsSet = false; 948 return value; 949 } 950 951 /** 952 * Returns an array of locales for which custom {@code Calendar} instances 953 * are available. 954 * <p>Note that Android does not support user-supplied locale service providers. 955 */ 956 public static synchronized Locale[] getAvailableLocales() { 957 return ICU.getAvailableCalendarLocales(); 958 } 959 960 /** 961 * Gets the first day of the week for this {@code Calendar}. 962 * 963 * @return the first day of the week. 964 */ 965 public int getFirstDayOfWeek() { 966 return firstDayOfWeek; 967 } 968 969 /** 970 * Gets the greatest minimum value of the specified field. This is the 971 * biggest value that {@code getActualMinimum} can return for any possible 972 * time. 973 * 974 * @param field 975 * the field. 976 * @return the greatest minimum value of the specified field. 977 */ 978 public abstract int getGreatestMinimum(int field); 979 980 /** 981 * Constructs a new instance of the {@code Calendar} subclass appropriate for the 982 * default {@code Locale}. 983 * 984 * @return a {@code Calendar} subclass instance set to the current date and time in 985 * the default {@code Timezone}. 986 */ 987 public static synchronized Calendar getInstance() { 988 return new GregorianCalendar(); 989 } 990 991 /** 992 * Constructs a new instance of the {@code Calendar} subclass appropriate for the 993 * specified {@code Locale}. 994 * 995 * @param locale 996 * the locale to use. 997 * @return a {@code Calendar} subclass instance set to the current date and time. 998 */ 999 public static synchronized Calendar getInstance(Locale locale) { 1000 return new GregorianCalendar(locale); 1001 } 1002 1003 /** 1004 * Constructs a new instance of the {@code Calendar} subclass appropriate for the 1005 * default {@code Locale}, using the specified {@code TimeZone}. 1006 * 1007 * @param timezone 1008 * the {@code TimeZone} to use. 1009 * @return a {@code Calendar} subclass instance set to the current date and time in 1010 * the specified timezone. 1011 */ 1012 public static synchronized Calendar getInstance(TimeZone timezone) { 1013 return new GregorianCalendar(timezone); 1014 } 1015 1016 /** 1017 * Constructs a new instance of the {@code Calendar} subclass appropriate for the 1018 * specified {@code Locale}. 1019 * 1020 * @param timezone 1021 * the {@code TimeZone} to use. 1022 * @param locale 1023 * the {@code Locale} to use. 1024 * @return a {@code Calendar} subclass instance set to the current date and time in 1025 * the specified timezone. 1026 */ 1027 public static synchronized Calendar getInstance(TimeZone timezone, Locale locale) { 1028 return new GregorianCalendar(timezone, locale); 1029 } 1030 1031 /** 1032 * Gets the smallest maximum value of the specified field. This is the 1033 * smallest value that {@code getActualMaximum()} can return for any 1034 * possible time. 1035 * 1036 * @param field 1037 * the field number. 1038 * @return the smallest maximum value of the specified field. 1039 */ 1040 public abstract int getLeastMaximum(int field); 1041 1042 /** 1043 * Gets the greatest maximum value of the specified field. This returns the 1044 * biggest value that {@code get} can return for the specified field. 1045 * 1046 * @param field 1047 * the field. 1048 * @return the greatest maximum value of the specified field. 1049 */ 1050 public abstract int getMaximum(int field); 1051 1052 /** 1053 * Gets the minimal days in the first week of the year. 1054 * 1055 * @return the minimal days in the first week of the year. 1056 */ 1057 public int getMinimalDaysInFirstWeek() { 1058 return minimalDaysInFirstWeek; 1059 } 1060 1061 /** 1062 * Gets the smallest minimum value of the specified field. this returns the 1063 * smallest value thet {@code get} can return for the specified field. 1064 * 1065 * @param field 1066 * the field number. 1067 * @return the smallest minimum value of the specified field. 1068 */ 1069 public abstract int getMinimum(int field); 1070 1071 /** 1072 * Gets the time of this {@code Calendar} as a {@code Date} object. 1073 * 1074 * @return a new {@code Date} initialized to the time of this {@code Calendar}. 1075 * 1076 * @throws IllegalArgumentException 1077 * if the time is not set and the time cannot be computed 1078 * from the current field values. 1079 */ 1080 public final Date getTime() { 1081 return new Date(getTimeInMillis()); 1082 } 1083 1084 /** 1085 * Computes the time from the fields if required and returns the time. 1086 * 1087 * @return the time of this {@code Calendar}. 1088 * 1089 * @throws IllegalArgumentException 1090 * if the time is not set and the time cannot be computed 1091 * from the current field values. 1092 */ 1093 public long getTimeInMillis() { 1094 if (!isTimeSet) { 1095 computeTime(); 1096 isTimeSet = true; 1097 } 1098 return time; 1099 } 1100 1101 /** 1102 * Gets the timezone of this {@code Calendar}. 1103 * 1104 * @return the {@code TimeZone} used by this {@code Calendar}. 1105 */ 1106 public TimeZone getTimeZone() { 1107 return zone; 1108 } 1109 1110 /** 1111 * Returns an integer hash code for the receiver. Objects which are equal 1112 * return the same value for this method. 1113 * 1114 * @return the receiver's hash. 1115 * 1116 * @see #equals 1117 */ 1118 @Override 1119 public int hashCode() { 1120 return (isLenient() ? 1237 : 1231) + getFirstDayOfWeek() 1121 + getMinimalDaysInFirstWeek() + getTimeZone().hashCode(); 1122 } 1123 1124 /** 1125 * Gets the value of the specified field without recomputing. 1126 * 1127 * @param field 1128 * the field. 1129 * @return the value of the specified field. 1130 */ 1131 protected final int internalGet(int field) { 1132 return fields[field]; 1133 } 1134 1135 /** 1136 * Returns if this {@code Calendar} accepts field values which are outside the valid 1137 * range for the field. 1138 * 1139 * @return {@code true} if this {@code Calendar} is lenient, {@code false} otherwise. 1140 */ 1141 public boolean isLenient() { 1142 return lenient; 1143 } 1144 1145 /** 1146 * Returns whether the specified field is set. Note that the interpretation of "is set" is 1147 * somewhat technical. In particular, it does <i>not</i> mean that the field's value is up 1148 * to date. If you want to know whether a field contains an up-to-date value, you must also 1149 * check {@code areFieldsSet}, making this method somewhat useless unless you're a subclass, 1150 * in which case you can access the {@code isSet} array directly. 1151 * <p> 1152 * A field remains "set" from the first time its value is computed until it's cleared by one 1153 * of the {@code clear} methods. Thus "set" does not mean "valid". You probably want to call 1154 * {@code get} -- which will update fields as necessary -- rather than try to make use of 1155 * this method. 1156 * 1157 * @param field 1158 * a {@code Calendar} field number. 1159 * @return {@code true} if the specified field is set, {@code false} otherwise. 1160 */ 1161 public final boolean isSet(int field) { 1162 return isSet[field]; 1163 } 1164 1165 /** 1166 * Adds the specified amount to the specified field and wraps the value of 1167 * the field when it goes beyond the maximum or minimum value for the 1168 * current date. Other fields will be adjusted as required to maintain a 1169 * consistent date. 1170 * 1171 * @param field 1172 * the field to roll. 1173 * @param value 1174 * the amount to add. 1175 */ 1176 public void roll(int field, int value) { 1177 boolean increment = value >= 0; 1178 int count = increment ? value : -value; 1179 for (int i = 0; i < count; i++) { 1180 roll(field, increment); 1181 } 1182 } 1183 1184 /** 1185 * Increment or decrement the specified field and wrap the value of the 1186 * field when it goes beyond the maximum or minimum value for the current 1187 * date. Other fields will be adjusted as required to maintain a consistent 1188 * date. 1189 * 1190 * @param field 1191 * the number indicating the field to roll. 1192 * @param increment 1193 * {@code true} to increment the field, {@code false} to decrement. 1194 */ 1195 public abstract void roll(int field, boolean increment); 1196 1197 /** 1198 * Sets a field to the specified value. 1199 * 1200 * @param field 1201 * the code indicating the {@code Calendar} field to modify. 1202 * @param value 1203 * the value. 1204 */ 1205 public void set(int field, int value) { 1206 fields[field] = value; 1207 isSet[field] = true; 1208 areFieldsSet = isTimeSet = false; 1209 if (field > MONTH && field < AM_PM) { 1210 lastDateFieldSet = field; 1211 } 1212 if (field == HOUR || field == HOUR_OF_DAY) { 1213 lastTimeFieldSet = field; 1214 } 1215 if (field == AM_PM) { 1216 lastTimeFieldSet = HOUR; 1217 } 1218 } 1219 1220 /** 1221 * Sets the year, month and day of the month fields. Other fields are not 1222 * changed. 1223 * 1224 * @param year 1225 * the year. 1226 * @param month 1227 * the month. 1228 * @param day 1229 * the day of the month. 1230 */ 1231 public final void set(int year, int month, int day) { 1232 set(YEAR, year); 1233 set(MONTH, month); 1234 set(DATE, day); 1235 } 1236 1237 /** 1238 * Sets the year, month, day of the month, hour of day and minute fields. 1239 * Other fields are not changed. 1240 * 1241 * @param year 1242 * the year. 1243 * @param month 1244 * the month. 1245 * @param day 1246 * the day of the month. 1247 * @param hourOfDay 1248 * the hour of day. 1249 * @param minute 1250 * the minute. 1251 */ 1252 public final void set(int year, int month, int day, int hourOfDay, 1253 int minute) { 1254 set(year, month, day); 1255 set(HOUR_OF_DAY, hourOfDay); 1256 set(MINUTE, minute); 1257 } 1258 1259 /** 1260 * Sets the year, month, day of the month, hour of day, minute and second 1261 * fields. Other fields are not changed. 1262 * 1263 * @param year 1264 * the year. 1265 * @param month 1266 * the month. 1267 * @param day 1268 * the day of the month. 1269 * @param hourOfDay 1270 * the hour of day. 1271 * @param minute 1272 * the minute. 1273 * @param second 1274 * the second. 1275 */ 1276 public final void set(int year, int month, int day, int hourOfDay, 1277 int minute, int second) { 1278 set(year, month, day, hourOfDay, minute); 1279 set(SECOND, second); 1280 } 1281 1282 /** 1283 * Sets the first day of the week for this {@code Calendar}. 1284 * 1285 * @param value 1286 * a {@code Calendar} day of the week. 1287 */ 1288 public void setFirstDayOfWeek(int value) { 1289 firstDayOfWeek = value; 1290 } 1291 1292 /** 1293 * Sets this {@code Calendar} to accept field values which are outside the valid 1294 * range for the field. 1295 * 1296 * @param value 1297 * a boolean value. 1298 */ 1299 public void setLenient(boolean value) { 1300 lenient = value; 1301 } 1302 1303 /** 1304 * Sets the minimal days in the first week of the year. 1305 * 1306 * @param value 1307 * the minimal days in the first week of the year. 1308 */ 1309 public void setMinimalDaysInFirstWeek(int value) { 1310 minimalDaysInFirstWeek = value; 1311 } 1312 1313 /** 1314 * Sets the time of this {@code Calendar}. 1315 * 1316 * @param date 1317 * a {@code Date} object. 1318 */ 1319 public final void setTime(Date date) { 1320 setTimeInMillis(date.getTime()); 1321 } 1322 1323 /** 1324 * Sets the time of this {@code Calendar}. 1325 * 1326 * @param milliseconds 1327 * the time as the number of milliseconds since Jan. 1, 1970. 1328 */ 1329 public void setTimeInMillis(long milliseconds) { 1330 if (!isTimeSet || !areFieldsSet || time != milliseconds) { 1331 time = milliseconds; 1332 isTimeSet = true; 1333 areFieldsSet = false; 1334 complete(); 1335 } 1336 } 1337 1338 /** 1339 * Sets the {@code TimeZone} used by this Calendar. 1340 * 1341 * @param timezone 1342 * a {@code TimeZone}. 1343 */ 1344 public void setTimeZone(TimeZone timezone) { 1345 zone = timezone; 1346 areFieldsSet = false; 1347 } 1348 1349 /** 1350 * Returns the string representation of this {@code Calendar}. 1351 */ 1352 @Override 1353 public String toString() { 1354 StringBuilder result = new StringBuilder(getClass().getName() + 1355 "[time=" + (isTimeSet ? String.valueOf(time) : "?") + 1356 ",areFieldsSet=" + areFieldsSet + 1357 ",lenient=" + lenient + 1358 ",zone=" + zone.getID() + 1359 ",firstDayOfWeek=" + firstDayOfWeek + 1360 ",minimalDaysInFirstWeek=" + minimalDaysInFirstWeek); 1361 for (int i = 0; i < FIELD_COUNT; i++) { 1362 result.append(','); 1363 result.append(FIELD_NAMES[i]); 1364 result.append('='); 1365 if (isSet[i]) { 1366 result.append(fields[i]); 1367 } else { 1368 result.append('?'); 1369 } 1370 } 1371 result.append(']'); 1372 return result.toString(); 1373 } 1374 1375 /** 1376 * Compares the times of the two {@code Calendar}, which represent the milliseconds 1377 * from the January 1, 1970 00:00:00.000 GMT (Gregorian). 1378 * 1379 * @param anotherCalendar 1380 * another calendar that this one is compared with. 1381 * @return 0 if the times of the two {@code Calendar}s are equal, -1 if the time of 1382 * this {@code Calendar} is before the other one, 1 if the time of this 1383 * {@code Calendar} is after the other one. 1384 * @throws NullPointerException 1385 * if the argument is null. 1386 * @throws IllegalArgumentException 1387 * if the argument does not include a valid time 1388 * value. 1389 */ 1390 public int compareTo(Calendar anotherCalendar) { 1391 if (anotherCalendar == null) { 1392 throw new NullPointerException("anotherCalendar == null"); 1393 } 1394 long timeInMillis = getTimeInMillis(); 1395 long anotherTimeInMillis = anotherCalendar.getTimeInMillis(); 1396 if (timeInMillis > anotherTimeInMillis) { 1397 return 1; 1398 } 1399 if (timeInMillis == anotherTimeInMillis) { 1400 return 0; 1401 } 1402 return -1; 1403 } 1404 1405 /** 1406 * Returns a human-readable string for the value of {@code field} 1407 * using the given style and locale. If no string is available, returns null. 1408 * The value is retrieved by invoking {@code get(field)}. 1409 * 1410 * <p>For example, {@code getDisplayName(MONTH, SHORT, Locale.US)} will return "Jan" 1411 * while {@code getDisplayName(MONTH, LONG, Locale.US)} will return "January". 1412 * 1413 * @param field the field 1414 * @param style {@code SHORT} or {@code LONG} 1415 * @param locale the locale 1416 * @return the display name, or null 1417 * @throws NullPointerException if {@code locale == null} 1418 * @throws IllegalArgumentException if {@code field} or {@code style} is invalid 1419 * @since 1.6 1420 */ 1421 public String getDisplayName(int field, int style, Locale locale) { 1422 // TODO: the RI's documentation says ALL_STYLES is invalid, but actually treats it as SHORT. 1423 if (style == ALL_STYLES) { 1424 style = SHORT; 1425 } 1426 String[] array = getDisplayNameArray(field, style, locale); 1427 int value = get(field); 1428 return (array != null) ? array[value] : null; 1429 } 1430 1431 private String[] getDisplayNameArray(int field, int style, Locale locale) { 1432 if (field < 0 || field >= FIELD_COUNT) { 1433 throw new IllegalArgumentException("bad field " + field); 1434 } 1435 checkStyle(style); 1436 DateFormatSymbols dfs = DateFormatSymbols.getInstance(locale); 1437 switch (field) { 1438 case AM_PM: 1439 return dfs.getAmPmStrings(); 1440 case DAY_OF_WEEK: 1441 return (style == LONG) ? dfs.getWeekdays() : dfs.getShortWeekdays(); 1442 case ERA: 1443 return dfs.getEras(); 1444 case MONTH: 1445 return (style == LONG) ? dfs.getMonths() : dfs.getShortMonths(); 1446 } 1447 return null; 1448 } 1449 1450 private static void checkStyle(int style) { 1451 if (style != ALL_STYLES && style != SHORT && style != LONG) { 1452 throw new IllegalArgumentException("bad style " + style); 1453 } 1454 } 1455 1456 /** 1457 * Returns a map of human-readable strings to corresponding values, 1458 * for the given field, style, and locale. 1459 * Returns null if no strings are available. 1460 * 1461 * <p>For example, {@code getDisplayNames(MONTH, ALL_STYLES, Locale.US)} would 1462 * contain mappings from "Jan" and "January" to {@link #JANUARY}, and so on. 1463 * 1464 * @param field the field 1465 * @param style {@code SHORT}, {@code LONG}, or {@code ALL_STYLES} 1466 * @param locale the locale 1467 * @return the display name, or null 1468 * @throws NullPointerException if {@code locale == null} 1469 * @throws IllegalArgumentException if {@code field} or {@code style} is invalid 1470 * @since 1.6 1471 */ 1472 public Map<String, Integer> getDisplayNames(int field, int style, Locale locale) { 1473 checkStyle(style); 1474 complete(); 1475 Map<String, Integer> result = new HashMap<String, Integer>(); 1476 if (style == SHORT || style == ALL_STYLES) { 1477 insertValuesInMap(result, getDisplayNameArray(field, SHORT, locale)); 1478 } 1479 if (style == LONG || style == ALL_STYLES) { 1480 insertValuesInMap(result, getDisplayNameArray(field, LONG, locale)); 1481 } 1482 return result.isEmpty() ? null : result; 1483 } 1484 1485 private static void insertValuesInMap(Map<String, Integer> map, String[] values) { 1486 if (values == null) { 1487 return; 1488 } 1489 for (int i = 0; i < values.length; ++i) { 1490 if (values[i] != null && !values[i].isEmpty()) { 1491 map.put(values[i], i); 1492 } 1493 } 1494 } 1495 1496 private static final ObjectStreamField[] serialPersistentFields = { 1497 new ObjectStreamField("areFieldsSet", boolean.class), 1498 new ObjectStreamField("fields", int[].class), 1499 new ObjectStreamField("firstDayOfWeek", int.class), 1500 new ObjectStreamField("isSet", boolean[].class), 1501 new ObjectStreamField("isTimeSet", boolean.class), 1502 new ObjectStreamField("lenient", boolean.class), 1503 new ObjectStreamField("minimalDaysInFirstWeek", int.class), 1504 new ObjectStreamField("nextStamp", int.class), 1505 new ObjectStreamField("serialVersionOnStream", int.class), 1506 new ObjectStreamField("time", long.class), 1507 new ObjectStreamField("zone", TimeZone.class), 1508 }; 1509 1510 private void writeObject(ObjectOutputStream stream) throws IOException { 1511 complete(); 1512 ObjectOutputStream.PutField putFields = stream.putFields(); 1513 putFields.put("areFieldsSet", areFieldsSet); 1514 putFields.put("fields", this.fields); 1515 putFields.put("firstDayOfWeek", firstDayOfWeek); 1516 putFields.put("isSet", isSet); 1517 putFields.put("isTimeSet", isTimeSet); 1518 putFields.put("lenient", lenient); 1519 putFields.put("minimalDaysInFirstWeek", minimalDaysInFirstWeek); 1520 putFields.put("nextStamp", 2 /* MINIMUM_USER_STAMP */); 1521 putFields.put("serialVersionOnStream", 1); 1522 putFields.put("time", time); 1523 putFields.put("zone", zone); 1524 stream.writeFields(); 1525 } 1526 1527 private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { 1528 ObjectInputStream.GetField readFields = stream.readFields(); 1529 areFieldsSet = readFields.get("areFieldsSet", false); 1530 this.fields = (int[]) readFields.get("fields", null); 1531 firstDayOfWeek = readFields.get("firstDayOfWeek", Calendar.SUNDAY); 1532 isSet = (boolean[]) readFields.get("isSet", null); 1533 isTimeSet = readFields.get("isTimeSet", false); 1534 lenient = readFields.get("lenient", true); 1535 minimalDaysInFirstWeek = readFields.get("minimalDaysInFirstWeek", 1); 1536 time = readFields.get("time", 0L); 1537 zone = (TimeZone) readFields.get("zone", null); 1538 } 1539 } 1540