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
8package com.ibm.icu.text;
9
10import java.io.IOException;
11import java.io.InvalidObjectException;
12import java.io.ObjectInputStream;
13import java.text.FieldPosition;
14import java.text.Format;
15import java.text.ParseException;
16import java.text.ParsePosition;
17import java.util.Arrays;
18import java.util.Date;
19import java.util.EnumSet;
20import java.util.HashMap;
21import java.util.List;
22import java.util.Locale;
23import java.util.Map;
24import java.util.MissingResourceException;
25
26import com.ibm.icu.impl.ICUResourceBundle;
27import com.ibm.icu.impl.RelativeDateFormat;
28import com.ibm.icu.util.Calendar;
29import com.ibm.icu.util.GregorianCalendar;
30import com.ibm.icu.util.TimeZone;
31import com.ibm.icu.util.ULocale;
32import 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 */
144public 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