]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_8_1_1/main/classes/core/src/com/ibm/icu/text/ChineseDateFormat.java
Added flags.
[Dictionary.git] / jars / icu4j-4_8_1_1 / main / classes / core / src / com / ibm / icu / text / ChineseDateFormat.java
1 /*********************************************************************
2  * Copyright (C) 2000-2011, International Business Machines Corporation and
3  * others. All Rights Reserved.
4  *********************************************************************
5  */
6 package com.ibm.icu.text;
7
8 import java.io.InvalidObjectException;
9 import java.text.FieldPosition;
10 import java.text.ParsePosition;
11 import java.util.Locale;
12
13 import com.ibm.icu.impl.PatternProps;
14 import com.ibm.icu.util.Calendar;
15 import com.ibm.icu.util.ChineseCalendar;
16 import com.ibm.icu.util.TimeZone;
17 import com.ibm.icu.util.ULocale;
18
19 /**
20  * A concrete {@link DateFormat} for {@link com.ibm.icu.util.ChineseCalendar}.
21  * This class handles a <code>ChineseCalendar</code>-specific field,
22  * <code>ChineseCalendar.IS_LEAP_MONTH</code>.  It also redefines the
23  * handling of two fields, <code>ERA</code> and <code>YEAR</code>.  The
24  * former is displayed numerically, instead of symbolically, since it is
25  * the numeric cycle number in <code>ChineseCalendar</code>.  The latter is
26  * numeric, as before, but has no special 2-digit Y2K behavior.
27  *
28  * <p>With regard to <code>ChineseCalendar.IS_LEAP_MONTH</code>, this
29  * class handles parsing specially.  If no string symbol is found at all,
30  * this is taken as equivalent to an <code>IS_LEAP_MONTH</code> value of
31  * zero.  This allows formats to display a special string (e.g., "*") for
32  * leap months, but no string for normal months.
33  *
34  * <p>Summary of field changes vs. {@link SimpleDateFormat}:<pre>
35  * Symbol   Meaning                 Presentation        Example
36  * ------   -------                 ------------        -------
37  * G        cycle                   (Number)            78
38  * y        year of cycle (1..60)   (Number)            17
39  * l        is leap month           (Text)              4637
40  * </pre>
41  *
42  * @see com.ibm.icu.util.ChineseCalendar
43  * @see ChineseDateFormatSymbols
44  * @author Alan Liu
45  * @stable ICU 2.0
46  */
47 public class ChineseDateFormat extends SimpleDateFormat {
48     // Generated by serialver from JDK 1.4.1_01
49     static final long serialVersionUID = -4610300753104099899L;
50     
51     // TODO Finish the constructors
52
53     /**
54      * Construct a ChineseDateFormat from a date format pattern and locale
55      * @param pattern the pattern
56      * @param locale the locale
57      * @stable ICU 2.0
58      */
59    public ChineseDateFormat(String pattern, Locale locale) {
60        this(pattern, ULocale.forLocale(locale));
61     }
62
63     /**
64      * Construct a ChineseDateFormat from a date format pattern and locale
65      * @param pattern the pattern
66      * @param locale the locale
67      * @stable ICU 3.2
68      */
69    public ChineseDateFormat(String pattern, ULocale locale) {
70        this(pattern, null, locale);
71     }
72
73     /**
74      * Construct a ChineseDateFormat from a date format pattern, numbering system override and locale
75      * @param pattern the pattern
76      * @param override The override string.  A numbering system override string can take one of the following forms:
77      *     1). If just a numbering system name is specified, it applies to all numeric fields in the date format pattern.
78      *     2). To specify an alternate numbering system on a field by field basis, use the field letters from the pattern
79      *         followed by an = sign, followed by the numbering system name.  For example, to specify that just the year
80      *         be formatted using Hebrew digits, use the override "y=hebr".  Multiple overrides can be specified in a single
81      *         string by separating them with a semi-colon. For example, the override string "m=thai;y=deva" would format using
82      *         Thai digits for the month and Devanagari digits for the year.
83      * @param locale the locale
84      * @stable ICU 4.2
85      */
86    public ChineseDateFormat(String pattern, String override, ULocale locale) {
87        super(pattern, new ChineseDateFormatSymbols(locale), 
88                new ChineseCalendar(TimeZone.getDefault(), locale), locale, true, override);
89     }
90
91 // NOTE: This API still exists; we just inherit it from SimpleDateFormat
92 // as of ICU 3.0
93 //  /**
94 //   * @stable ICU 2.0
95 //   */
96 //  protected String subFormat(char ch, int count, int beginOffset,
97 //                             FieldPosition pos, DateFormatSymbols formatData,
98 //                             Calendar cal)  {
99 //      switch (ch) {
100 //      case 'G': // 'G' - ERA
101 //          return zeroPaddingNumber(cal.get(Calendar.ERA), 1, 9);
102 //      case 'l': // 'l' - IS_LEAP_MONTH
103 //          {
104 //              ChineseDateFormatSymbols symbols =
105 //                  (ChineseDateFormatSymbols) formatData;
106 //              return symbols.getLeapMonth(cal.get(
107 //                             ChineseCalendar.IS_LEAP_MONTH));
108 //          }
109 //      default:
110 //          return super.subFormat(ch, count, beginOffset, pos, formatData, cal);
111 //      }
112 //  }    
113
114     /**
115      * {@inheritDoc}
116      * @internal
117      * @deprecated This API is ICU internal only.
118      */
119     protected void subFormat(StringBuffer buf,
120                              char ch, int count, int beginOffset,
121                              FieldPosition pos,
122                              Calendar cal) {
123
124         switch (ch) {
125         case 'G': // 'G' - ERA
126             zeroPaddingNumber(numberFormat,buf, cal.get(Calendar.ERA), 1, 9);
127             break;
128         case 'l': // 'l' - IS_LEAP_MONTH
129             buf.append(((ChineseDateFormatSymbols) getSymbols()).
130                        getLeapMonth(cal.get(ChineseCalendar.IS_LEAP_MONTH)));
131             break;
132         default:
133             super.subFormat(buf, ch, count, beginOffset, pos, cal);
134             break;
135         }
136
137         // TODO: add code to set FieldPosition for 'G' and 'l' fields. This
138         // is a DESIGN FLAW -- subclasses shouldn't have to duplicate the
139         // code that handles this at the end of SimpleDateFormat.subFormat.
140         // The logic should be moved up into SimpleDateFormat.format.
141     }
142
143     /**
144      * {@inheritDoc}
145      * 
146      * @stable ICU 2.0
147      */
148     protected int subParse(String text, int start, char ch, int count, boolean obeyCount, boolean allowNegative,
149             boolean[] ambiguousYear, Calendar cal) {
150         if (ch != 'G' && ch != 'l' && ch != 'y') {
151             return super.subParse(text, start, ch, count, obeyCount, allowNegative, ambiguousYear, cal);
152         }
153
154         // Skip whitespace
155         start = PatternProps.skipWhiteSpace(text, start);
156
157         ParsePosition pos = new ParsePosition(start);
158
159         switch (ch) {
160         case 'G': // 'G' - ERA
161         case 'y': // 'y' - YEAR, but without the 2-digit Y2K adjustment
162         {
163             Number number = null;
164             if (obeyCount) {
165                 if ((start + count) > text.length()) {
166                     return -start;
167                 }
168                 number = numberFormat.parse(text.substring(0, start + count), pos);
169             } else {
170                 number = numberFormat.parse(text, pos);
171             }
172             if (number == null) {
173                 return -start;
174             }
175             int value = number.intValue();
176             cal.set(ch == 'G' ? Calendar.ERA : Calendar.YEAR, value);
177             return pos.getIndex();
178         }
179         case 'l': // 'l' - IS_LEAP_MONTH
180         {
181             ChineseDateFormatSymbols symbols = (ChineseDateFormatSymbols) getSymbols();
182             int result = matchString(text, start, ChineseCalendar.IS_LEAP_MONTH, symbols.isLeapMonth, cal);
183             // Treat the absence of any matching string as setting
184             // IS_LEAP_MONTH to false.
185             if (result < 0) {
186                 cal.set(ChineseCalendar.IS_LEAP_MONTH, 0);
187                 result = start;
188             }
189             return result;
190         }
191             ///CLOVER:OFF
192         default:
193             return 0; // This can never happen
194             ///CLOVER:ON
195         }
196     }
197
198     /**
199      * {@inheritDoc}
200      * 
201      * @stable ICU 3.8
202      */
203     protected DateFormat.Field patternCharToDateFormatField(char ch) {
204         if (ch == 'l') {
205             return ChineseDateFormat.Field.IS_LEAP_MONTH;
206         }
207         return super.patternCharToDateFormatField(ch);
208     }
209
210     /**
211      * The instances of this inner class are used as attribute keys and values
212      * in AttributedCharacterIterator that
213      * ChineseDateFormat.formatToCharacterIterator() method returns.
214      * <p>
215      * There is no public constructor to this class, the only instances are the
216      * constants defined here.
217      * <p>
218      * @stable ICU 3.8
219      */
220     public static class Field extends DateFormat.Field {
221
222         private static final long serialVersionUID = -5102130532751400330L;
223
224         /**
225          * Constant identifying the leap month marker.
226          * @stable ICU 3.8
227          */
228         public static final Field IS_LEAP_MONTH = new Field("is leap month", ChineseCalendar.IS_LEAP_MONTH);
229
230         /**
231          * Constructs a <code>ChineseDateFormat.Field</code> with the given name and
232          * the <code>ChineseCalendar</code> field which this attribute represents.
233          * Use -1 for <code>calendarField</code> if this field does not have a
234          * corresponding <code>ChineseCalendar</code> field.
235          * 
236          * @param name          Name of the attribute
237          * @param calendarField <code>Calendar</code> field constant
238          * 
239          * @stable ICU 3.8
240          */
241         protected Field(String name, int calendarField) {
242             super(name, calendarField);
243         }
244
245         /**
246          * Returns the <code>Field</code> constant that corresponds to the <code>
247          * ChineseCalendar</code> field <code>calendarField</code>.  If there is no
248          * corresponding <code>Field</code> is available, null is returned.
249          * 
250          * @param calendarField <code>ChineseCalendar</code> field constant
251          * @return <code>Field</code> associated with the <code>calendarField</code>,
252          * or null if no associated <code>Field</code> is available.
253          * @throws IllegalArgumentException if <code>calendarField</code> is not
254          * a valid <code>Calendar</code> field constant.
255          * 
256          * @stable ICU 3.8
257          */
258         public static DateFormat.Field ofCalendarField(int calendarField) {
259             if (calendarField == ChineseCalendar.IS_LEAP_MONTH) {
260                 return IS_LEAP_MONTH;
261             }
262             return DateFormat.Field.ofCalendarField(calendarField);
263         }
264
265         /**
266          * {@inheritDoc}
267          * 
268          * @stable ICU 3.8
269          */
270         ///CLOVER:OFF
271         protected Object readResolve() throws InvalidObjectException {
272             if (this.getClass() != ChineseDateFormat.Field.class) {
273                 throw new InvalidObjectException("A subclass of ChineseDateFormat.Field must implement readResolve.");
274             }
275             if (this.getName().equals(IS_LEAP_MONTH.getName())) {
276                 return IS_LEAP_MONTH;
277             } else {
278                 throw new InvalidObjectException("Unknown attribute name.");
279             }
280         }
281         ///CLOVER:ON
282     }
283 }