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