1 /*********************************************************************
2 * Copyright (C) 2000-2012, International Business Machines Corporation and
3 * others. All Rights Reserved.
4 *********************************************************************
6 package com.ibm.icu.text;
8 import java.io.InvalidObjectException;
9 import java.text.FieldPosition;
10 import java.util.Locale;
12 import com.ibm.icu.util.Calendar;
13 import com.ibm.icu.util.ChineseCalendar;
14 import com.ibm.icu.util.TimeZone;
15 import com.ibm.icu.util.ULocale;
18 * A concrete {@link DateFormat} for {@link com.ibm.icu.util.ChineseCalendar}.
19 * This class handles a <code>ChineseCalendar</code>-specific field,
20 * <code>ChineseCalendar.IS_LEAP_MONTH</code>. It also redefines the
21 * handling of two fields, <code>ERA</code> and <code>YEAR</code>. The
22 * former is displayed numerically, instead of symbolically, since it is
23 * the numeric cycle number in <code>ChineseCalendar</code>. The latter is
24 * numeric, as before, but has no special 2-digit Y2K behavior.
26 * <p>With regard to <code>ChineseCalendar.IS_LEAP_MONTH</code>, this
27 * class handles parsing specially. If no string symbol is found at all,
28 * this is taken as equivalent to an <code>IS_LEAP_MONTH</code> value of
29 * zero. This allows formats to display a special string (e.g., "*") for
30 * leap months, but no string for normal months.
32 * <p>Summary of field changes vs. {@link SimpleDateFormat}:<pre>
33 * Symbol Meaning Presentation Example
34 * ------ ------- ------------ -------
36 * y year of cycle (1..60) (Number) 17
37 * l is leap month (Text) 4637
40 * @see com.ibm.icu.util.ChineseCalendar
41 * @see ChineseDateFormatSymbols
43 * @deprecated ICU 50 Use SimpleDateFormat instead.
45 public class ChineseDateFormat extends SimpleDateFormat {
46 // Generated by serialver from JDK 1.4.1_01
47 static final long serialVersionUID = -4610300753104099899L;
49 // TODO Finish the constructors
52 * Construct a ChineseDateFormat from a date format pattern and locale
53 * @param pattern the pattern
54 * @param locale the locale
57 public ChineseDateFormat(String pattern, Locale locale) {
58 this(pattern, ULocale.forLocale(locale));
62 * Construct a ChineseDateFormat from a date format pattern and locale
63 * @param pattern the pattern
64 * @param locale the locale
67 public ChineseDateFormat(String pattern, ULocale locale) {
68 this(pattern, null, locale);
72 * Construct a ChineseDateFormat from a date format pattern, numbering system override and locale
73 * @param pattern the pattern
74 * @param override The override string. A numbering system override string can take one of the following forms:
75 * 1). If just a numbering system name is specified, it applies to all numeric fields in the date format pattern.
76 * 2). To specify an alternate numbering system on a field by field basis, use the field letters from the pattern
77 * followed by an = sign, followed by the numbering system name. For example, to specify that just the year
78 * be formatted using Hebrew digits, use the override "y=hebr". Multiple overrides can be specified in a single
79 * string by separating them with a semi-colon. For example, the override string "m=thai;y=deva" would format using
80 * Thai digits for the month and Devanagari digits for the year.
81 * @param locale the locale
84 public ChineseDateFormat(String pattern, String override, ULocale locale) {
85 super(pattern, new ChineseDateFormatSymbols(locale),
86 new ChineseCalendar(TimeZone.getDefault(), locale), locale, true, override);
89 // NOTE: This API still exists; we just inherit it from SimpleDateFormat
94 // protected String subFormat(char ch, int count, int beginOffset,
95 // FieldPosition pos, DateFormatSymbols formatData,
98 // case 'G': // 'G' - ERA
99 // return zeroPaddingNumber(cal.get(Calendar.ERA), 1, 9);
100 // case 'l': // 'l' - IS_LEAP_MONTH
102 // ChineseDateFormatSymbols symbols =
103 // (ChineseDateFormatSymbols) formatData;
104 // return symbols.getLeapMonth(cal.get(
105 // ChineseCalendar.IS_LEAP_MONTH));
108 // return super.subFormat(ch, count, beginOffset, pos, formatData, cal);
115 * @deprecated This API is ICU internal only.
117 protected void subFormat(StringBuffer buf,
118 char ch, int count, int beginOffset,
119 int fieldNum, DisplayContext capitalizationContext,
123 // Logic to handle 'G' for chinese calendar is moved into SimpleDateFormat,
124 // and obsolete pattern char 'l' is now ignored in SimpleDateFormat, so we
125 // just use its implementation
126 super.subFormat(buf, ch, count, beginOffset, fieldNum, capitalizationContext, pos, cal);
128 // The following is no longer an issue for this subclass...
129 // TODO: add code to set FieldPosition for 'G' and 'l' fields. This
130 // is a DESIGN FLAW -- subclasses shouldn't have to duplicate the
131 // code that handles this at the end of SimpleDateFormat.subFormat.
132 // The logic should be moved up into SimpleDateFormat.format.
140 protected int subParse(String text, int start, char ch, int count, boolean obeyCount, boolean allowNegative,
141 boolean[] ambiguousYear, Calendar cal) {
142 // Logic to handle numeric 'G' eras for chinese calendar, and to skip special 2-digit year
143 // handling for chinese calendar, is moved into SimpleDateFormat, so delete here.
144 // Obsolete pattern char 'l' is now ignored for parsing in SimpleDateFormat, no handling
146 // So just use SimpleDateFormat implementation for this.
147 // just use its implementation
148 return super.subParse(text, start, ch, count, obeyCount, allowNegative, ambiguousYear, cal);
156 protected DateFormat.Field patternCharToDateFormatField(char ch) {
157 // no longer any field corresponding to pattern char 'l'
158 return super.patternCharToDateFormatField(ch);
162 * The instances of this inner class are used as attribute keys and values
163 * in AttributedCharacterIterator that
164 * ChineseDateFormat.formatToCharacterIterator() method returns.
166 * There is no public constructor to this class, the only instances are the
167 * constants defined here.
171 public static class Field extends DateFormat.Field {
173 private static final long serialVersionUID = -5102130532751400330L;
176 * Constant identifying the leap month marker.
177 * @deprecated ICU 50 This field is only used by the deprecated ChineseDateFormat class.
179 public static final Field IS_LEAP_MONTH = new Field("is leap month", ChineseCalendar.IS_LEAP_MONTH);
182 * Constructs a <code>ChineseDateFormat.Field</code> with the given name and
183 * the <code>ChineseCalendar</code> field which this attribute represents.
184 * Use -1 for <code>calendarField</code> if this field does not have a
185 * corresponding <code>ChineseCalendar</code> field.
187 * @param name Name of the attribute
188 * @param calendarField <code>Calendar</code> field constant
192 protected Field(String name, int calendarField) {
193 super(name, calendarField);
197 * Returns the <code>Field</code> constant that corresponds to the <code>
198 * ChineseCalendar</code> field <code>calendarField</code>. If there is no
199 * corresponding <code>Field</code> is available, null is returned.
201 * @param calendarField <code>ChineseCalendar</code> field constant
202 * @return <code>Field</code> associated with the <code>calendarField</code>,
203 * or null if no associated <code>Field</code> is available.
204 * @throws IllegalArgumentException if <code>calendarField</code> is not
205 * a valid <code>Calendar</code> field constant.
209 public static DateFormat.Field ofCalendarField(int calendarField) {
210 // Should we remove the following, since there is no longer a specific
211 // date format field for leap month (since 'l' pattern char is obsolete)?
212 if (calendarField == ChineseCalendar.IS_LEAP_MONTH) {
213 return IS_LEAP_MONTH;
215 return DateFormat.Field.ofCalendarField(calendarField);
224 protected Object readResolve() throws InvalidObjectException {
225 if (this.getClass() != ChineseDateFormat.Field.class) {
226 throw new InvalidObjectException("A subclass of ChineseDateFormat.Field must implement readResolve.");
228 if (this.getName().equals(IS_LEAP_MONTH.getName())) {
229 return IS_LEAP_MONTH;
231 throw new InvalidObjectException("Unknown attribute name.");