Home | History | Annotate | Download | only in util
      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  * &lt; 24:00 on Jan 1, 1970 &lt; 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) &lt; 12:01 am,
    146  * and 12:00 pm (noon) &lt; 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 &nbsp; 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 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