Home | History | Annotate | Download | only in text
      1 //  2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html#License
      3 /*
      4  *   Copyright (C) 1996-2016, International Business Machines
      5  *   Corporation and others.  All Rights Reserved.
      6  */
      7 
      8 package com.ibm.icu.text;
      9 
     10 import java.io.IOException;
     11 import java.io.InvalidObjectException;
     12 import java.io.ObjectInputStream;
     13 import java.text.FieldPosition;
     14 import java.text.Format;
     15 import java.text.ParseException;
     16 import java.text.ParsePosition;
     17 import java.util.Arrays;
     18 import java.util.Date;
     19 import java.util.EnumSet;
     20 import java.util.HashMap;
     21 import java.util.List;
     22 import java.util.Locale;
     23 import java.util.Map;
     24 import java.util.MissingResourceException;
     25 
     26 import com.ibm.icu.impl.ICUResourceBundle;
     27 import com.ibm.icu.impl.RelativeDateFormat;
     28 import com.ibm.icu.util.Calendar;
     29 import com.ibm.icu.util.GregorianCalendar;
     30 import com.ibm.icu.util.TimeZone;
     31 import com.ibm.icu.util.ULocale;
     32 import com.ibm.icu.util.ULocale.Category;
     33 
     34 /**
     35  * {@icuenhanced java.text.DateFormat}.{@icu _usage_}
     36  *
     37  * <p>
     38  * DateFormat is an abstract class for date/time formatting subclasses which formats and parses dates or time in a
     39  * language-independent manner. The date/time formatting subclass, such as SimpleDateFormat, allows for formatting
     40  * (i.e., date -&gt; text), parsing (text -&gt; date), and normalization. The date is represented as a <code>Date</code>
     41  * object or as the milliseconds since January 1, 1970, 00:00:00 GMT.
     42  *
     43  * <p>
     44  * DateFormat helps you to format and parse dates for any locale. Your code can be completely independent of the locale
     45  * conventions for months, days of the week, or even the calendar format: lunar vs. solar. It provides many class
     46  * methods for obtaining default date/time formatters based on the default for a given locale and a number of formatting
     47  * styles or arbitrary "skeletons".
     48  * <ol>
     49  * <li>The formatting styles include FULL, LONG, MEDIUM, and SHORT. More detail and examples of using these styles are
     50  * provided in the method descriptions.
     51  * <li>The formatting styles only cover a fraction of the necessary usage. You often need to have just certain
     52  * combinations of fields, like Month and Year, but have it to be formatted appropriate to a given locale. This is done
     53  * using the (misnamed) getPatternInstance() method, supplying a skeleton. There are a number of constants that have
     54  * common pre-defined skeletons, such as {@link #MINUTE_SECOND} for something like "13:45" or {@link #YEAR_ABBR_MONTH}
     55  * for something like "Sept 2012".
     56  * </ol>
     57  *
     58  * <p>
     59  * To format a date for the current Locale, use one of the static factory methods:
     60  *
     61  * <pre>
     62  * myString = DateFormat.getDateInstance().format(myDate);
     63  * myString = DateFormat.getPatternInstance(DateFormat.YEAR_ABBR_MONTH).format(myDate);
     64  * </pre>
     65  * <p>
     66  * If you are formatting multiple numbers, it is more efficient to get the format and use it multiple times so that the
     67  * system doesn't have to fetch the information about the local language and country conventions multiple times.
     68  *
     69  * <pre>
     70  * DateFormat df = DateFormat.getDateInstance();
     71  * for (int i = 0; i &lt; a.length; ++i) {
     72  *     output.println(df.format(myDate[i]) + &quot;; &quot;);
     73  * }
     74  * </pre>
     75  * <p>
     76  * To format a date for a different Locale, specify it in the call to getDateInstance().
     77  *
     78  * <pre>
     79  * DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);
     80  * </pre>
     81  * <p>
     82  * You can use a DateFormat to parse also.
     83  *
     84  * <pre>
     85  * myDate = df.parse(myString);
     86  * </pre>
     87  * <p>
     88  * There are many static factory methods available. Use getDateInstance to get the normal date format for that country.
     89  * Use getTimeInstance to get the time format for that country. Use getDateTimeInstance to get a date and time format.
     90  * You can pass in different options to these factory methods to control the length of the result; from SHORT to MEDIUM
     91  * to LONG to FULL. The exact result depends on the locale, but generally:
     92  * <ul>
     93  * <li>SHORT is completely numeric, such as 12.13.52 or 3:30pm
     94  * <li>MEDIUM is longer, such as Jan 12, 1952
     95  * <li>LONG is longer, such as January 12, 1952 or 3:30:32pm
     96  * <li>FULL is pretty completely specified, such as Tuesday, April 12, 1952 AD or 3:30:42pm PST.
     97  * </ul>
     98  *
     99  * <p>
    100  * Use getPatternInstance to format with a skeleton. Typically this is with a predefined skeleton, like
    101  * {@link #YEAR_ABBR_MONTH} for something like "Sept 2012". If you don't want to use one of the predefined skeletons,
    102  * you can supply your own. The skeletons are like the patterns in SimpleDateFormat, except they:
    103  * <ol>
    104  * <li>only keep the field pattern letter and ignore all other parts in a pattern, such as space, punctuation, and
    105  * string literals.
    106  * <li>are independent of the order of fields.
    107  * <li>ignore certain differences in the field's pattern letter length:
    108  * <ol>
    109  * <li>For those non-digit calendar fields, the pattern letter length is important, such as MMM, MMMM, and MMMMM; E and
    110  * EEEE, and the field's pattern letter length is honored.
    111  * <li>For the digit calendar fields, such as M or MM, d or dd, yy or yyyy, the field pattern length is ignored and the
    112  * best match, which is defined in date time patterns, will be returned without honor the field pattern letter length in
    113  * skeleton.
    114  * </ol>
    115  * </ol>
    116  *
    117  * <p>
    118  * You can also set the time zone on the format if you wish. If you want even more control over the format or parsing,
    119  * (or want to give your users more control), you can try casting the DateFormat you get from the factory methods to a
    120  * SimpleDateFormat. This will work for the majority of countries; just remember to put it in a try block in case you
    121  * encounter an unusual one.
    122  *
    123  * <p>
    124  * You can also use forms of the parse and format methods with ParsePosition and FieldPosition to allow you to
    125  * <ul>
    126  * <li>progressively parse through pieces of a string.
    127  * <li>align any particular field, or find out where it is for selection on the screen.
    128  * </ul>
    129  *
    130  * <h3>Synchronization</h3>
    131  *
    132  * Date formats are not synchronized. It is recommended to create separate format instances for each thread. If multiple
    133  * threads access a format concurrently, it must be synchronized externally.
    134  *
    135  * @see UFormat
    136  * @see NumberFormat
    137  * @see SimpleDateFormat
    138  * @see com.ibm.icu.util.Calendar
    139  * @see com.ibm.icu.util.GregorianCalendar
    140  * @see com.ibm.icu.util.TimeZone
    141  * @author Mark Davis, Chen-Lieh Huang, Alan Liu
    142  * @stable ICU 2.0
    143  */
    144 public abstract class DateFormat extends UFormat {
    145 
    146     /**
    147      * The calendar that <code>DateFormat</code> uses to produce the time field
    148      * values needed to implement date and time formatting.  Subclasses should
    149      * initialize this to a calendar appropriate for the locale associated with
    150      * this <code>DateFormat</code>.
    151      * @serial
    152      * @stable ICU 2.0
    153      */
    154     protected Calendar calendar;
    155 
    156     /**
    157      * The number formatter that <code>DateFormat</code> uses to format numbers
    158      * in dates and times.  Subclasses should initialize this to a number format
    159      * appropriate for the locale associated with this <code>DateFormat</code>.
    160      * @serial
    161      * @stable ICU 2.0
    162      */
    163     protected NumberFormat numberFormat;
    164 
    165     /**
    166      * FieldPosition selector for 'G' field alignment,
    167      * corresponding to the {@link Calendar#ERA} field.
    168      * @stable ICU 2.0
    169      */
    170     public final static int ERA_FIELD = 0;
    171 
    172     /**
    173      * FieldPosition selector for 'y' field alignment,
    174      * corresponding to the {@link Calendar#YEAR} field.
    175      * @stable ICU 2.0
    176      */
    177     public final static int YEAR_FIELD = 1;
    178 
    179     /**
    180      * FieldPosition selector for 'M' field alignment,
    181      * corresponding to the {@link Calendar#MONTH} field.
    182      * @stable ICU 2.0
    183      */
    184     public final static int MONTH_FIELD = 2;
    185 
    186     /**
    187      * FieldPosition selector for 'd' field alignment,
    188      * corresponding to the {@link Calendar#DATE} field.
    189      * @stable ICU 2.0
    190      */
    191     public final static int DATE_FIELD = 3;
    192 
    193     /**
    194      * FieldPosition selector for 'k' field alignment,
    195      * corresponding to the {@link Calendar#HOUR_OF_DAY} field.
    196      * HOUR_OF_DAY1_FIELD is used for the one-based 24-hour clock.
    197      * For example, 23:59 + 01:00 results in 24:59.
    198      * @stable ICU 2.0
    199      */
    200     public final static int HOUR_OF_DAY1_FIELD = 4;
    201 
    202     /**
    203      * FieldPosition selector for 'H' field alignment,
    204      * corresponding to the {@link Calendar#HOUR_OF_DAY} field.
    205      * HOUR_OF_DAY0_FIELD is used for the zero-based 24-hour clock.
    206      * For example, 23:59 + 01:00 results in 00:59.
    207      * @stable ICU 2.0
    208      */
    209     public final static int HOUR_OF_DAY0_FIELD = 5;
    210 
    211     /**
    212      * FieldPosition selector for 'm' field alignment,
    213      * corresponding to the {@link Calendar#MINUTE} field.
    214      * @stable ICU 2.0
    215      */
    216     public final static int MINUTE_FIELD = 6;
    217 
    218     /**
    219      * FieldPosition selector for 's' field alignment,
    220      * corresponding to the {@link Calendar#SECOND} field.
    221      * @stable ICU 2.0
    222      */
    223     public final static int SECOND_FIELD = 7;
    224 
    225     /**
    226      * {@icu} FieldPosition selector for 'S' field alignment,
    227      * corresponding to the {@link Calendar#MILLISECOND} field.
    228      *
    229      * Note: Time formats that use 'S' can display a maximum of three
    230      * significant digits for fractional seconds, corresponding to millisecond
    231      * resolution and a fractional seconds sub-pattern of SSS. If the
    232      * sub-pattern is S or SS, the fractional seconds value will be truncated
    233      * (not rounded) to the number of display places specified. If the
    234      * fractional seconds sub-pattern is longer than SSS, the additional
    235      * display places will be filled with zeros.
    236      * @stable ICU 3.0
    237      */
    238     public final static int FRACTIONAL_SECOND_FIELD = 8;
    239 
    240     /**
    241      * Alias for FRACTIONAL_SECOND_FIELD.
    242      * @stable ICU 3.0
    243      */
    244     public final static int MILLISECOND_FIELD = FRACTIONAL_SECOND_FIELD;
    245 
    246     /**
    247      * FieldPosition selector for 'E' field alignment,
    248      * corresponding to the {@link Calendar#DAY_OF_WEEK} field.
    249      * @stable ICU 2.0
    250      */
    251     public final static int DAY_OF_WEEK_FIELD = 9;
    252 
    253     /**
    254      * FieldPosition selector for 'D' field alignment,
    255      * corresponding to the {@link Calendar#DAY_OF_YEAR} field.
    256      * @stable ICU 2.0
    257      */
    258     public final static int DAY_OF_YEAR_FIELD = 10;
    259 
    260     /**
    261      * FieldPosition selector for 'F' field alignment,
    262      * corresponding to the {@link Calendar#DAY_OF_WEEK_IN_MONTH} field.
    263      * @stable ICU 2.0
    264      */
    265     public final static int DAY_OF_WEEK_IN_MONTH_FIELD = 11;
    266 
    267     /**
    268      * FieldPosition selector for 'w' field alignment,
    269      * corresponding to the {@link Calendar#WEEK_OF_YEAR} field.
    270      * @stable ICU 2.0
    271      */
    272     public final static int WEEK_OF_YEAR_FIELD = 12;
    273 
    274     /**
    275      * FieldPosition selector for 'W' field alignment,
    276      * corresponding to the {@link Calendar#WEEK_OF_MONTH} field.
    277      * @stable ICU 2.0
    278      */
    279     public final static int WEEK_OF_MONTH_FIELD = 13;
    280 
    281     /**
    282      * FieldPosition selector for 'a' field alignment,
    283      * corresponding to the {@link Calendar#AM_PM} field.
    284      * @stable ICU 2.0
    285      */
    286     public final static int AM_PM_FIELD = 14;
    287 
    288     /**
    289      * FieldPosition selector for 'h' field alignment,
    290      * corresponding to the {@link Calendar#HOUR} field.
    291      * HOUR1_FIELD is used for the one-based 12-hour clock.
    292      * For example, 11:30 PM + 1 hour results in 12:30 AM.
    293      * @stable ICU 2.0
    294      */
    295     public final static int HOUR1_FIELD = 15;
    296 
    297     /**
    298      * FieldPosition selector for 'K' field alignment,
    299      * corresponding to the {@link Calendar#HOUR} field.
    300      * HOUR0_FIELD is used for the zero-based 12-hour clock.
    301      * For example, 11:30 PM + 1 hour results in 00:30 AM.
    302      * @stable ICU 2.0
    303      */
    304     public final static int HOUR0_FIELD = 16;
    305 
    306     /**
    307      * FieldPosition selector for 'z' field alignment,
    308      * corresponding to the {@link Calendar#ZONE_OFFSET} and
    309      * {@link Calendar#DST_OFFSET} fields.
    310      * @stable ICU 2.0
    311      */
    312     public final static int TIMEZONE_FIELD = 17;
    313 
    314     /**
    315      * {@icu} FieldPosition selector for 'Y' field alignment,
    316      * corresponding to the {@link Calendar#YEAR_WOY} field.
    317      * @stable ICU 3.0
    318      */
    319     public final static int YEAR_WOY_FIELD = 18;
    320 
    321     /**
    322      * {@icu} FieldPosition selector for 'e' field alignment,
    323      * corresponding to the {@link Calendar#DOW_LOCAL} field.
    324      * @stable ICU 3.0
    325      */
    326     public final static int DOW_LOCAL_FIELD = 19;
    327 
    328     /**
    329      * {@icu} FieldPosition selector for 'u' field alignment,
    330      * corresponding to the {@link Calendar#EXTENDED_YEAR} field.
    331      * @stable ICU 3.0
    332      */
    333     public final static int EXTENDED_YEAR_FIELD = 20;
    334 
    335     /**
    336      * {@icu} FieldPosition selector for 'g' field alignment,
    337      * corresponding to the {@link Calendar#JULIAN_DAY} field.
    338      * @stable ICU 3.0
    339      */
    340     public final static int JULIAN_DAY_FIELD = 21;
    341 
    342     /**
    343      * {@icu} FieldPosition selector for 'A' field alignment,
    344      * corresponding to the {@link Calendar#MILLISECONDS_IN_DAY} field.
    345      * @stable ICU 3.0
    346      */
    347     public final static int MILLISECONDS_IN_DAY_FIELD = 22;
    348 
    349     /**
    350      * {@icu} FieldPosition selector for 'Z' field alignment,
    351      * corresponding to the {@link Calendar#ZONE_OFFSET} and
    352      * {@link Calendar#DST_OFFSET} fields.
    353      * @stable ICU 3.0
    354      */
    355     public final static int TIMEZONE_RFC_FIELD = 23;
    356 
    357     /**
    358      * {@icu} FieldPosition selector for 'v' field alignment,
    359      * corresponding to the {@link Calendar#ZONE_OFFSET} and
    360      * {@link Calendar#DST_OFFSET} fields.  This displays the generic zone
    361      * name, if available.
    362      * @stable ICU 3.4
    363      */
    364     public final static int TIMEZONE_GENERIC_FIELD = 24;
    365 
    366     /**
    367      * {@icu} FieldPosition selector for 'c' field alignment,
    368      * corresponding to the {@link Calendar#DAY_OF_WEEK} field.
    369      * This displays the stand alone day name, if available.
    370      * @stable ICU 3.4
    371      */
    372     public final static int STANDALONE_DAY_FIELD = 25;
    373 
    374     /**
    375      * {@icu} FieldPosition selector for 'L' field alignment,
    376      * corresponding to the {@link Calendar#MONTH} field.
    377      * This displays the stand alone month name, if available.
    378      * @stable ICU 3.4
    379      */
    380     public final static int STANDALONE_MONTH_FIELD = 26;
    381 
    382     /**
    383      * {@icu} FieldPosition selector for 'Q' field alignment,
    384      * corresponding to the {@link Calendar#MONTH} field.
    385      * This displays the quarter.
    386      * @stable ICU 3.6
    387      */
    388     public final static int QUARTER_FIELD = 27;
    389 
    390     /**
    391      * {@icu} FieldPosition selector for 'q' field alignment,
    392      * corresponding to the {@link Calendar#MONTH} field.
    393      * This displays the stand alone quarter, if available.
    394      * @stable ICU 3.6
    395      */
    396     public final static int STANDALONE_QUARTER_FIELD = 28;
    397 
    398     /**
    399      * {@icu} FieldPosition selector for 'V' field alignment,
    400      * corresponding to the {@link Calendar#ZONE_OFFSET} and
    401      * {@link Calendar#DST_OFFSET} fields.  This displays the fallback timezone
    402      * name when VVVV is specified, and the short standard or daylight
    403      * timezone name ignoring commonlyUsed when a single V is specified.
    404      * @stable ICU 3.8
    405      */
    406     public final static int TIMEZONE_SPECIAL_FIELD = 29;
    407 
    408     /**
    409      * {@icu} FieldPosition selector for 'U' field alignment,
    410      * corresponding to the {@link Calendar#YEAR} field.
    411      * This displays the cyclic year name, if available.
    412      * @stable ICU 49
    413      */
    414     public final static int YEAR_NAME_FIELD = 30;
    415 
    416     /**
    417      * {@icu} FieldPosition selector for 'O' field alignment,
    418      * corresponding to the {@link Calendar#ZONE_OFFSET} and
    419      * {@link Calendar#DST_OFFSET} fields.  This displays the
    420      * localized GMT format.
    421      * @stable ICU 51
    422      */
    423     public final static int TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD = 31;
    424 
    425     /**
    426      * {@icu} FieldPosition selector for 'X' field alignment,
    427      * corresponding to the {@link Calendar#ZONE_OFFSET} and
    428      * {@link Calendar#DST_OFFSET} fields.  This displays the
    429      * ISO 8601 local time offset format or UTC indicator ("Z").
    430      * @stable ICU 51
    431      */
    432     public final static int TIMEZONE_ISO_FIELD = 32;
    433 
    434     /**
    435      * {@icu} FieldPosition selector for 'x' field alignment,
    436      * corresponding to the {@link Calendar#ZONE_OFFSET} and
    437      * {@link Calendar#DST_OFFSET} fields.  This displays the
    438      * ISO 8601 local time offset format.
    439      * @stable ICU 51
    440      */
    441     public final static int TIMEZONE_ISO_LOCAL_FIELD = 33;
    442 
    443     /**
    444      * {@icu} FieldPosition selector for 'r' field alignment,
    445      * corresponding to the {@link Calendar#EXTENDED_YEAR} field
    446      * of the *related* calendar which may be different than the
    447      * one used by the DateFormat.
    448      * @internal
    449      * @deprecated This API is ICU internal only.
    450      */
    451     @Deprecated
    452     final static int RELATED_YEAR = 34;
    453 
    454     /**
    455      * {@icu} FieldPosition selector for 'b' field alignment.
    456      * No related Calendar field.
    457      * This displays the fixed day period (am/pm/midnight/noon).
    458      * @stable ICU 59
    459      */
    460     public final static int AM_PM_MIDNIGHT_NOON_FIELD = 35;
    461 
    462     /**
    463      * {@icu} FieldPosition selector for 'B' field alignment.
    464      * No related Calendar field.
    465      * This displays the flexible day period.
    466      * @stable ICU 59
    467      */
    468     public final static int FLEXIBLE_DAY_PERIOD_FIELD = 36;
    469 
    470     /**
    471      * {@icu} FieldPosition selector time separator,
    472      * no related Calendar field. No pattern character is currently
    473      * defined for this.
    474      * @internal
    475      * @deprecated This API is ICU internal only.
    476      */
    477     @Deprecated
    478     public final static int TIME_SEPARATOR = 37;
    479 
    480     /**
    481      * {@icu} Number of FieldPosition selectors for DateFormat.
    482      * Valid selectors range from 0 to FIELD_COUNT-1.
    483      * @deprecated ICU 58 The numeric value may change over time, see ICU ticket #12420.
    484      */
    485     @Deprecated
    486     public final static int FIELD_COUNT = 38;
    487     // A previous comment for the above stated that we must have
    488     // DateFormat.FIELD_COUNT == DateFormatSymbols.patternChars.length()
    489     // but that does not seem to be the case, and in fact since there is
    490     // no pattern character currently defined for TIME_SEPARATOR it is
    491     // currently the case that
    492     // DateFormat.FIELD_COUNT == DateFormatSymbols.patternChars.length() + 1
    493 
    494 
    495     /**
    496      * boolean attributes
    497      *
    498      * @stable ICU 53
    499      */
    500     public enum BooleanAttribute {
    501         /**
    502          * indicates whitespace tolerance. Also included is trailing dot tolerance.
    503          * @stable ICU 53
    504          */
    505         PARSE_ALLOW_WHITESPACE,
    506         /**
    507          * indicates tolerance of numeric data when String data may be assumed.
    508          * e.g. YEAR_NAME_FIELD
    509          * @stable ICU 53
    510          */
    511         PARSE_ALLOW_NUMERIC,
    512         /**
    513          * indicates tolerance of pattern mismatch between input data and specified format pattern.
    514          * e.g. accepting "September" for a month pattern of MMM ("Sep")
    515          * @stable ICU 56
    516          */
    517         PARSE_MULTIPLE_PATTERNS_FOR_MATCH,
    518         /**
    519          * indicates tolerance of a partial literal match
    520          * e.g. accepting "--mon-02-march-2011" for a pattern of "'--: 'EEE-WW-MMMM-yyyy"
    521          * @stable ICU 56
    522          */
    523         PARSE_PARTIAL_LITERAL_MATCH,
    524         /**
    525          * alias of PARSE_PARTIAL_LITERAL_MATCH
    526          * @internal
    527          * @deprecated
    528          */
    529         @Deprecated
    530         PARSE_PARTIAL_MATCH
    531     };
    532 
    533     /**
    534      * boolean attributes for this instance. Inclusion in this is indicates a true condition.
    535      */
    536     private EnumSet<BooleanAttribute> booleanAttributes = EnumSet.allOf(BooleanAttribute.class);
    537 
    538     /*
    539      * Capitalization setting, hoisted to DateFormat ICU 53
    540      * Note that SimpleDateFormat serialization may call getContext/setContext to read/write
    541      * this for compatibility with serialization for its old copy of capitalizationSetting.
    542      * @serial
    543      */
    544     private DisplayContext capitalizationSetting = DisplayContext.CAPITALIZATION_NONE;
    545 
    546     static final int currentSerialVersion = 1;
    547 
    548     /**
    549      * Describes the version of <code>DateFormat</code> present on the stream.
    550      * Possible values are:
    551      * <ul>
    552      * <li><b>0</b> (or uninitialized): the pre-ICU-53 version
    553      *
    554      * <li><b>1</b>: ICU 53, adds serialVersionOnStream and capitalizationSetting
    555      * </ul>
    556      * When streaming out a <code>DateFormat</code>, the most recent format
    557      * (corresponding to the highest allowable <code>serialVersionOnStream</code>)
    558      * is always written.
    559      *
    560      * @serial
    561      */
    562     private int serialVersionOnStream = currentSerialVersion;
    563 
    564     // Proclaim serial compatibility with 1.1 FCS
    565     private static final long serialVersionUID = 7218322306649953788L;
    566 
    567     /**
    568      * Formats a time object into a time string. Examples of time objects
    569      * are a time value expressed in milliseconds and a Date object.
    570      * @param obj must be a Number or a Date or a Calendar.
    571      * @param toAppendTo the string buffer for the returning time string.
    572      * @return the formatted time string.
    573      * @param fieldPosition keeps track of the position of the field
    574      * within the returned string.
    575      * On input: an alignment field,
    576      * if desired. On output: the offsets of the alignment field. For
    577      * example, given a time text "1996.07.10 AD at 15:08:56 PDT",
    578      * if the given fieldPosition is DateFormat.YEAR_FIELD, the
    579      * begin index and end index of fieldPosition will be set to
    580      * 0 and 4, respectively.
    581      * Notice that if the same time field appears
    582      * more than once in a pattern, the fieldPosition will be set for the first
    583      * occurrence of that time field. For instance, formatting a Date to
    584      * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern
    585      * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD,
    586      * the begin index and end index of fieldPosition will be set to
    587      * 5 and 8, respectively, for the first occurrence of the timezone
    588      * pattern character 'z'.
    589      * @see java.text.Format
    590      * @stable ICU 2.0
    591      */
    592     @Override
    593     public final StringBuffer format(Object obj, StringBuffer toAppendTo,
    594                                      FieldPosition fieldPosition)
    595     {
    596         if (obj instanceof Calendar)
    597             return format( (Calendar)obj, toAppendTo, fieldPosition );
    598         else if (obj instanceof Date)
    599             return format( (Date)obj, toAppendTo, fieldPosition );
    600         else if (obj instanceof Number)
    601             return format( new Date(((Number)obj).longValue()),
    602                           toAppendTo, fieldPosition );
    603         else
    604             throw new IllegalArgumentException("Cannot format given Object (" +
    605                                                obj.getClass().getName() + ") as a Date");
    606     }
    607 
    608     /**
    609      * Formats a date into a date/time string.
    610      * @param cal a Calendar set to the date and time to be formatted
    611      * into a date/time string.  When the calendar type is different from
    612      * the internal calendar held by this DateFormat instance, the date
    613      * and the time zone will be inherited from the input calendar, but
    614      * other calendar field values will be calculated by the internal calendar.
    615      * @param toAppendTo the string buffer for the returning date/time string.
    616      * @param fieldPosition keeps track of the position of the field
    617      * within the returned string.
    618      * On input: an alignment field,
    619      * if desired. On output: the offsets of the alignment field. For
    620      * example, given a time text "1996.07.10 AD at 15:08:56 PDT",
    621      * if the given fieldPosition is DateFormat.YEAR_FIELD, the
    622      * begin index and end index of fieldPosition will be set to
    623      * 0 and 4, respectively.
    624      * Notice that if the same time field appears
    625      * more than once in a pattern, the fieldPosition will be set for the first
    626      * occurrence of that time field. For instance, formatting a Date to
    627      * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern
    628      * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD,
    629      * the begin index and end index of fieldPosition will be set to
    630      * 5 and 8, respectively, for the first occurrence of the timezone
    631      * pattern character 'z'.
    632      * @return the formatted date/time string.
    633      * @stable ICU 2.0
    634      */
    635     public abstract StringBuffer format(Calendar cal, StringBuffer toAppendTo,
    636                                         FieldPosition fieldPosition);
    637 
    638     /**
    639      * Formats a Date into a date/time string.
    640      * @param date a Date to be formatted into a date/time string.
    641      * @param toAppendTo the string buffer for the returning date/time string.
    642      * @param fieldPosition keeps track of the position of the field
    643      * within the returned string.
    644      * On input: an alignment field,
    645      * if desired. On output: the offsets of the alignment field. For
    646      * example, given a time text "1996.07.10 AD at 15:08:56 PDT",
    647      * if the given fieldPosition is DateFormat.YEAR_FIELD, the
    648      * begin index and end index of fieldPosition will be set to
    649      * 0 and 4, respectively.
    650      * Notice that if the same time field appears
    651      * more than once in a pattern, the fieldPosition will be set for the first
    652      * occurrence of that time field. For instance, formatting a Date to
    653      * the time string "1 PM PDT (Pacific Daylight Time)" using the pattern
    654      * "h a z (zzzz)" and the alignment field DateFormat.TIMEZONE_FIELD,
    655      * the begin index and end index of fieldPosition will be set to
    656      * 5 and 8, respectively, for the first occurrence of the timezone
    657      * pattern character 'z'.
    658      * @return the formatted date/time string.
    659      * @stable ICU 2.0
    660      */
    661     public StringBuffer format(Date date, StringBuffer toAppendTo,
    662                                      FieldPosition fieldPosition) {
    663         // Use our Calendar object
    664         calendar.setTime(date);
    665         return format(calendar, toAppendTo, fieldPosition);
    666     }
    667 
    668     /**
    669      * Formats a Date into a date/time string.
    670      * @param date the time value to be formatted into a time string.
    671      * @return the formatted time string.
    672      * @stable ICU 2.0
    673      */
    674     public final String format(Date date)
    675     {
    676         return format(date, new StringBuffer(64),new FieldPosition(0)).toString();
    677     }
    678 
    679     /**
    680      * Parses a date/time string. For example, a time text "07/10/96 4:5 PM, PDT"
    681      * will be parsed into a Date that is equivalent to Date(837039928046).
    682      * Parsing begins at the beginning of the string and proceeds as far as
    683      * possible.  Assuming no parse errors were encountered, this function
    684      * doesn't return any information about how much of the string was consumed
    685      * by the parsing.  If you need that information, use a version of
    686      * parse() that takes a ParsePosition.
    687      *
    688      * <p> By default, parsing is lenient: If the input is not in the form used
    689      * by this object's format method but can still be parsed as a date, then
    690      * the parse succeeds.  Clients may insist on strict adherence to the
    691      * format by calling setLenient(false).
    692      *
    693      * <p> Note that the normal date formats associated with some calendars - such
    694      * as the Chinese lunar calendar - do not specify enough fields to enable
    695      * dates to be parsed unambiguously. In the case of the Chinese lunar
    696      * calendar, while the year within the current 60-year cycle is specified,
    697      * the number of such cycles since the start date of the calendar (in the
    698      * ERA field of the Calendar object) is not normally part of the format,
    699      * and parsing may assume the wrong era. For cases such as this it is
    700      * recommended that clients parse using the parse method that takes a Calendar
    701      * with the Calendar passed in set to the current date, or to a date
    702      * within the era/cycle that should be assumed if absent in the format.
    703      *
    704      * @param text  The date/time string to be parsed
    705      *
    706      * @return      A Date, or null if the input could not be parsed
    707      *
    708      * @exception  ParseException  If the given string cannot be parsed as a date.
    709      *
    710      * @see #parse(String, ParsePosition)
    711      * @stable ICU 2.0
    712      */
    713     public Date parse(String text) throws ParseException
    714     {
    715         ParsePosition pos = new ParsePosition(0);
    716         Date result = parse(text, pos);
    717         if (pos.getIndex() == 0) // ICU4J
    718             throw new ParseException("Unparseable date: \"" + text + "\"" ,
    719                                      pos.getErrorIndex()); // ICU4J
    720         return result;
    721     }
    722 
    723     /**
    724      * Parses a date/time string according to the given parse position.
    725      * For example, a time text "07/10/96 4:5 PM, PDT" will be parsed
    726      * into a Calendar that is equivalent to Date(837039928046). Before
    727      * calling this method the caller should initialize the calendar
    728      * in one of two ways (unless existing field information is to be kept):
    729      * (1) clear the calendar, or (2) set the calendar to the current date
    730      * (or to any date whose fields should be used to supply values that
    731      * are missing in the parsed date). For example, Chinese calendar dates
    732      * do not normally provide an era/cycle; in this case the calendar that
    733      * is passed in should be set to a date within the era that should be
    734      * assumed, normally the current era.
    735      *
    736      * <p> By default, parsing is lenient: If the input is not in the form used
    737      * by this object's format method but can still be parsed as a date, then
    738      * the parse succeeds.  Clients may insist on strict adherence to the
    739      * format by calling setLenient(false).
    740      *
    741      * @see #setLenient(boolean)
    742      *
    743      * @param text  The date/time string to be parsed
    744      *
    745      * @param cal   The calendar set on input to the date and time to be used
    746      *              for missing values in the date/time string being parsed,
    747      *              and set on output to the parsed date/time. In general, this
    748      *              should be initialized before calling this method - either
    749      *              cleared or set to the current date, depending on desired
    750      *              behavior. If this parse fails, the calendar may still
    751      *              have been modified. When the calendar type is different
    752      *              from the internal calendar held by this DateFormat
    753      *              instance, calendar field values will be parsed based
    754      *              on the internal calendar initialized with the time and
    755      *              the time zone taken from this calendar, then the
    756      *              parse result (time in milliseconds and time zone) will
    757      *              be set back to this calendar.
    758      *
    759      * @param pos   On input, the position at which to start parsing; on
    760      *              output, the position at which parsing terminated, or the
    761      *              start position if the parse failed.
    762      * @stable ICU 2.0
    763      */
    764     public abstract void parse(String text, Calendar cal, ParsePosition pos);
    765 
    766     /**
    767      * Parses a date/time string according to the given parse position.  For
    768      * example, a time text "07/10/96 4:5 PM, PDT" will be parsed into a Date
    769      * that is equivalent to Date(837039928046).
    770      *
    771      * <p> By default, parsing is lenient: If the input is not in the form used
    772      * by this object's format method but can still be parsed as a date, then
    773      * the parse succeeds.  Clients may insist on strict adherence to the
    774      * format by calling setLenient(false).
    775      *
    776      * <p> Note that the normal date formats associated with some calendars - such
    777      * as the Chinese lunar calendar - do not specify enough fields to enable
    778      * dates to be parsed unambiguously. In the case of the Chinese lunar
    779      * calendar, while the year within the current 60-year cycle is specified,
    780      * the number of such cycles since the start date of the calendar (in the
    781      * ERA field of the Calendar object) is not normally part of the format,
    782      * and parsing may assume the wrong era. For cases such as this it is
    783      * recommended that clients parse using the parse method that takes a Calendar
    784      * with the Calendar passed in set to the current date, or to a date
    785      * within the era/cycle that should be assumed if absent in the format.
    786      *
    787      * @see #setLenient(boolean)
    788      *
    789      * @param text  The date/time string to be parsed
    790      *
    791      * @param pos   On input, the position at which to start parsing; on
    792      *              output, the position at which parsing terminated, or the
    793      *              start position if the parse failed.
    794      *
    795      * @return      A Date, or null if the input could not be parsed
    796      * @stable ICU 2.0
    797      */
    798     public Date parse(String text, ParsePosition pos) {
    799         Date result = null;
    800         int start = pos.getIndex();
    801         TimeZone tzsav = calendar.getTimeZone();
    802         calendar.clear();
    803         parse(text, calendar, pos);
    804         if (pos.getIndex() != start) {
    805             try {
    806                 result = calendar.getTime();
    807             } catch (IllegalArgumentException e) {
    808                 // This occurs if the calendar is non-lenient and there is
    809                 // an out-of-range field.  We don't know which field was
    810                 // illegal so we set the error index to the start.
    811                 pos.setIndex(start);
    812                 pos.setErrorIndex(start);
    813             }
    814         }
    815         // Restore TimeZone
    816         calendar.setTimeZone(tzsav);
    817         return result;
    818     }
    819 
    820     /**
    821      * Parses a date/time string into an Object.  This convenience method simply
    822      * calls parse(String, ParsePosition).
    823      *
    824      * @see #parse(String, ParsePosition)
    825      * @stable ICU 2.0
    826      */
    827     @Override
    828     public Object parseObject (String source, ParsePosition pos)
    829     {
    830         return parse(source, pos);
    831     }
    832 
    833     /**
    834      * {@icu} Constant for empty style pattern.
    835      * @stable ICU 3.8
    836      */
    837     public static final int NONE = -1;
    838 
    839     /**
    840      * Constant for full style pattern.
    841      * @stable ICU 2.0
    842      */
    843     public static final int FULL = 0;
    844 
    845     /**
    846      * Constant for long style pattern.
    847      * @stable ICU 2.0
    848      */
    849     public static final int LONG = 1;
    850 
    851     /**
    852      * Constant for medium style pattern.
    853      * @stable ICU 2.0
    854      */
    855     public static final int MEDIUM = 2;
    856 
    857     /**
    858      * Constant for short style pattern.
    859      * @stable ICU 2.0
    860      */
    861     public static final int SHORT = 3;
    862 
    863     /**
    864      * Constant for default style pattern.  Its value is MEDIUM.
    865      * @stable ICU 2.0
    866      */
    867     public static final int DEFAULT = MEDIUM;
    868 
    869     /**
    870      * {@icu} Constant for relative style mask.
    871      * @stable ICU 3.8
    872      */
    873     public static final int RELATIVE = (1 << 7);
    874 
    875     /**
    876      * {@icu} Constant for relative full style pattern.
    877      * @stable ICU 3.8
    878      */
    879     public static final int RELATIVE_FULL = RELATIVE | FULL;
    880 
    881     /**
    882      * {@icu} Constant for relative style pattern.
    883      * @stable ICU 3.8
    884      */
    885     public static final int RELATIVE_LONG = RELATIVE | LONG;
    886 
    887     /**
    888      * {@icu} Constant for relative style pattern.
    889      * @stable ICU 3.8
    890      */
    891     public static final int RELATIVE_MEDIUM = RELATIVE | MEDIUM;
    892 
    893     /**
    894      * {@icu} Constant for relative style pattern.
    895      * @stable ICU 3.8
    896      */
    897     public static final int RELATIVE_SHORT = RELATIVE | SHORT;
    898 
    899     /**
    900      * {@icu} Constant for relative default style pattern.
    901      * @stable ICU 3.8
    902      */
    903     public static final int RELATIVE_DEFAULT = RELATIVE | DEFAULT;
    904 
    905     /*
    906      * DATES
    907      */
    908 
    909     /**
    910      * {@icu} Constant for date skeleton with year.
    911      * @stable ICU 4.0
    912      */
    913     public static final String YEAR = "y";
    914 
    915     /**
    916      * {@icu} Constant for date skeleton with quarter.
    917      * @stable ICU 50
    918      */
    919     public static final String QUARTER = "QQQQ";
    920 
    921     /**
    922      * {@icu} Constant for date skeleton with abbreviated quarter.
    923      * @stable ICU 50
    924      */
    925     public static final String ABBR_QUARTER = "QQQ";
    926 
    927     /**
    928      * {@icu} Constant for date skeleton with year and quarter.
    929      * @stable ICU 4.0
    930      */
    931     public static final String YEAR_QUARTER = "yQQQQ";
    932 
    933     /**
    934      * {@icu} Constant for date skeleton with year and abbreviated quarter.
    935      * @stable ICU 4.0
    936      */
    937     public static final String YEAR_ABBR_QUARTER = "yQQQ";
    938 
    939     /**
    940      * {@icu} Constant for date skeleton with month.
    941      * @stable ICU 4.0
    942      */
    943     public static final String MONTH = "MMMM";
    944 
    945     /**
    946      * {@icu} Constant for date skeleton with abbreviated month.
    947      * @stable ICU 4.0
    948      */
    949     public static final String ABBR_MONTH = "MMM";
    950 
    951     /**
    952      * {@icu} Constant for date skeleton with numeric month.
    953      * @stable ICU 4.0
    954      */
    955     public static final String NUM_MONTH = "M";
    956 
    957     /**
    958      * {@icu} Constant for date skeleton with year and month.
    959      * @stable ICU 4.0
    960      */
    961     public static final String YEAR_MONTH = "yMMMM";
    962 
    963     /**
    964      * {@icu} Constant for date skeleton with year and abbreviated month.
    965      * @stable ICU 4.0
    966      */
    967     public static final String YEAR_ABBR_MONTH = "yMMM";
    968 
    969     /**
    970      * {@icu} Constant for date skeleton with year and numeric month.
    971      * @stable ICU 4.0
    972      */
    973     public static final String YEAR_NUM_MONTH = "yM";
    974 
    975     /**
    976      * {@icu} Constant for date skeleton with day.
    977      * @stable ICU 4.0
    978      */
    979     public static final String DAY = "d";
    980 
    981     /**
    982      * {@icu} Constant for date skeleton with year, month, and day.
    983      * Used in combinations date + time, date + time + zone, or time + zone.
    984      * @stable ICU 4.0
    985      */
    986     public static final String YEAR_MONTH_DAY = "yMMMMd";
    987 
    988     /**
    989      * {@icu} Constant for date skeleton with year, abbreviated month, and day.
    990      * Used in combinations date + time, date + time + zone, or time + zone.
    991      * @stable ICU 4.0
    992      */
    993     public static final String YEAR_ABBR_MONTH_DAY = "yMMMd";
    994 
    995     /**
    996      * {@icu} Constant for date skeleton with year, numeric month, and day.
    997      * Used in combinations date + time, date + time + zone, or time + zone.
    998      * @stable ICU 4.0
    999      */
   1000     public static final String YEAR_NUM_MONTH_DAY = "yMd";
   1001 
   1002     /**
   1003      * {@icu} Constant for date skeleton with weekday.
   1004      * @stable ICU 50
   1005      */
   1006     public static final String WEEKDAY = "EEEE";
   1007 
   1008     /**
   1009      * {@icu} Constant for date skeleton with abbreviated weekday.
   1010      * @stable ICU 50
   1011      */
   1012     public static final String ABBR_WEEKDAY = "E";
   1013 
   1014     /**
   1015      * {@icu} Constant for date skeleton with year, month, weekday, and day.
   1016      * Used in combinations date + time, date + time + zone, or time + zone.
   1017      * @stable ICU 4.0
   1018      */
   1019     public static final String YEAR_MONTH_WEEKDAY_DAY = "yMMMMEEEEd";
   1020 
   1021     /**
   1022      * {@icu} Constant for date skeleton with year, abbreviated month, weekday, and day.
   1023      * Used in combinations date + time, date + time + zone, or time + zone.
   1024      * @stable ICU 4.0
   1025      */
   1026     public static final String YEAR_ABBR_MONTH_WEEKDAY_DAY = "yMMMEd";
   1027 
   1028     /**
   1029      * {@icu} Constant for date skeleton with year, numeric month, weekday, and day.
   1030      * Used in combinations date + time, date + time + zone, or time + zone.
   1031      * @stable ICU 4.0
   1032      */
   1033     public static final String YEAR_NUM_MONTH_WEEKDAY_DAY = "yMEd";
   1034 
   1035     /**
   1036      * {@icu} Constant for date skeleton with long month and day.
   1037      * Used in combinations date + time, date + time + zone, or time + zone.
   1038      * @stable ICU 4.0
   1039      */
   1040     public static final String MONTH_DAY = "MMMMd";
   1041 
   1042     /**
   1043      * {@icu} Constant for date skeleton with abbreviated month and day.
   1044      * Used in combinations date + time, date + time + zone, or time + zone.
   1045      * @stable ICU 4.0
   1046      */
   1047     public static final String ABBR_MONTH_DAY = "MMMd";
   1048 
   1049     /**
   1050      * {@icu} Constant for date skeleton with numeric month and day.
   1051      * Used in combinations date + time, date + time + zone, or time + zone.
   1052      * @stable ICU 4.0
   1053      */
   1054     public static final String NUM_MONTH_DAY = "Md";
   1055 
   1056     /**
   1057      * {@icu} Constant for date skeleton with month, weekday, and day.
   1058      * Used in combinations date + time, date + time + zone, or time + zone.
   1059      * @stable ICU 4.0
   1060      */
   1061     public static final String MONTH_WEEKDAY_DAY = "MMMMEEEEd";
   1062 
   1063     /**
   1064      * {@icu} Constant for date skeleton with abbreviated month, weekday, and day.
   1065      * Used in combinations date + time, date + time + zone, or time + zone.
   1066      * @stable ICU 4.0
   1067      */
   1068     public static final String ABBR_MONTH_WEEKDAY_DAY = "MMMEd";
   1069 
   1070     /**
   1071      * {@icu} Constant for date skeleton with numeric month, weekday, and day.
   1072      * Used in combinations date + time, date + time + zone, or time + zone.
   1073      * @stable ICU 4.0
   1074      */
   1075     public static final String NUM_MONTH_WEEKDAY_DAY = "MEd";
   1076 
   1077     /**
   1078      * List of all of the date skeleton constants for iteration.
   1079      * Note that this is fragile; be sure to add any values that are added above.
   1080      * @internal
   1081      * @deprecated This API is ICU internal only.
   1082      */
   1083     @Deprecated
   1084     public static final List<String> DATE_SKELETONS = Arrays.asList(
   1085             YEAR,
   1086             QUARTER,
   1087             ABBR_QUARTER,
   1088             YEAR_QUARTER,
   1089             YEAR_ABBR_QUARTER,
   1090             MONTH,
   1091             ABBR_MONTH,
   1092             NUM_MONTH,
   1093             YEAR_MONTH,
   1094             YEAR_ABBR_MONTH,
   1095             YEAR_NUM_MONTH,
   1096             DAY,
   1097             YEAR_MONTH_DAY,
   1098             YEAR_ABBR_MONTH_DAY,
   1099             YEAR_NUM_MONTH_DAY,
   1100             WEEKDAY,
   1101             ABBR_WEEKDAY,
   1102             YEAR_MONTH_WEEKDAY_DAY,
   1103             YEAR_ABBR_MONTH_WEEKDAY_DAY,
   1104             YEAR_NUM_MONTH_WEEKDAY_DAY,
   1105             MONTH_DAY,
   1106             ABBR_MONTH_DAY,
   1107             NUM_MONTH_DAY,
   1108             MONTH_WEEKDAY_DAY,
   1109             ABBR_MONTH_WEEKDAY_DAY,
   1110             NUM_MONTH_WEEKDAY_DAY);
   1111 
   1112     /*
   1113      * TIMES
   1114      */
   1115 
   1116     /**
   1117      * {@icu} Constant for date skeleton with hour, with the locale's preferred hour format (12 or 24).
   1118      * @stable ICU 4.0
   1119      */
   1120     public static final String HOUR = "j";
   1121 
   1122     /**
   1123      * {@icu} Constant for date skeleton with hour in 24-hour presentation.
   1124      * @stable ICU 50
   1125      */
   1126     public static final String HOUR24 = "H";
   1127 
   1128     /**
   1129      * {@icu} Constant for date skeleton with minute.
   1130      * @stable ICU 50
   1131      */
   1132     public static final String MINUTE = "m";
   1133 
   1134     /**
   1135      * {@icu} Constant for date skeleton with hour and minute, with the locale's preferred hour format (12 or 24).
   1136      * Used in combinations date + time, date + time + zone, or time + zone.
   1137      * @stable ICU 4.0
   1138      */
   1139     public static final String HOUR_MINUTE = "jm";
   1140 
   1141     /**
   1142      * {@icu} Constant for date skeleton with hour and minute in 24-hour presentation.
   1143      * Used in combinations date + time, date + time + zone, or time + zone.
   1144      * @stable ICU 4.0
   1145      */
   1146     public static final String HOUR24_MINUTE = "Hm";
   1147 
   1148     /**
   1149      * {@icu} Constant for date skeleton with second.
   1150      * @stable ICU 50
   1151      */
   1152     public static final String SECOND = "s";
   1153 
   1154     /**
   1155      * {@icu} Constant for date skeleton with hour, minute, and second,
   1156      * with the locale's preferred hour format (12 or 24).
   1157      * Used in combinations date + time, date + time + zone, or time + zone.
   1158      * @stable ICU 4.0
   1159      */
   1160     public static final String HOUR_MINUTE_SECOND = "jms";
   1161 
   1162     /**
   1163      * {@icu} Constant for date skeleton with hour, minute, and second in
   1164      * 24-hour presentation.
   1165      * Used in combinations date + time, date + time + zone, or time + zone.
   1166      * @stable ICU 4.0
   1167      */
   1168     public static final String HOUR24_MINUTE_SECOND = "Hms";
   1169 
   1170     /**
   1171      * {@icu} Constant for date skeleton with minute and second.
   1172      * Used in combinations date + time, date + time + zone, or time + zone.
   1173      * @stable ICU 4.0
   1174      */
   1175     public static final String MINUTE_SECOND = "ms";
   1176 
   1177     /**
   1178      * List of all of the time skeleton constants for iteration.
   1179      * Note that this is fragile; be sure to add any values that are added above.
   1180      * @internal
   1181      * @deprecated This API is ICU internal only.
   1182      */
   1183     @Deprecated
   1184     public static final List<String> TIME_SKELETONS = Arrays.asList(
   1185             HOUR,
   1186             HOUR24,
   1187             MINUTE,
   1188             HOUR_MINUTE,
   1189             HOUR24_MINUTE,
   1190             SECOND,
   1191             HOUR_MINUTE_SECOND,
   1192             HOUR24_MINUTE_SECOND,
   1193             MINUTE_SECOND);
   1194 
   1195     /*
   1196      * TIMEZONES
   1197      */
   1198 
   1199     /**
   1200      * {@icu} Constant for <i>generic location format</i>, such as Los Angeles Time;
   1201      * used in combinations date + time + zone, or time + zone.
   1202      * @see <a href="http://unicode.org/reports/tr35/#Date_Format_Patterns">LDML Date Format Patterns</a>
   1203      * @see <a href="http://unicode.org/reports/tr35/#Time_Zone_Fallback">LDML Time Zone Fallback</a>
   1204      * @stable ICU 50
   1205      */
   1206     public static final String LOCATION_TZ = "VVVV";
   1207 
   1208     /**
   1209      * {@icu} Constant for <i>generic non-location format</i>, such as Pacific Time;
   1210      * used in combinations date + time + zone, or time + zone.
   1211      * @see <a href="http://unicode.org/reports/tr35/#Date_Format_Patterns">LDML Date Format Patterns</a>
   1212      * @see <a href="http://unicode.org/reports/tr35/#Time_Zone_Fallback">LDML Time Zone Fallback</a>
   1213      * @stable ICU 50
   1214      */
   1215     public static final String GENERIC_TZ = "vvvv";
   1216 
   1217     /**
   1218      * {@icu} Constant for <i>generic non-location format</i>, abbreviated if possible, such as PT;
   1219      * used in combinations date + time + zone, or time + zone.
   1220      * @see <a href="http://unicode.org/reports/tr35/#Date_Format_Patterns">LDML Date Format Patterns</a>
   1221      * @see <a href="http://unicode.org/reports/tr35/#Time_Zone_Fallback">LDML Time Zone Fallback</a>
   1222      * @stable ICU 50
   1223      */
   1224     public static final String ABBR_GENERIC_TZ = "v";
   1225 
   1226     /**
   1227      * {@icu} Constant for <i>specific non-location format</i>, such as Pacific Daylight Time;
   1228      * used in combinations date + time + zone, or time + zone.
   1229      * @see <a href="http://unicode.org/reports/tr35/#Date_Format_Patterns">LDML Date Format Patterns</a>
   1230      * @see <a href="http://unicode.org/reports/tr35/#Time_Zone_Fallback">LDML Time Zone Fallback</a>
   1231      * @stable ICU 50
   1232      */
   1233     public static final String SPECIFIC_TZ = "zzzz";
   1234 
   1235     /**
   1236      * {@icu} Constant for <i>specific non-location format</i>, abbreviated if possible, such as PDT;
   1237      * used in combinations date + time + zone, or time + zone.
   1238      * @see <a href="http://unicode.org/reports/tr35/#Date_Format_Patterns">LDML Date Format Patterns</a>
   1239      * @see <a href="http://unicode.org/reports/tr35/#Time_Zone_Fallback">LDML Time Zone Fallback</a>
   1240      * @stable ICU 50
   1241      */
   1242     public static final String ABBR_SPECIFIC_TZ = "z";
   1243 
   1244     /**
   1245      * {@icu} Constant for <i>localized GMT/UTC format</i>, such as GMT+8:00 or HPG-8:00;
   1246      * used in combinations date + time + zone, or time + zone.
   1247      * @see <a href="http://unicode.org/reports/tr35/#Date_Format_Patterns">LDML Date Format Patterns</a>
   1248      * @see <a href="http://unicode.org/reports/tr35/#Time_Zone_Fallback">LDML Time Zone Fallback</a>
   1249      * @stable ICU 50
   1250      */
   1251     public static final String ABBR_UTC_TZ = "ZZZZ";
   1252 
   1253     /**
   1254      * List of all of the zone skeleton constants for iteration.
   1255      * Note that this is fragile; be sure to add any values that are added above.
   1256      * @internal
   1257      * @deprecated This API is ICU internal only.
   1258      */
   1259     @Deprecated
   1260     public static final List<String> ZONE_SKELETONS = Arrays.asList(
   1261             LOCATION_TZ,
   1262             GENERIC_TZ,
   1263             ABBR_GENERIC_TZ,
   1264             SPECIFIC_TZ,
   1265             ABBR_SPECIFIC_TZ,
   1266             ABBR_UTC_TZ);
   1267 
   1268     /*
   1269      * deprecated skeleton constants
   1270      */
   1271 
   1272     /**
   1273      * {@icu} Constant for date skeleton with standalone month.
   1274      * @deprecated ICU 50 Use {@link #MONTH} instead.
   1275      */
   1276     @Deprecated
   1277     public static final String STANDALONE_MONTH = "LLLL";
   1278 
   1279     /**
   1280      * {@icu} Constant for date skeleton with standalone abbreviated month.
   1281      * @deprecated ICU 50 Use {@link #ABBR_MONTH} instead.
   1282      */
   1283     @Deprecated
   1284     public static final String ABBR_STANDALONE_MONTH = "LLL";
   1285 
   1286     /**
   1287      * {@icu} Constant for date skeleton with hour, minute, and generic timezone.
   1288      * @deprecated ICU 50 Use instead {@link #HOUR_MINUTE}+{@link #ABBR_GENERIC_TZ} or some other timezone presentation.
   1289      */
   1290     @Deprecated
   1291     public static final String HOUR_MINUTE_GENERIC_TZ = "jmv";
   1292 
   1293     /**
   1294      * {@icu} Constant for date skeleton with hour, minute, and timezone.
   1295      * @deprecated ICU 50 Use instead {@link #HOUR_MINUTE}+{@link #ABBR_SPECIFIC_TZ} or some other timezone presentation.
   1296      */
   1297     @Deprecated
   1298     public static final String HOUR_MINUTE_TZ = "jmz";
   1299 
   1300     /**
   1301      * {@icu} Constant for date skeleton with hour and generic timezone.
   1302      * @deprecated ICU 50 Use instead {@link #HOUR}+{@link #ABBR_GENERIC_TZ} or some other timezone presentation.
   1303      */
   1304     @Deprecated
   1305     public static final String HOUR_GENERIC_TZ = "jv";
   1306 
   1307     /**
   1308      * {@icu} Constant for date skeleton with hour and timezone.
   1309      * @deprecated ICU 50 Use instead {@link #HOUR}+{@link #ABBR_SPECIFIC_TZ} or some other timezone presentation.
   1310      */
   1311     @Deprecated
   1312     public static final String HOUR_TZ = "jz";
   1313 
   1314 
   1315     /**
   1316      * Gets the time formatter with the default formatting style
   1317      * for the default <code>FORMAT</code> locale.
   1318      * @return a time formatter.
   1319      * @see Category#FORMAT
   1320      * @stable ICU 2.0
   1321      */
   1322     public final static DateFormat getTimeInstance()
   1323     {
   1324         return get(-1, DEFAULT, ULocale.getDefault(Category.FORMAT), null);
   1325     }
   1326 
   1327     /**
   1328      * Returns the time formatter with the given formatting style
   1329      * for the default <code>FORMAT</code> locale.
   1330      * @param style the given formatting style. For example,
   1331      * SHORT for "h:mm a" in the US locale. Relative time styles are not currently
   1332      * supported, and behave just like the corresponding non-relative style.
   1333      * @return a time formatter.
   1334      * @see Category#FORMAT
   1335      * @stable ICU 2.0
   1336      */
   1337     public final static DateFormat getTimeInstance(int style)
   1338     {
   1339         return get(-1, style, ULocale.getDefault(Category.FORMAT), null);
   1340     }
   1341 
   1342     /**
   1343      * Returns the time formatter with the given formatting style
   1344      * for the given locale.
   1345      * @param style the given formatting style. For example,
   1346      * SHORT for "h:mm a" in the US locale. Relative time styles are not currently
   1347      * supported, and behave just like the corresponding non-relative style.
   1348      * @param aLocale the given locale.
   1349      * @return a time formatter.
   1350      * @stable ICU 2.0
   1351      */
   1352     public final static DateFormat getTimeInstance(int style,
   1353                                                  Locale aLocale)
   1354     {
   1355         return get(-1, style, ULocale.forLocale(aLocale), null);
   1356     }
   1357 
   1358     /**
   1359      * Returns the time formatter with the given formatting style
   1360      * for the given locale.
   1361      * @param style the given formatting style. For example,
   1362      * SHORT for "h:mm a" in the US locale. Relative time styles are not currently
   1363      * supported, and behave just like the corresponding non-relative style.
   1364      * @param locale the given ulocale.
   1365      * @return a time formatter.
   1366      * @stable ICU 3.2
   1367      */
   1368     public final static DateFormat getTimeInstance(int style,
   1369                                                  ULocale locale)
   1370     {
   1371         return get(-1, style, locale, null);
   1372     }
   1373 
   1374     /**
   1375      * Returns the date formatter with the default formatting style
   1376      * for the default <code>FORMAT</code> locale.
   1377      * @return a date formatter.
   1378      * @see Category#FORMAT
   1379      * @stable ICU 2.0
   1380      */
   1381     public final static DateFormat getDateInstance()
   1382     {
   1383         return get(DEFAULT, -1, ULocale.getDefault(Category.FORMAT), null);
   1384     }
   1385 
   1386     /**
   1387      * Returns the date formatter with the given formatting style
   1388      * for the default <code>FORMAT</code> locale.
   1389      * @param style the given formatting style. For example,
   1390      * SHORT for "M/d/yy" in the US locale. As currently implemented, relative date
   1391      * formatting only affects a limited range of calendar days before or after the
   1392      * current date, based on the CLDR &lt;field type="day"&gt;/&lt;relative&gt; data: For example,
   1393      * in English, "Yesterday", "Today", and "Tomorrow". Outside of this range, relative
   1394      * dates are formatted using the corresponding non-relative style.
   1395      * @return a date formatter.
   1396      * @see Category#FORMAT
   1397      * @stable ICU 2.0
   1398      */
   1399     public final static DateFormat getDateInstance(int style)
   1400     {
   1401         return get(style, -1, ULocale.getDefault(Category.FORMAT), null);
   1402     }
   1403 
   1404     /**
   1405      * Returns the date formatter with the given formatting style
   1406      * for the given locale.
   1407      * @param style the given formatting style. For example,
   1408      * SHORT for "M/d/yy" in the US locale. As currently implemented, relative date
   1409      * formatting only affects a limited range of calendar days before or after the
   1410      * current date, based on the CLDR &lt;field type="day"&gt;/&lt;relative&gt; data: For example,
   1411      * in English, "Yesterday", "Today", and "Tomorrow". Outside of this range, relative
   1412      * dates are formatted using the corresponding non-relative style.
   1413      * @param aLocale the given locale.
   1414      * @return a date formatter.
   1415      * @stable ICU 2.0
   1416      */
   1417     public final static DateFormat getDateInstance(int style,
   1418                                                  Locale aLocale)
   1419     {
   1420         return get(style, -1, ULocale.forLocale(aLocale), null);
   1421     }
   1422 
   1423     /**
   1424      * Returns the date formatter with the given formatting style
   1425      * for the given locale.
   1426      * @param style the given formatting style. For example,
   1427      * SHORT for "M/d/yy" in the US locale. As currently implemented, relative date
   1428      * formatting only affects a limited range of calendar days before or after the
   1429      * current date, based on the CLDR &lt;field type="day"&gt;/&lt;relative&gt; data: For example,
   1430      * in English, "Yesterday", "Today", and "Tomorrow". Outside of this range, relative
   1431      * dates are formatted using the corresponding non-relative style.
   1432      * @param locale the given ulocale.
   1433      * @return a date formatter.
   1434      * @stable ICU 3.2
   1435      */
   1436     public final static DateFormat getDateInstance(int style,
   1437                                                  ULocale locale)
   1438     {
   1439         return get(style, -1, locale, null);
   1440     }
   1441 
   1442     /**
   1443      * Returns the date/time formatter with the default formatting style
   1444      * for the default <code>FORMAT</code> locale.
   1445      * @return a date/time formatter.
   1446      * @see Category#FORMAT
   1447      * @stable ICU 2.0
   1448      */
   1449     public final static DateFormat getDateTimeInstance()
   1450     {
   1451         return get(DEFAULT, DEFAULT, ULocale.getDefault(Category.FORMAT), null);
   1452     }
   1453 
   1454     /**
   1455      * Returns the date/time formatter with the given date and time
   1456      * formatting styles for the default <code>FORMAT</code> locale.
   1457      * @param dateStyle the given date formatting style. For example,
   1458      * SHORT for "M/d/yy" in the US locale. As currently implemented, relative date
   1459      * formatting only affects a limited range of calendar days before or after the
   1460      * current date, based on the CLDR &lt;field type="day"&gt;/&lt;relative&gt; data: For example,
   1461      * in English, "Yesterday", "Today", and "Tomorrow". Outside of this range, relative
   1462      * dates are formatted using the corresponding non-relative style.
   1463      * @param timeStyle the given time formatting style. For example,
   1464      * SHORT for "h:mm a" in the US locale. Relative time styles are not currently
   1465      * supported, and behave just like the corresponding non-relative style.
   1466      * @return a date/time formatter.
   1467      * @see Category#FORMAT
   1468      * @stable ICU 2.0
   1469      */
   1470     public final static DateFormat getDateTimeInstance(int dateStyle,
   1471                                                        int timeStyle)
   1472     {
   1473         return get(dateStyle, timeStyle, ULocale.getDefault(Category.FORMAT), null);
   1474     }
   1475 
   1476     /**
   1477      * Returns the date/time formatter with the given formatting styles
   1478      * for the given locale.
   1479      * @param dateStyle the given date formatting style. As currently implemented, relative date
   1480      * formatting only affects a limited range of calendar days before or after the
   1481      * current date, based on the CLDR &lt;field type="day"&gt;/&lt;relative&gt; data: For example,
   1482      * in English, "Yesterday", "Today", and "Tomorrow". Outside of this range, relative
   1483      * dates are formatted using the corresponding non-relative style.
   1484      * @param timeStyle the given time formatting style. Relative time styles are not
   1485      * currently supported, and behave just like the corresponding non-relative style.
   1486      * @param aLocale the given locale.
   1487      * @return a date/time formatter.
   1488      * @stable ICU 2.0
   1489      */
   1490     public final static DateFormat getDateTimeInstance(
   1491         int dateStyle, int timeStyle, Locale aLocale)
   1492     {
   1493         return get(dateStyle, timeStyle, ULocale.forLocale(aLocale), null);
   1494     }
   1495 
   1496     /**
   1497      * Returns the date/time formatter with the given formatting styles
   1498      * for the given locale.
   1499      * @param dateStyle the given date formatting style. As currently implemented, relative date
   1500      * formatting only affects a limited range of calendar days before or after the
   1501      * current date, based on the CLDR &lt;field type="day"&gt;/&lt;relative&gt; data: For example,
   1502      * in English, "Yesterday", "Today", and "Tomorrow". Outside of this range, relative
   1503      * dates are formatted using the corresponding non-relative style.
   1504      * @param timeStyle the given time formatting style. Relative time styles are not
   1505      * currently supported, and behave just like the corresponding non-relative style.
   1506      * @param locale the given ulocale.
   1507      * @return a date/time formatter.
   1508      * @stable ICU 3.2
   1509      */
   1510     public final static DateFormat getDateTimeInstance(
   1511         int dateStyle, int timeStyle, ULocale locale)
   1512     {
   1513         return get(dateStyle, timeStyle, locale, null);
   1514     }
   1515 
   1516     /**
   1517      * Returns a default date/time formatter that uses the SHORT style for both the
   1518      * date and the time.
   1519      * @stable ICU 2.0
   1520      */
   1521     public final static DateFormat getInstance() {
   1522         return getDateTimeInstance(SHORT, SHORT);
   1523     }
   1524 
   1525     /**
   1526      * Returns the set of locales for which DateFormats are installed.
   1527      * @return the set of locales for which DateFormats are installed.
   1528      * @stable ICU 2.0
   1529      */
   1530     public static Locale[] getAvailableLocales()
   1531     {
   1532         return ICUResourceBundle.getAvailableLocales();
   1533     }
   1534 
   1535     /**
   1536      * {@icu} Returns the set of locales for which DateFormats are installed.
   1537      * @return the set of locales for which DateFormats are installed.
   1538      * @draft ICU 3.2 (retain)
   1539      * @provisional This API might change or be removed in a future release.
   1540      */
   1541     public static ULocale[] getAvailableULocales()
   1542     {
   1543         return ICUResourceBundle.getAvailableULocales();
   1544     }
   1545 
   1546     /**
   1547      * Sets the calendar to be used by this date format.  Initially, the default
   1548      * calendar for the specified or default locale is used.
   1549      * @param newCalendar the new Calendar to be used by the date format
   1550      * @stable ICU 2.0
   1551      */
   1552     public void setCalendar(Calendar newCalendar)
   1553     {
   1554         this.calendar = newCalendar;
   1555     }
   1556 
   1557     /**
   1558      * Returns the calendar associated with this date/time formatter.
   1559      * @return the calendar associated with this date/time formatter.
   1560      * @stable ICU 2.0
   1561      */
   1562     public Calendar getCalendar()
   1563     {
   1564         return calendar;
   1565     }
   1566 
   1567     /**
   1568      * Sets the number formatter.
   1569      * @param newNumberFormat the given new NumberFormat.
   1570      * @stable ICU 2.0
   1571      */
   1572     public void setNumberFormat(NumberFormat newNumberFormat)
   1573     {
   1574         numberFormat = (NumberFormat)newNumberFormat.clone();
   1575         fixNumberFormatForDates(numberFormat);
   1576     }
   1577 
   1578     // no matter what the locale's default number format looked like, we want
   1579     // to modify it so that it doesn't use thousands separators, doesn't always
   1580     // show the decimal point, and recognizes integers only when parsing
   1581     static void fixNumberFormatForDates(NumberFormat nf) {
   1582         nf.setGroupingUsed(false);
   1583         if (nf instanceof DecimalFormat) {
   1584             ((DecimalFormat)nf).setDecimalSeparatorAlwaysShown(false);
   1585         }
   1586         nf.setParseIntegerOnly(true);
   1587         nf.setMinimumFractionDigits(0);
   1588     }
   1589 
   1590     /**
   1591      * Returns the number formatter which this date/time formatter uses to
   1592      * format and parse a time.
   1593      * @return the number formatter which this date/time formatter uses.
   1594      * @stable ICU 2.0
   1595      */
   1596     public NumberFormat getNumberFormat()
   1597     {
   1598         return numberFormat;
   1599     }
   1600 
   1601     /**
   1602      * Sets the time zone for the calendar of this DateFormat object.
   1603      * @param zone the given new time zone.
   1604      * @stable ICU 2.0
   1605      */
   1606     public void setTimeZone(TimeZone zone)
   1607     {
   1608         calendar.setTimeZone(zone);
   1609     }
   1610 
   1611     /**
   1612      * Returns the time zone.
   1613      * @return the time zone associated with the calendar of DateFormat.
   1614      * @stable ICU 2.0
   1615      */
   1616     public TimeZone getTimeZone()
   1617     {
   1618         return calendar.getTimeZone();
   1619     }
   1620 
   1621     /**
   1622      * Specifies whether date/time parsing is to be lenient.  With
   1623      * lenient parsing, the parser may use heuristics to interpret inputs that
   1624      * do not precisely match this object's format.  Without lenient parsing,
   1625      * inputs must match this object's format more closely.
   1626      * <br><br>
   1627      * <b>Note:</b> ICU 53 introduced finer grained control of leniency (and added
   1628      * new control points) making the preferred method a combination of
   1629      * setCalendarLenient() &amp; setBooleanAttribute() calls.
   1630      * This method supports prior functionality but may not support all
   1631      * future leniency control &amp; behavior of DateFormat. For control of pre 53 leniency,
   1632      * Calendar and DateFormat whitespace &amp; numeric tolerance, this method is safe to
   1633      * use. However, mixing leniency control via this method and modification of the
   1634      * newer attributes via setBooleanAttribute() may produce undesirable
   1635      * results.
   1636      *
   1637      * @param lenient True specifies date/time interpretation to be lenient.
   1638      * @see com.ibm.icu.util.Calendar#setLenient
   1639      * @see #setBooleanAttribute(BooleanAttribute, boolean)
   1640      * @see #setCalendarLenient(boolean)
   1641      * @stable ICU 2.0
   1642      */
   1643     public void setLenient(boolean lenient)
   1644     {
   1645         calendar.setLenient(lenient);
   1646         setBooleanAttribute(BooleanAttribute.PARSE_ALLOW_NUMERIC, lenient);
   1647         setBooleanAttribute(BooleanAttribute.PARSE_ALLOW_WHITESPACE, lenient);
   1648     }
   1649 
   1650     /**
   1651      * Returns whether both date/time parsing in the encapsulated Calendar object and DateFormat whitespace &amp;
   1652      * numeric processing is lenient.
   1653      * @stable ICU 2.0
   1654      */
   1655     public boolean isLenient()
   1656     {
   1657         return calendar.isLenient()
   1658                 && getBooleanAttribute(BooleanAttribute.PARSE_ALLOW_NUMERIC)
   1659                 && getBooleanAttribute(BooleanAttribute.PARSE_ALLOW_WHITESPACE);
   1660     }
   1661 
   1662     /**
   1663      * Specifies whether date/time parsing in the encapsulated Calendar object should be lenient.
   1664      * With lenient parsing, the parser may use heuristics to interpret inputs that
   1665      * do not precisely match this object's format.  Without lenient parsing,
   1666      * inputs must match this object's format more closely.
   1667      * @param lenient when true, Calendar parsing is lenient
   1668      * @see com.ibm.icu.util.Calendar#setLenient
   1669      * @stable ICU 53
   1670      */
   1671     public void setCalendarLenient(boolean lenient)
   1672     {
   1673         calendar.setLenient(lenient);
   1674     }
   1675 
   1676 
   1677     /**
   1678      * Returns whether date/time parsing in the encapsulated Calendar object is lenient.
   1679      * @stable ICU 53
   1680      */
   1681     public boolean isCalendarLenient()
   1682     {
   1683         return calendar.isLenient();
   1684     }
   1685 
   1686     /**
   1687      * Sets a boolean attribute for this instance. Aspects of DateFormat leniency are controlled by
   1688      * boolean attributes.
   1689      *
   1690      * @see BooleanAttribute
   1691      * @stable ICU 53
   1692      */
   1693     public DateFormat setBooleanAttribute(BooleanAttribute key, boolean value)
   1694     {
   1695         if(key.equals(DateFormat.BooleanAttribute.PARSE_PARTIAL_MATCH)) {
   1696             key = DateFormat.BooleanAttribute.PARSE_PARTIAL_LITERAL_MATCH;
   1697         }
   1698         if(value)
   1699         {
   1700             booleanAttributes.add(key);
   1701         }
   1702         else
   1703         {
   1704             booleanAttributes.remove(key);
   1705         }
   1706 
   1707         return this;
   1708     }
   1709 
   1710     /**
   1711      * Returns the current value for the specified BooleanAttribute for this instance
   1712      *
   1713      * if attribute is missing false is returned.
   1714      *
   1715      * @see BooleanAttribute
   1716      * @stable ICU 53
   1717      */
   1718     public boolean getBooleanAttribute(BooleanAttribute key)
   1719     {
   1720         if(key == DateFormat.BooleanAttribute.PARSE_PARTIAL_MATCH) {
   1721             key = DateFormat.BooleanAttribute.PARSE_PARTIAL_LITERAL_MATCH;
   1722         }
   1723         return booleanAttributes.contains(key);
   1724     }
   1725 
   1726 
   1727     /**
   1728      * {@icu} Set a particular DisplayContext value in the formatter,
   1729      * such as CAPITALIZATION_FOR_STANDALONE.
   1730      *
   1731      * @param context The DisplayContext value to set.
   1732      * @stable ICU 53
   1733      */
   1734     public void setContext(DisplayContext context) {
   1735         if (context.type() == DisplayContext.Type.CAPITALIZATION) {
   1736             capitalizationSetting = context;
   1737         }
   1738     }
   1739 
   1740     /**
   1741      * {@icu} Get the formatter's DisplayContext value for the specified DisplayContext.Type,
   1742      * such as CAPITALIZATION.
   1743      *
   1744      * @param type the DisplayContext.Type whose value to return
   1745      * @return the current DisplayContext setting for the specified type
   1746      * @stable ICU 53
   1747      */
   1748     public DisplayContext getContext(DisplayContext.Type type) {
   1749         return (type == DisplayContext.Type.CAPITALIZATION && capitalizationSetting != null)?
   1750                 capitalizationSetting: DisplayContext.CAPITALIZATION_NONE;
   1751     }
   1752 
   1753     /**
   1754      * Overrides hashCode.
   1755      * @stable ICU 2.0
   1756      */
   1757     ///CLOVER:OFF
   1758     // turn off code coverage since all subclasses override this
   1759     @Override
   1760     public int hashCode() {
   1761         return numberFormat.hashCode();
   1762         // just enough fields for a reasonable distribution
   1763     }
   1764     ///CLOVER:ON
   1765 
   1766     /**
   1767      * Overrides equals.
   1768      * @stable ICU 2.0
   1769      */
   1770     @Override
   1771     public boolean equals(Object obj) {
   1772         if (this == obj) return true;
   1773         if (obj == null || getClass() != obj.getClass()) return false;
   1774         DateFormat other = (DateFormat) obj;
   1775         return (((calendar==null && other.calendar==null) ||
   1776                     (calendar!=null && other.calendar!=null && calendar.isEquivalentTo(other.calendar))) &&
   1777                 ((numberFormat==null && other.numberFormat==null) ||
   1778                     (numberFormat!=null && other.numberFormat!=null && numberFormat.equals(other.numberFormat))) &&
   1779                 capitalizationSetting == other.capitalizationSetting);
   1780     }
   1781 
   1782     /**
   1783      * Overrides clone.
   1784      * @stable ICU 2.0
   1785      */
   1786     @Override
   1787     public Object clone()
   1788     {
   1789         DateFormat other = (DateFormat) super.clone();
   1790         other.calendar = (Calendar) calendar.clone();
   1791         if (numberFormat != null) {
   1792             other.numberFormat = (NumberFormat) numberFormat.clone();
   1793         }
   1794         return other;
   1795     }
   1796 
   1797     /**
   1798      * Creates a DateFormat with the given time and/or date style in the given
   1799      * locale.
   1800      * @param dateStyle a value from 0 to 3 indicating the time format,
   1801      * or -1 to indicate no date
   1802      * @param timeStyle a value from 0 to 3 indicating the time format,
   1803      * or -1 to indicate no time
   1804      * @param loc the locale for the format
   1805      * @param cal the calendar to be used, or null
   1806      */
   1807     private static DateFormat get(int dateStyle, int timeStyle, ULocale loc, Calendar cal) {
   1808         if((timeStyle != DateFormat.NONE && (timeStyle & RELATIVE)>0) ||
   1809            (dateStyle != DateFormat.NONE && (dateStyle & RELATIVE)>0)) {
   1810             RelativeDateFormat r = new RelativeDateFormat(timeStyle, dateStyle /* offset? */, loc, cal);
   1811             return r;
   1812         }
   1813 
   1814         if (timeStyle < DateFormat.NONE || timeStyle > DateFormat.SHORT) {
   1815             throw new IllegalArgumentException("Illegal time style " + timeStyle);
   1816         }
   1817         if (dateStyle < DateFormat.NONE || dateStyle > DateFormat.SHORT) {
   1818             throw new IllegalArgumentException("Illegal date style " + dateStyle);
   1819         }
   1820 
   1821         if (cal == null) {
   1822             cal = Calendar.getInstance(loc);
   1823         }
   1824 
   1825         try {
   1826             DateFormat result = cal.getDateTimeFormat(dateStyle, timeStyle, loc);
   1827             result.setLocale(cal.getLocale(ULocale.VALID_LOCALE),
   1828                  cal.getLocale(ULocale.ACTUAL_LOCALE));
   1829             return result;
   1830         } catch (MissingResourceException e) {
   1831             ///CLOVER:OFF
   1832             // coverage requires separate run with no data, so skip
   1833             return new SimpleDateFormat("M/d/yy h:mm a");
   1834             ///CLOVER:ON
   1835         }
   1836     }
   1837 
   1838     /**
   1839      * First, read in the default serializable data.
   1840      *
   1841      * Then, if <code>serialVersionOnStream</code> is less than 1, indicating that
   1842      * the stream was written by a pre-ICU-53 version,
   1843      * set capitalizationSetting to a default value.
   1844      * Finally, set serialVersionOnStream back to the maximum allowed value so that
   1845      * default serialization will work properly if this object is streamed out again.
   1846      */
   1847     private void readObject(ObjectInputStream stream)
   1848          throws IOException, ClassNotFoundException
   1849     {
   1850         stream.defaultReadObject();
   1851         if (serialVersionOnStream < 1) {
   1852             // Didn't have capitalizationSetting, set it to default
   1853             capitalizationSetting = DisplayContext.CAPITALIZATION_NONE;
   1854         }
   1855 
   1856         // if deserialized from a release that didn't have booleanAttributes, add them all
   1857         if(booleanAttributes == null) {
   1858             booleanAttributes = EnumSet.allOf(BooleanAttribute.class);
   1859         }
   1860 
   1861         serialVersionOnStream = currentSerialVersion;
   1862     }
   1863 
   1864     /**
   1865      * Creates a new date format.
   1866      * @stable ICU 2.0
   1867      */
   1868     protected DateFormat() {}
   1869 
   1870     //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1871 
   1872     //-------------------------------------------------------------------------
   1873     // Public static interface for creating custon DateFormats for different
   1874     // types of Calendars.
   1875     //-------------------------------------------------------------------------
   1876 
   1877     /**
   1878      * Creates a {@link DateFormat} object that can be used to format dates in
   1879      * the calendar system specified by <code>cal</code>.
   1880      * <p>
   1881      * @param cal   The calendar system for which a date format is desired.
   1882      *
   1883      * @param dateStyle The type of date format desired.  This can be
   1884      *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
   1885      *              etc.
   1886      *
   1887      * @param locale The locale for which the date format is desired.
   1888      * @stable ICU 2.0
   1889      */
   1890     static final public DateFormat getDateInstance(Calendar cal, int dateStyle, Locale locale)
   1891     {
   1892         return getDateTimeInstance(cal, dateStyle, -1, ULocale.forLocale(locale));
   1893     }
   1894 
   1895     /**
   1896      * Creates a {@link DateFormat} object that can be used to format dates in
   1897      * the calendar system specified by <code>cal</code>.
   1898      * <p>
   1899      * @param cal   The calendar system for which a date format is desired.
   1900      *
   1901      * @param dateStyle The type of date format desired.  This can be
   1902      *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
   1903      *              etc.
   1904      *
   1905      * @param locale The locale for which the date format is desired.
   1906      * @stable ICU 3.2
   1907      */
   1908     static final public DateFormat getDateInstance(Calendar cal, int dateStyle, ULocale locale)
   1909     {
   1910         return getDateTimeInstance(cal, dateStyle, -1, locale);
   1911     }
   1912 
   1913     /**
   1914      * Creates a {@link DateFormat} object that can be used to format times in
   1915      * the calendar system specified by <code>cal</code>.
   1916      * @param cal   The calendar system for which a time format is desired.
   1917      *
   1918      * @param timeStyle The type of time format desired.  This can be
   1919      *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
   1920      *              etc.
   1921      *
   1922      * @param locale The locale for which the time format is desired.
   1923      *
   1924      * @see DateFormat#getTimeInstance
   1925      * @stable ICU 2.0
   1926      */
   1927     static final public DateFormat getTimeInstance(Calendar cal, int timeStyle, Locale locale)
   1928     {
   1929         return getDateTimeInstance(cal, -1, timeStyle, ULocale.forLocale(locale));
   1930     }
   1931 
   1932     /**
   1933      * Creates a {@link DateFormat} object that can be used to format times in
   1934      * the calendar system specified by <code>cal</code>.
   1935      * @param cal   The calendar system for which a time format is desired.
   1936      *
   1937      * @param timeStyle The type of time format desired.  This can be
   1938      *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
   1939      *              etc.
   1940      *
   1941      * @param locale The locale for which the time format is desired.
   1942      *
   1943      * @see DateFormat#getTimeInstance
   1944      * @stable ICU 3.2
   1945      */
   1946     static final public DateFormat getTimeInstance(Calendar cal, int timeStyle, ULocale locale)
   1947     {
   1948         return getDateTimeInstance(cal, -1, timeStyle, locale);
   1949     }
   1950 
   1951     /**
   1952      * Creates a {@link DateFormat} object that can be used to format dates and times in
   1953      * the calendar system specified by <code>cal</code>.
   1954      * @param cal   The calendar system for which a date/time format is desired.
   1955      *
   1956      * @param dateStyle The type of date format desired.  This can be
   1957      *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
   1958      *              etc.
   1959      *
   1960      * @param timeStyle The type of time format desired.  This can be
   1961      *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
   1962      *              etc.
   1963      *
   1964      * @param locale The locale for which the date/time format is desired.
   1965      *
   1966      * @see DateFormat#getDateTimeInstance
   1967      * @stable ICU 2.0
   1968      */
   1969     static final public DateFormat getDateTimeInstance(Calendar cal, int dateStyle,
   1970                                                  int timeStyle, Locale locale)
   1971     {
   1972         return getDateTimeInstance(cal, dateStyle, timeStyle, ULocale.forLocale(locale));
   1973     }
   1974 
   1975     /**
   1976      * Creates a {@link DateFormat} object that can be used to format dates and times in
   1977      * the calendar system specified by <code>cal</code>.
   1978      * @param cal   The calendar system for which a date/time format is desired.
   1979      *
   1980      * @param dateStyle The type of date format desired.  This can be
   1981      *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
   1982      *              etc.
   1983      *
   1984      * @param timeStyle The type of time format desired.  This can be
   1985      *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
   1986      *              etc.
   1987      *
   1988      * @param locale The locale for which the date/time format is desired.
   1989      *
   1990      * @see DateFormat#getDateTimeInstance
   1991      * @stable ICU 3.2
   1992      */
   1993     static final public DateFormat getDateTimeInstance(Calendar cal, int dateStyle,
   1994                                                  int timeStyle, ULocale locale)
   1995     {
   1996         if (cal == null) {
   1997             throw new IllegalArgumentException("Calendar must be supplied");
   1998         }
   1999         return get(dateStyle, timeStyle, locale, cal);
   2000     }
   2001 
   2002     /**
   2003      * Returns a date/time formatter that uses the SHORT style
   2004      * for both the date and the time.
   2005      *
   2006      * @param cal   The calendar system for which a date/time format is desired.
   2007      * @param locale The locale for which the date/time format is desired.
   2008      * @stable ICU 2.0
   2009      */
   2010     static final public DateFormat getInstance(Calendar cal, Locale locale) {
   2011         return getDateTimeInstance(cal, SHORT, SHORT, ULocale.forLocale(locale));
   2012     }
   2013 
   2014     /**
   2015      * Returns a date/time formatter that uses the SHORT style
   2016      * for both the date and the time.
   2017      *
   2018      * @param cal   The calendar system for which a date/time format is desired.
   2019      * @param locale The locale for which the date/time format is desired.
   2020      * @stable ICU 3.2
   2021      * @provisional This API might change or be removed in a future release.
   2022      */
   2023     static final public DateFormat getInstance(Calendar cal, ULocale locale) {
   2024         return getDateTimeInstance(cal, SHORT, SHORT, locale);
   2025     }
   2026 
   2027     /**
   2028      * Returns a default date/time formatter that uses the SHORT style for both the
   2029      * date and the time.
   2030      *
   2031      * @param cal   The calendar system for which a date/time format is desired.
   2032      * @stable ICU 2.0
   2033      */
   2034     static final public DateFormat getInstance(Calendar cal) {
   2035         return getInstance(cal, ULocale.getDefault(Category.FORMAT));
   2036     }
   2037 
   2038     /**
   2039      * Creates a {@link DateFormat} object for the default locale that can be used
   2040      * to format dates in the calendar system specified by <code>cal</code>.
   2041      * <p>
   2042      * @param cal   The calendar system for which a date format is desired.
   2043      *
   2044      * @param dateStyle The type of date format desired.  This can be
   2045      *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
   2046      *              etc.
   2047      * @stable ICU 2.0
   2048      */
   2049     static final public DateFormat getDateInstance(Calendar cal, int dateStyle) {
   2050         return getDateInstance(cal, dateStyle, ULocale.getDefault(Category.FORMAT));
   2051     }
   2052 
   2053     /**
   2054      * Creates a {@link DateFormat} object that can be used to format times in
   2055      * the calendar system specified by <code>cal</code>.
   2056      * @param cal   The calendar system for which a time format is desired.
   2057      *
   2058      * @param timeStyle The type of time format desired.  This can be
   2059      *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
   2060      *              etc.
   2061      *
   2062      * @see DateFormat#getTimeInstance
   2063      * @stable ICU 2.0
   2064      */
   2065     static final public DateFormat getTimeInstance(Calendar cal, int timeStyle) {
   2066         return getTimeInstance(cal, timeStyle, ULocale.getDefault(Category.FORMAT));
   2067     }
   2068 
   2069     /**
   2070      * Creates a {@link DateFormat} object for the default locale that can be used to format
   2071      * dates and times in the calendar system specified by <code>cal</code>.
   2072      * @param cal   The calendar system for which a date/time format is desired.
   2073      *
   2074      * @param dateStyle The type of date format desired.  This can be
   2075      *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
   2076      *              etc.
   2077      *
   2078      * @param timeStyle The type of time format desired.  This can be
   2079      *              {@link DateFormat#SHORT}, {@link DateFormat#MEDIUM},
   2080      *              etc.
   2081      *
   2082      * @see DateFormat#getDateTimeInstance
   2083      * @stable ICU 2.0
   2084      */
   2085     static final public DateFormat getDateTimeInstance(Calendar cal, int dateStyle, int timeStyle) {
   2086         return getDateTimeInstance(cal, dateStyle, timeStyle, ULocale.getDefault(Category.FORMAT));
   2087     }
   2088 
   2089     /**
   2090      * {@icu} Returns a {@link DateFormat} object that can be used to format dates and times in
   2091      * the default locale.
   2092      *
   2093      * @param skeleton The skeleton that selects the fields to be formatted. (Uses the
   2094      *              {@link DateTimePatternGenerator}.) This can be {@link DateFormat#ABBR_MONTH},
   2095      *              {@link DateFormat#MONTH_WEEKDAY_DAY}, etc.
   2096      *
   2097      * @stable ICU 54
   2098      */
   2099     public final static DateFormat getInstanceForSkeleton(String skeleton) {
   2100         return getPatternInstance(skeleton, ULocale.getDefault(Category.FORMAT));
   2101     }
   2102 
   2103     /**
   2104      * {@icu} Returns a {@link DateFormat} object that can be used to format dates and times in
   2105      * the given locale.
   2106      *
   2107      * @param skeleton The skeleton that selects the fields to be formatted. (Uses the
   2108      *              {@link DateTimePatternGenerator}.) This can be {@link DateFormat#ABBR_MONTH},
   2109      *              {@link DateFormat#MONTH_WEEKDAY_DAY}, etc.
   2110      *
   2111      * @param locale The locale for which the date/time format is desired.
   2112      *
   2113      * @stable ICU 54
   2114      */
   2115     public final static DateFormat getInstanceForSkeleton(String skeleton, Locale locale) {
   2116         return getPatternInstance(skeleton, ULocale.forLocale(locale));
   2117     }
   2118 
   2119     /**
   2120      * {@icu} Returns a {@link DateFormat} object that can be used to format dates and times in
   2121      * the given locale.
   2122      *
   2123      * @param skeleton The skeleton that selects the fields to be formatted. (Uses the
   2124      *              {@link DateTimePatternGenerator}.) This can be {@link DateFormat#ABBR_MONTH},
   2125      *              {@link DateFormat#MONTH_WEEKDAY_DAY}, etc.
   2126      *
   2127      * @param locale The locale for which the date/time format is desired.
   2128      *
   2129      * @stable ICU 54
   2130      */
   2131     public final static DateFormat getInstanceForSkeleton(String skeleton, ULocale locale) {
   2132         DateTimePatternGenerator generator = DateTimePatternGenerator.getInstance(locale);
   2133         final String bestPattern = generator.getBestPattern(skeleton);
   2134         return new SimpleDateFormat(bestPattern, locale);
   2135     }
   2136 
   2137     /**
   2138      * {@icu} Creates a {@link DateFormat} object that can be used to format dates and
   2139      * times in the calendar system specified by <code>cal</code>.
   2140      *
   2141      * @param cal   The calendar system for which a date/time format is desired.
   2142      *
   2143      * @param skeleton The skeleton that selects the fields to be formatted. (Uses the
   2144      *              {@link DateTimePatternGenerator}.)  This can be
   2145      *              {@link DateFormat#ABBR_MONTH}, {@link DateFormat#MONTH_WEEKDAY_DAY},
   2146      *              etc.
   2147      *
   2148      * @param locale The locale for which the date/time format is desired.
   2149      *
   2150      * @stable ICU 54
   2151      */
   2152     public final static DateFormat getInstanceForSkeleton(Calendar cal, String skeleton, Locale locale) {
   2153         return getPatternInstance(cal, skeleton, ULocale.forLocale(locale));
   2154     }
   2155 
   2156     /**
   2157      * {@icu} Creates a {@link DateFormat} object that can be used to format dates and
   2158      * times in the calendar system specified by <code>cal</code>.
   2159      *
   2160      * @param cal   The calendar system for which a date/time format is desired.
   2161      *
   2162      * @param skeleton The skeleton that selects the fields to be formatted. (Uses the
   2163      *              {@link DateTimePatternGenerator}.)  This can be
   2164      *              {@link DateFormat#ABBR_MONTH}, {@link DateFormat#MONTH_WEEKDAY_DAY},
   2165      *              etc.
   2166      *
   2167      * @param locale The locale for which the date/time format is desired.
   2168      *
   2169      * @stable ICU 54
   2170      */
   2171     public final static DateFormat getInstanceForSkeleton(
   2172         Calendar cal, String skeleton, ULocale locale) {
   2173         DateTimePatternGenerator generator = DateTimePatternGenerator.getInstance(locale);
   2174         final String bestPattern = generator.getBestPattern(skeleton);
   2175         SimpleDateFormat format = new SimpleDateFormat(bestPattern, locale);
   2176         format.setCalendar(cal);
   2177         return format;
   2178     }
   2179 
   2180 
   2181     /**
   2182      * {@icu} Returns a {@link DateFormat} object that can be used to format dates and times in
   2183      * the default locale.
   2184      * The getInstanceForSkeleton methods are preferred over the getPatternInstance methods.
   2185      *
   2186      * @param skeleton The skeleton that selects the fields to be formatted. (Uses the
   2187      *              {@link DateTimePatternGenerator}.) This can be {@link DateFormat#ABBR_MONTH},
   2188      *              {@link DateFormat#MONTH_WEEKDAY_DAY}, etc.
   2189      *
   2190      * @stable ICU 4.0
   2191      */
   2192     public final static DateFormat getPatternInstance(String skeleton) {
   2193         return getInstanceForSkeleton(skeleton);
   2194     }
   2195 
   2196     /**
   2197      * {@icu} Returns a {@link DateFormat} object that can be used to format dates and times in
   2198      * the given locale.
   2199      * The getInstanceForSkeleton methods are preferred over the getPatternInstance methods.
   2200      *
   2201      * @param skeleton The skeleton that selects the fields to be formatted. (Uses the
   2202      *              {@link DateTimePatternGenerator}.) This can be {@link DateFormat#ABBR_MONTH},
   2203      *              {@link DateFormat#MONTH_WEEKDAY_DAY}, etc.
   2204      *
   2205      * @param locale The locale for which the date/time format is desired.
   2206      *
   2207      * @stable ICU 4.0
   2208      */
   2209     public final static DateFormat getPatternInstance(String skeleton, Locale locale) {
   2210         return getInstanceForSkeleton(skeleton, locale);
   2211     }
   2212 
   2213     /**
   2214      * {@icu} Returns a {@link DateFormat} object that can be used to format dates and times in
   2215      * the given locale.
   2216      * The getInstanceForSkeleton methods are preferred over the getPatternInstance methods.
   2217      *
   2218      * @param skeleton The skeleton that selects the fields to be formatted. (Uses the
   2219      *              {@link DateTimePatternGenerator}.) This can be {@link DateFormat#ABBR_MONTH},
   2220      *              {@link DateFormat#MONTH_WEEKDAY_DAY}, etc.
   2221      *
   2222      * @param locale The locale for which the date/time format is desired.
   2223      *
   2224      * @stable ICU 4.0
   2225      */
   2226     public final static DateFormat getPatternInstance(String skeleton, ULocale locale) {
   2227         return getInstanceForSkeleton(skeleton, locale);
   2228     }
   2229 
   2230     /**
   2231      * {@icu} Creates a {@link DateFormat} object that can be used to format dates and
   2232      * times in the calendar system specified by <code>cal</code>.
   2233      * The getInstanceForSkeleton methods are preferred over the getPatternInstance methods.
   2234      *
   2235      * @param cal   The calendar system for which a date/time format is desired.
   2236      *
   2237      * @param skeleton The skeleton that selects the fields to be formatted. (Uses the
   2238      *              {@link DateTimePatternGenerator}.)  This can be
   2239      *              {@link DateFormat#ABBR_MONTH}, {@link DateFormat#MONTH_WEEKDAY_DAY},
   2240      *              etc.
   2241      *
   2242      * @param locale The locale for which the date/time format is desired.
   2243      *
   2244      * @stable ICU 4.0
   2245      */
   2246     public final static DateFormat getPatternInstance(Calendar cal, String skeleton, Locale locale) {
   2247         return getInstanceForSkeleton(cal, skeleton, locale);
   2248     }
   2249 
   2250     /**
   2251      * {@icu} Creates a {@link DateFormat} object that can be used to format dates and
   2252      * times in the calendar system specified by <code>cal</code>.
   2253      * The getInstanceForSkeleton methods are preferred over the getPatternInstance methods.
   2254      *
   2255      * @param cal   The calendar system for which a date/time format is desired.
   2256      *
   2257      * @param skeleton The skeleton that selects the fields to be formatted. (Uses the
   2258      *              {@link DateTimePatternGenerator}.)  This can be
   2259      *              {@link DateFormat#ABBR_MONTH}, {@link DateFormat#MONTH_WEEKDAY_DAY},
   2260      *              etc.
   2261      *
   2262      * @param locale The locale for which the date/time format is desired.
   2263      *
   2264      * @stable ICU 4.0
   2265      */
   2266     public final static DateFormat getPatternInstance(
   2267         Calendar cal, String skeleton, ULocale locale) {
   2268         return getInstanceForSkeleton(cal, skeleton, locale);
   2269     }
   2270 
   2271     /**
   2272      * The instances of this inner class are used as attribute keys and values
   2273      * in AttributedCharacterIterator that
   2274      * DateFormat.formatToCharacterIterator() method returns.
   2275      *
   2276      * <p>There is no public constructor to this class, the only instances are the
   2277      * constants defined here.
   2278      * <p>
   2279      * @stable ICU 3.8
   2280      */
   2281     public static class Field extends Format.Field {
   2282 
   2283         private static final long serialVersionUID = -3627456821000730829L;
   2284 
   2285         // Max number of calendar fields
   2286         private static final int CAL_FIELD_COUNT;
   2287 
   2288         // Table for mapping calendar field number to DateFormat.Field
   2289         private static final Field[] CAL_FIELDS;
   2290 
   2291         // Map for resolving DateFormat.Field by name
   2292         private static final Map<String, Field> FIELD_NAME_MAP;
   2293 
   2294         static {
   2295             GregorianCalendar cal = new GregorianCalendar();
   2296             CAL_FIELD_COUNT = cal.getFieldCount();
   2297             CAL_FIELDS = new Field[CAL_FIELD_COUNT];
   2298             FIELD_NAME_MAP = new HashMap<String, Field>(CAL_FIELD_COUNT);
   2299         }
   2300 
   2301         // Java fields -------------------
   2302 
   2303         /**
   2304          * Constant identifying the time of day indicator(am/pm).
   2305          * @stable ICU 3.8
   2306          */
   2307         public static final Field AM_PM = new Field("am pm", Calendar.AM_PM);
   2308 
   2309         /**
   2310          * Constant identifying the day of month field.
   2311          * @stable ICU 3.8
   2312          */
   2313         public static final Field DAY_OF_MONTH = new Field("day of month", Calendar.DAY_OF_MONTH);
   2314 
   2315         /**
   2316          * Constant identifying the day of week field.
   2317          * @stable ICU 3.8
   2318          */
   2319         public static final Field DAY_OF_WEEK = new Field("day of week", Calendar.DAY_OF_WEEK);
   2320 
   2321         /**
   2322          * Constant identifying the day of week in month field.
   2323          * @stable ICU 3.8
   2324          */
   2325         public static final Field DAY_OF_WEEK_IN_MONTH =
   2326             new Field("day of week in month", Calendar.DAY_OF_WEEK_IN_MONTH);
   2327 
   2328         /**
   2329          * Constant identifying the day of year field.
   2330          * @stable ICU 3.8
   2331          */
   2332         public static final Field DAY_OF_YEAR = new Field("day of year", Calendar.DAY_OF_YEAR);
   2333 
   2334         /**
   2335          * Constant identifying the era field.
   2336          * @stable ICU 3.8
   2337          */
   2338         public static final Field ERA = new Field("era", Calendar.ERA);
   2339 
   2340         /**
   2341          * Constant identifying the hour(0-23) of day field.
   2342          * @stable ICU 3.8
   2343          */
   2344         public static final Field HOUR_OF_DAY0 = new Field("hour of day", Calendar.HOUR_OF_DAY);
   2345 
   2346         /**
   2347          * Constant identifying the hour(1-24) of day field.
   2348          * @stable ICU 3.8
   2349          */
   2350         public static final Field HOUR_OF_DAY1 = new Field("hour of day 1", -1);
   2351 
   2352         /**
   2353          * Constant identifying the hour(0-11) field.
   2354          * @stable ICU 3.8
   2355          */
   2356         public static final Field HOUR0 = new Field("hour", Calendar.HOUR);
   2357 
   2358         /**
   2359          * Constant identifying the hour(1-12) field.
   2360          * @stable ICU 3.8
   2361          */
   2362         public static final Field HOUR1 = new Field("hour 1", -1);
   2363 
   2364         /**
   2365          * Constant identifying the millisecond field.
   2366          * @stable ICU 3.8
   2367          */
   2368         public static final Field MILLISECOND = new Field("millisecond", Calendar.MILLISECOND);
   2369 
   2370         /**
   2371          * Constant identifying the minute field.
   2372          * @stable ICU 3.8
   2373          */
   2374         public static final Field MINUTE = new Field("minute", Calendar.MINUTE);
   2375 
   2376         /**
   2377          * Constant identifying the month field.
   2378          * @stable ICU 3.8
   2379          */
   2380         public static final Field MONTH = new Field("month", Calendar.MONTH);
   2381 
   2382         /**
   2383          * Constant identifying the second field.
   2384          * @stable ICU 3.8
   2385          */
   2386         public static final Field SECOND = new Field("second", Calendar.SECOND);
   2387 
   2388         /**
   2389          * Constant identifying the time zone field.
   2390          * @stable ICU 3.8
   2391          */
   2392         public static final Field TIME_ZONE = new Field("time zone", -1);
   2393 
   2394         /**
   2395          * Constant identifying the week of month field.
   2396          * @stable ICU 3.8
   2397          */
   2398         public static final Field WEEK_OF_MONTH =
   2399             new Field("week of month", Calendar.WEEK_OF_MONTH);
   2400 
   2401         /**
   2402          * Constant identifying the week of year field.
   2403          * @stable ICU 3.8
   2404          */
   2405         public static final Field WEEK_OF_YEAR = new Field("week of year", Calendar.WEEK_OF_YEAR);
   2406 
   2407         /**
   2408          * Constant identifying the year field.
   2409          * @stable ICU 3.8
   2410          */
   2411         public static final Field YEAR = new Field("year", Calendar.YEAR);
   2412 
   2413 
   2414         // ICU only fields -------------------
   2415 
   2416         /**
   2417          * Constant identifying the local day of week field.
   2418          * @stable ICU 3.8
   2419          */
   2420         public static final Field DOW_LOCAL = new Field("local day of week", Calendar.DOW_LOCAL);
   2421 
   2422         /**
   2423          * Constant identifying the extended year field.
   2424          * @stable ICU 3.8
   2425          */
   2426         public static final Field EXTENDED_YEAR = new Field("extended year",
   2427                                                             Calendar.EXTENDED_YEAR);
   2428 
   2429         /**
   2430          * Constant identifying the Julian day field.
   2431          * @stable ICU 3.8
   2432          */
   2433         public static final Field JULIAN_DAY = new Field("Julian day", Calendar.JULIAN_DAY);
   2434 
   2435         /**
   2436          * Constant identifying the milliseconds in day field.
   2437          * @stable ICU 3.8
   2438          */
   2439         public static final Field MILLISECONDS_IN_DAY =
   2440             new Field("milliseconds in day", Calendar.MILLISECONDS_IN_DAY);
   2441 
   2442         /**
   2443          * Constant identifying the year used with week of year field.
   2444          * @stable ICU 3.8
   2445          */
   2446         public static final Field YEAR_WOY = new Field("year for week of year", Calendar.YEAR_WOY);
   2447 
   2448         /**
   2449          * Constant identifying the quarter field.
   2450          * @stable ICU 3.8
   2451          */
   2452         public static final Field QUARTER = new Field("quarter", -1);
   2453 
   2454         /**
   2455          * Constant identifying the related year field.
   2456          * @internal
   2457          * @deprecated This API is ICU internal only.
   2458          */
   2459         @Deprecated
   2460         public static final Field RELATED_YEAR = new Field("related year", -1);
   2461 
   2462         /**
   2463          * {@icu} Constant identifying the am/pm/midnight/noon field.
   2464          * @stable ICU 57
   2465          */
   2466         public static final Field AM_PM_MIDNIGHT_NOON = new Field("am/pm/midnight/noon", -1);
   2467 
   2468         /**
   2469          * {@icu} Constant identifying the flexible day period field.
   2470          * @stable ICU 57
   2471          */
   2472         public static final Field FLEXIBLE_DAY_PERIOD = new Field("flexible day period", -1);
   2473 
   2474         /**
   2475          * Constant identifying the time separator field.
   2476          * @internal
   2477          * @deprecated This API is ICU internal only.
   2478          */
   2479         @Deprecated
   2480         public static final Field TIME_SEPARATOR = new Field("time separator", -1);
   2481 
   2482         // Stand alone types are variants for its base types.  So we do not define Field for
   2483         // them.
   2484         /*
   2485         public static final Field STANDALONE_DAY =
   2486             new Field("stand alone day of week", Calendar.DAY_OF_WEEK);
   2487         public static final Field STANDALONE_MONTH = new Field("stand alone month", Calendar.MONTH);
   2488         public static final Field STANDALONE_QUARTER = new Field("stand alone quarter", -1);
   2489         */
   2490 
   2491         // Corresponding calendar field
   2492         private final int calendarField;
   2493 
   2494         /**
   2495          * Constructs a <code>DateFormat.Field</code> with the given name and
   2496          * the <code>Calendar</code> field which this attribute represents.  Use -1 for
   2497          * <code>calendarField</code> if this field does not have a corresponding
   2498          * <code>Calendar</code> field.
   2499          *
   2500          * @param name          Name of the attribute
   2501          * @param calendarField <code>Calendar</code> field constant
   2502          *
   2503          * @stable ICU 3.8
   2504          */
   2505         protected Field(String name, int calendarField) {
   2506             super(name);
   2507             this.calendarField = calendarField;
   2508             if (this.getClass() == DateFormat.Field.class) {
   2509                 FIELD_NAME_MAP.put(name, this);
   2510                 if (calendarField >= 0 && calendarField < CAL_FIELD_COUNT) {
   2511                     CAL_FIELDS[calendarField] = this;
   2512                 }
   2513             }
   2514         }
   2515 
   2516         /**
   2517          * Returns the <code>Field</code> constant that corresponds to the <code>
   2518          * Calendar</code> field <code>calendarField</code>.  If there is no
   2519          * corresponding <code>Field</code> is available, null is returned.
   2520          *
   2521          * @param calendarField <code>Calendar</code> field constant
   2522          * @return <code>Field</code> associated with the <code>calendarField</code>,
   2523          * or null if no associated <code>Field</code> is available.
   2524          * @throws IllegalArgumentException if <code>calendarField</code> is not
   2525          * a valid <code>Calendar</code> field constant.
   2526          *
   2527          * @stable ICU 3.8
   2528          */
   2529         public static DateFormat.Field ofCalendarField(int calendarField) {
   2530             if (calendarField < 0 || calendarField >= CAL_FIELD_COUNT) {
   2531                 throw new IllegalArgumentException("Calendar field number is out of range");
   2532             }
   2533             return CAL_FIELDS[calendarField];
   2534         }
   2535 
   2536         /**
   2537          * Returns the <code>Calendar</code> field associated with this attribute.
   2538          * If there is no corresponding <code>Calendar</code> available, this will
   2539          * return -1.
   2540          *
   2541          * @return <code>Calendar</code> constant for this attribute.
   2542          *
   2543          * @stable ICU 3.8
   2544          */
   2545         public int getCalendarField() {
   2546             return calendarField;
   2547         }
   2548 
   2549         /**
   2550          * Resolves instances being deserialized to the predefined constants.
   2551          *
   2552          * @throws InvalidObjectException if the constant could not be resolved.
   2553          *
   2554          * @stable ICU 3.8
   2555          */
   2556         @Override
   2557         protected Object readResolve() throws InvalidObjectException {
   2558             ///CLOVER:OFF
   2559             if (this.getClass() != DateFormat.Field.class) {
   2560                 throw new InvalidObjectException(
   2561                     "A subclass of DateFormat.Field must implement readResolve.");
   2562             }
   2563             ///CLOVER:ON
   2564             Object o = FIELD_NAME_MAP.get(this.getName());
   2565             ///CLOVER:OFF
   2566             if (o == null) {
   2567                 throw new InvalidObjectException("Unknown attribute name.");
   2568             }
   2569             ///CLOVER:ON
   2570             return o;
   2571         }
   2572     }
   2573 }
   2574