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