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