一、前言
对于apache-rat(0.9)包中org.apache.commons.lang.time.DateFormatUtils日期格式工具类,进行yyyy-MM-dd'T'HH:mm:ss"、yyyy-MM-dd'T'HH:mm:ssZZ、HH:mm:ssZZ、yyyy-MM-dd等待不同格式的转换处理。
二、源码说明
1.DateUtils日期工具类
package org.apache.commons.lang.time;@b@@b@import java.util.Date;@b@import java.util.Locale;@b@import java.util.TimeZone;@b@@b@public class DateFormatUtils@b@{@b@ public static final FastDateFormat ISO_DATETIME_FORMAT = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss");@b@ public static final FastDateFormat ISO_DATETIME_TIME_ZONE_FORMAT = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZZ");@b@ public static final FastDateFormat ISO_DATE_FORMAT = FastDateFormat.getInstance("yyyy-MM-dd");@b@ public static final FastDateFormat ISO_DATE_TIME_ZONE_FORMAT = FastDateFormat.getInstance("yyyy-MM-ddZZ");@b@ public static final FastDateFormat ISO_TIME_FORMAT = FastDateFormat.getInstance("'T'HH:mm:ss");@b@ public static final FastDateFormat ISO_TIME_TIME_ZONE_FORMAT = FastDateFormat.getInstance("'T'HH:mm:ssZZ");@b@ public static final FastDateFormat ISO_TIME_NO_T_FORMAT = FastDateFormat.getInstance("HH:mm:ss");@b@ public static final FastDateFormat ISO_TIME_NO_T_TIME_ZONE_FORMAT = FastDateFormat.getInstance("HH:mm:ssZZ");@b@ public static final FastDateFormat SMTP_DATETIME_FORMAT = FastDateFormat.getInstance("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US);@b@@b@ public static String format(long millis, String pattern)@b@ {@b@ return format(new Date(millis), pattern, null, null);@b@ }@b@@b@ public static String format(long millis, String pattern, Locale locale)@b@ {@b@ return format(new Date(millis), pattern, null, locale);@b@ }@b@@b@ public static String format(long millis, String pattern, TimeZone timeZone)@b@ {@b@ return format(new Date(millis), pattern, timeZone, null);@b@ }@b@@b@ public static String format(long millis, String pattern, TimeZone timeZone, Locale locale)@b@ {@b@ return format(new Date(millis), pattern, timeZone, locale);@b@ }@b@@b@ public static String format(Date date, String pattern)@b@ {@b@ return format(date, pattern, null, null);@b@ }@b@@b@ public static String format(Date date, String pattern, Locale locale)@b@ {@b@ return format(date, pattern, null, locale);@b@ }@b@@b@ public static String format(Date date, String pattern, TimeZone timeZone)@b@ {@b@ return format(date, pattern, timeZone, null);@b@ }@b@@b@ public static String format(Date date, String pattern, TimeZone timeZone, Locale locale)@b@ {@b@ FastDateFormat df = FastDateFormat.getInstance(pattern, timeZone, locale);@b@ return df.format(date);@b@ }@b@@b@ public static String formatUTC(long millis, String pattern)@b@ {@b@ return format(new Date(millis), pattern, DateUtils.UTC_TIME_ZONE, null);@b@ }@b@@b@ public static String formatUTC(long millis, String pattern, Locale locale)@b@ {@b@ return format(new Date(millis), pattern, DateUtils.UTC_TIME_ZONE, locale);@b@ }@b@@b@ public static String formatUTC(Date date, String pattern)@b@ {@b@ return format(date, pattern, DateUtils.UTC_TIME_ZONE, null);@b@ }@b@@b@ public static String formatUTC(Date date, String pattern, Locale locale)@b@ {@b@ return format(date, pattern, DateUtils.UTC_TIME_ZONE, locale);@b@ }@b@}
2.FastDateFormat格式
package org.apache.commons.lang.time;@b@@b@import java.text.DateFormat;@b@import java.text.DateFormatSymbols;@b@import java.text.FieldPosition;@b@import java.text.Format;@b@import java.text.ParsePosition;@b@import java.text.SimpleDateFormat;@b@import java.util.ArrayList;@b@import java.util.Calendar;@b@import java.util.Date;@b@import java.util.GregorianCalendar;@b@import java.util.HashMap;@b@import java.util.List;@b@import java.util.Locale;@b@import java.util.Map;@b@import java.util.TimeZone;@b@@b@public class FastDateFormat extends Format@b@{@b@ public static final int FULL = 0;@b@ public static final int LONG = 1;@b@ public static final int MEDIUM = 2;@b@ public static final int SHORT = 3;@b@ static final double LOG_10 = Math.log(10.0D);@b@ private static String cDefaultPattern;@b@ private static Map cInstanceCache = new HashMap(7);@b@ private static Map cDateInstanceCache = new HashMap(7);@b@ private static Map cTimeInstanceCache = new HashMap(7);@b@ private static Map cDateTimeInstanceCache = new HashMap(7);@b@ private static Map cTimeZoneDisplayCache = new HashMap(7);@b@ private final String mPattern;@b@ private final TimeZone mTimeZone;@b@ private final boolean mTimeZoneForced;@b@ private final Locale mLocale;@b@ private final boolean mLocaleForced;@b@ private Rule[] mRules;@b@ private int mMaxLengthEstimate;@b@@b@ protected FastDateFormat(String pattern, TimeZone timeZone, Locale locale)@b@ {@b@ if (pattern == null)@b@ throw new IllegalArgumentException("The pattern must not be null");@b@@b@ this.mPattern = pattern;@b@@b@ this.mTimeZoneForced = (timeZone != null);@b@ if (timeZone == null)@b@ timeZone = TimeZone.getDefault();@b@@b@ this.mTimeZone = timeZone;@b@@b@ this.mLocaleForced = (locale != null);@b@ if (locale == null)@b@ locale = Locale.getDefault();@b@@b@ this.mLocale = locale;@b@ }@b@@b@ protected StringBuffer applyRules(Calendar calendar, StringBuffer buf)@b@ {@b@ Rule[] rules = this.mRules;@b@ int len = this.mRules.length;@b@ for (int i = 0; i < len; ++i)@b@ rules[i].appendTo(buf, calendar);@b@@b@ return buf;@b@ }@b@@b@ public boolean equals(Object obj)@b@ {@b@ if (obj instanceof FastDateFormat == false)@b@ return false;@b@@b@ FastDateFormat other = (FastDateFormat)obj;@b@@b@ return ((((this.mPattern == other.mPattern) || (this.mPattern.equals(other.mPattern)))) && @b@ (((this.mTimeZone == other.mTimeZone) || (this.mTimeZone.equals(other.mTimeZone)))) && @b@ (((this.mLocale == other.mLocale) || (this.mLocale.equals(other.mLocale)))) && @b@ (this.mTimeZoneForced == other.mTimeZoneForced) && @b@ (this.mLocaleForced == other.mLocaleForced));@b@ }@b@@b@ public String format(long millis)@b@ {@b@ return format(new Date(millis));@b@ }@b@@b@ public StringBuffer format(long millis, StringBuffer buf)@b@ {@b@ return format(new Date(millis), buf);@b@ }@b@@b@ public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos)@b@ {@b@ if (obj instanceof Date)@b@ return format((Date)obj, toAppendTo);@b@ if (obj instanceof Calendar)@b@ return format((Calendar)obj, toAppendTo);@b@ if (obj instanceof Long)@b@ return format(((Long)obj).longValue(), toAppendTo);@b@@b@ throw new IllegalArgumentException("Unknown class: " + @b@ obj.getClass().getName());@b@ }@b@@b@ public String format(Calendar calendar)@b@ {@b@ return format(calendar, new StringBuffer(this.mMaxLengthEstimate)).toString();@b@ }@b@@b@ public StringBuffer format(Calendar calendar, StringBuffer buf)@b@ {@b@ if (this.mTimeZoneForced) {@b@ calendar = (Calendar)calendar.clone();@b@ calendar.setTimeZone(this.mTimeZone);@b@ }@b@ return applyRules(calendar, buf);@b@ }@b@@b@ public String format(Date date)@b@ {@b@ Calendar c = new GregorianCalendar(this.mTimeZone);@b@ c.setTime(date);@b@ return applyRules(c, new StringBuffer(this.mMaxLengthEstimate)).toString();@b@ }@b@@b@ public StringBuffer format(Date date, StringBuffer buf)@b@ {@b@ Calendar c = new GregorianCalendar(this.mTimeZone);@b@ c.setTime(date);@b@ return applyRules(c, buf);@b@ }@b@@b@ public static FastDateFormat getDateInstance(int style)@b@ {@b@ return getDateInstance(style, null, null);@b@ }@b@@b@ public static FastDateFormat getDateInstance(int style, Locale locale)@b@ {@b@ return getDateInstance(style, null, locale);@b@ }@b@@b@ public static FastDateFormat getDateInstance(int style, TimeZone timeZone)@b@ {@b@ return getDateInstance(style, timeZone, null);@b@ }@b@@b@ public static synchronized FastDateFormat getDateInstance(int style, TimeZone timeZone, Locale locale)@b@ {@b@ Object key = new Integer(style);@b@ if (timeZone != null)@b@ key = new Pair(key, timeZone);@b@@b@ if (locale != null) {@b@ key = new Pair(key, locale);@b@ }@b@@b@ FastDateFormat format = (FastDateFormat)cDateInstanceCache.get(key);@b@ if (format == null) {@b@ if (locale == null)@b@ locale = Locale.getDefault();@b@@b@ try@b@ {@b@ SimpleDateFormat formatter = (SimpleDateFormat)DateFormat.getDateInstance(style, locale);@b@ String pattern = formatter.toPattern();@b@ format = getInstance(pattern, timeZone, locale);@b@ cDateInstanceCache.put(key, format);@b@ }@b@ catch (ClassCastException localClassCastException) {@b@ throw new IllegalArgumentException("No date pattern for locale: " + locale);@b@ }@b@ }@b@ return format;@b@ }@b@@b@ public static FastDateFormat getDateTimeInstance(int dateStyle, int timeStyle)@b@ {@b@ return getDateTimeInstance(dateStyle, timeStyle, null, null);@b@ }@b@@b@ public static FastDateFormat getDateTimeInstance(int dateStyle, int timeStyle, Locale locale)@b@ {@b@ return getDateTimeInstance(dateStyle, timeStyle, null, locale);@b@ }@b@@b@ public static FastDateFormat getDateTimeInstance(int dateStyle, int timeStyle, TimeZone timeZone)@b@ {@b@ return getDateTimeInstance(dateStyle, timeStyle, timeZone, null);@b@ }@b@@b@ public static synchronized FastDateFormat getDateTimeInstance(int dateStyle, int timeStyle, TimeZone timeZone, Locale locale)@b@ {@b@ Object key = new Pair(new Integer(dateStyle), new Integer(timeStyle));@b@ if (timeZone != null)@b@ key = new Pair(key, timeZone);@b@@b@ if (locale != null) {@b@ key = new Pair(key, locale);@b@ }@b@@b@ FastDateFormat format = (FastDateFormat)cDateTimeInstanceCache.get(key);@b@ if (format == null) {@b@ if (locale == null)@b@ locale = Locale.getDefault();@b@@b@ try@b@ {@b@ SimpleDateFormat formatter = (SimpleDateFormat)DateFormat.getDateTimeInstance(dateStyle, timeStyle, @b@ locale);@b@ String pattern = formatter.toPattern();@b@ format = getInstance(pattern, timeZone, locale);@b@ cDateTimeInstanceCache.put(key, format);@b@ }@b@ catch (ClassCastException localClassCastException) {@b@ throw new IllegalArgumentException("No date time pattern for locale: " + locale);@b@ }@b@ }@b@ return format;@b@ }@b@@b@ private static synchronized String getDefaultPattern()@b@ {@b@ if (cDefaultPattern == null)@b@ cDefaultPattern = new SimpleDateFormat().toPattern();@b@@b@ return cDefaultPattern;@b@ }@b@@b@ public static FastDateFormat getInstance()@b@ {@b@ return getInstance(getDefaultPattern(), null, null);@b@ }@b@@b@ public static FastDateFormat getInstance(String pattern)@b@ {@b@ return getInstance(pattern, null, null);@b@ }@b@@b@ public static FastDateFormat getInstance(String pattern, Locale locale)@b@ {@b@ return getInstance(pattern, null, locale);@b@ }@b@@b@ public static FastDateFormat getInstance(String pattern, TimeZone timeZone)@b@ {@b@ return getInstance(pattern, timeZone, null);@b@ }@b@@b@ public static synchronized FastDateFormat getInstance(String pattern, TimeZone timeZone, Locale locale)@b@ {@b@ FastDateFormat emptyFormat = new FastDateFormat(pattern, timeZone, locale);@b@ FastDateFormat format = (FastDateFormat)cInstanceCache.get(emptyFormat);@b@ if (format == null) {@b@ format = emptyFormat;@b@ format.init();@b@ cInstanceCache.put(format, format);@b@ }@b@ return format;@b@ }@b@@b@ public Locale getLocale()@b@ {@b@ return this.mLocale;@b@ }@b@@b@ public int getMaxLengthEstimate()@b@ {@b@ return this.mMaxLengthEstimate;@b@ }@b@@b@ public String getPattern()@b@ {@b@ return this.mPattern;@b@ }@b@@b@ public static FastDateFormat getTimeInstance(int style)@b@ {@b@ return getTimeInstance(style, null, null);@b@ }@b@@b@ public static FastDateFormat getTimeInstance(int style, Locale locale)@b@ {@b@ return getTimeInstance(style, null, locale);@b@ }@b@@b@ public static FastDateFormat getTimeInstance(int style, TimeZone timeZone)@b@ {@b@ return getTimeInstance(style, timeZone, null);@b@ }@b@@b@ public static synchronized FastDateFormat getTimeInstance(int style, TimeZone timeZone, Locale locale)@b@ {@b@ Object key = new Integer(style);@b@ if (timeZone != null)@b@ key = new Pair(key, timeZone);@b@@b@ if (locale != null) {@b@ key = new Pair(key, locale);@b@ }@b@@b@ FastDateFormat format = (FastDateFormat)cTimeInstanceCache.get(key);@b@ if (format == null) {@b@ if (locale == null)@b@ locale = Locale.getDefault();@b@@b@ try@b@ {@b@ SimpleDateFormat formatter = (SimpleDateFormat)DateFormat.getTimeInstance(style, locale);@b@ String pattern = formatter.toPattern();@b@ format = getInstance(pattern, timeZone, locale);@b@ cTimeInstanceCache.put(key, format);@b@ }@b@ catch (ClassCastException localClassCastException) {@b@ throw new IllegalArgumentException("No date pattern for locale: " + locale);@b@ }@b@ }@b@ return format;@b@ }@b@@b@ public TimeZone getTimeZone()@b@ {@b@ return this.mTimeZone;@b@ }@b@@b@ static synchronized String getTimeZoneDisplay(TimeZone tz, boolean daylight, int style, Locale locale)@b@ {@b@ Object key = new TimeZoneDisplayKey(tz, daylight, style, locale);@b@ String value = (String)cTimeZoneDisplayCache.get(key);@b@ if (value == null)@b@ {@b@ value = tz.getDisplayName(daylight, style, locale);@b@ cTimeZoneDisplayCache.put(key, value);@b@ }@b@ return value;@b@ }@b@@b@ public boolean getTimeZoneOverridesCalendar()@b@ {@b@ return this.mTimeZoneForced;@b@ }@b@@b@ public int hashCode()@b@ {@b@ int total = 0;@b@ total += this.mPattern.hashCode();@b@ total += this.mTimeZone.hashCode();@b@ total += ((this.mTimeZoneForced) ? 1 : 0);@b@ total += this.mLocale.hashCode();@b@ total += ((this.mLocaleForced) ? 1 : 0);@b@ return total;@b@ }@b@@b@ protected void init()@b@ {@b@ List rulesList = parsePattern();@b@ this.mRules = ((Rule[])rulesList.toArray(new Rule[rulesList.size()]));@b@@b@ int len = 0;@b@ for (int i = this.mRules.length; --i >= 0; ) {@b@ len += this.mRules[i].estimateLength();@b@ }@b@@b@ this.mMaxLengthEstimate = len;@b@ }@b@@b@ public Object parseObject(String source, ParsePosition pos)@b@ {@b@ pos.setIndex(0);@b@ pos.setErrorIndex(0);@b@ return null;@b@ }@b@@b@ protected List parsePattern()@b@ {@b@ DateFormatSymbols symbols = new DateFormatSymbols(this.mLocale);@b@ List rules = new ArrayList();@b@@b@ String[] ERAs = symbols.getEras();@b@ String[] months = symbols.getMonths();@b@ String[] shortMonths = symbols.getShortMonths();@b@ String[] weekdays = symbols.getWeekdays();@b@ String[] shortWeekdays = symbols.getShortWeekdays();@b@ String[] AmPmStrings = symbols.getAmPmStrings();@b@@b@ int length = this.mPattern.length();@b@ int[] indexRef = new int[1];@b@@b@ for (int i = 0; i < length; ++i) {@b@ Rule rule;@b@ indexRef[0] = i;@b@ String token = parseToken(this.mPattern, indexRef);@b@ i = indexRef[0];@b@@b@ int tokenLen = token.length();@b@ if (tokenLen == 0)@b@ {@b@ break;@b@ }@b@@b@ char c = token.charAt(0);@b@@b@ switch (c)@b@ {@b@ case 'G':@b@ rule = new TextField(0, ERAs);@b@ break;@b@ case 'y':@b@ if (tokenLen >= 4)@b@ rule = selectNumberRule(1, tokenLen);@b@ else@b@ rule = TwoDigitYearField.INSTANCE;@b@@b@ break;@b@ case 'M':@b@ if (tokenLen >= 4)@b@ rule = new TextField(2, months);@b@ else if (tokenLen == 3)@b@ rule = new TextField(2, shortMonths);@b@ else if (tokenLen == 2)@b@ rule = TwoDigitMonthField.INSTANCE;@b@ else@b@ rule = UnpaddedMonthField.INSTANCE;@b@@b@ break;@b@ case 'd':@b@ rule = selectNumberRule(5, tokenLen);@b@ break;@b@ case 'h':@b@ rule = new TwelveHourField(selectNumberRule(10, tokenLen));@b@ break;@b@ case 'H':@b@ rule = selectNumberRule(11, tokenLen);@b@ break;@b@ case 'm':@b@ rule = selectNumberRule(12, tokenLen);@b@ break;@b@ case 's':@b@ rule = selectNumberRule(13, tokenLen);@b@ break;@b@ case 'S':@b@ rule = selectNumberRule(14, tokenLen);@b@ break;@b@ case 'E':@b@ rule = new TextField(7, weekdays);@b@ break;@b@ case 'D':@b@ rule = selectNumberRule(6, tokenLen);@b@ break;@b@ case 'F':@b@ rule = selectNumberRule(8, tokenLen);@b@ break;@b@ case 'w':@b@ rule = selectNumberRule(3, tokenLen);@b@ break;@b@ case 'W':@b@ rule = selectNumberRule(4, tokenLen);@b@ break;@b@ case 'a':@b@ rule = new TextField(9, AmPmStrings);@b@ break;@b@ case 'k':@b@ rule = new TwentyFourHourField(selectNumberRule(11, tokenLen));@b@ break;@b@ case 'K':@b@ rule = selectNumberRule(10, tokenLen);@b@ break;@b@ case 'z':@b@ if (tokenLen >= 4)@b@ rule = new TimeZoneNameRule(this.mTimeZone, this.mTimeZoneForced, this.mLocale, 1);@b@ else@b@ rule = new TimeZoneNameRule(this.mTimeZone, this.mTimeZoneForced, this.mLocale, 0);@b@@b@ break;@b@ case 'Z':@b@ if (tokenLen == 1)@b@ rule = TimeZoneNumberRule.INSTANCE_NO_COLON;@b@ else@b@ rule = TimeZoneNumberRule.INSTANCE_COLON;@b@@b@ break;@b@ case '\'':@b@ String sub = token.substring(1);@b@ if (sub.length() == 1)@b@ rule = new CharacterLiteral(sub.charAt(0));@b@ else@b@ rule = new StringLiteral(sub);@b@@b@ break;@b@ default:@b@ throw new IllegalArgumentException("Illegal pattern component: " + token);@b@ }@b@@b@ rules.add(rule);@b@ }@b@@b@ return rules;@b@ }@b@@b@ protected String parseToken(String pattern, int[] indexRef)@b@ {@b@ StringBuffer buf = new StringBuffer();@b@@b@ int i = indexRef[0];@b@ int length = pattern.length();@b@@b@ char c = pattern.charAt(i);@b@ if (((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z')))@b@ {@b@ buf.append(c);@b@@b@ while (i + 1 < length) {@b@ char peek = pattern.charAt(i + 1);@b@ if (peek != c) break label235;@b@ buf.append(c);@b@ ++i;@b@ }@b@@b@ }@b@ else@b@ {@b@ buf.append('\'');@b@@b@ boolean inLiteral = false;@b@@b@ for (; i < length; ++i) {@b@ c = pattern.charAt(i);@b@@b@ if (c == '\'') {@b@ if ((i + 1 < length) && (pattern.charAt(i + 1) == '\''))@b@ {@b@ ++i;@b@ buf.append(c);@b@ } else {@b@ inLiteral ^= true; }@b@ } else {@b@ if ((!(inLiteral)) && ((@b@ ((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))))) {@b@ --i;@b@ break;@b@ }@b@ buf.append(c);@b@ }@b@ }@b@ }@b@@b@ label235: indexRef[0] = i;@b@ return buf.toString();@b@ }@b@@b@ protected NumberRule selectNumberRule(int field, int padding)@b@ {@b@ switch (padding)@b@ {@b@ case 1:@b@ return new UnpaddedNumberField(field);@b@ case 2:@b@ return new TwoDigitNumberField(field);@b@ }@b@ return new PaddedNumberField(field, padding);@b@ }@b@@b@ public String toString()@b@ {@b@ return "FastDateFormat[" + this.mPattern + "]";@b@ }@b@@b@ private static abstract interface Rule@b@ {@b@ public abstract void appendTo(StringBuffer paramStringBuffer, Calendar paramCalendar);@b@@b@ public abstract int estimateLength();@b@ }@b@@b@ private static abstract interface NumberRule extends FastDateFormat.Rule@b@ {@b@ public abstract void appendTo(StringBuffer paramStringBuffer, int paramInt);@b@ }@b@@b@ private static class CharacterLiteral@b@ implements FastDateFormat.Rule@b@ {@b@ private final char mValue;@b@@b@ CharacterLiteral(char value)@b@ {@b@ this.mValue = value;@b@ }@b@@b@ public void appendTo(StringBuffer buffer, Calendar calendar)@b@ {@b@ buffer.append(this.mValue);@b@ }@b@@b@ public int estimateLength()@b@ {@b@ return 1;@b@ }@b@ }@b@@b@ private static class StringLiteral@b@ implements FastDateFormat.Rule@b@ {@b@ private final String mValue;@b@@b@ StringLiteral(String value)@b@ {@b@ this.mValue = value;@b@ }@b@@b@ public void appendTo(StringBuffer buffer, Calendar calendar)@b@ {@b@ buffer.append(this.mValue);@b@ }@b@@b@ public int estimateLength()@b@ {@b@ return this.mValue.length();@b@ }@b@ }@b@@b@ private static class TextField@b@ implements FastDateFormat.Rule@b@ {@b@ private final int mField;@b@ private final String[] mValues;@b@@b@ TextField(int field, String[] values)@b@ {@b@ this.mField = field;@b@ this.mValues = values;@b@ }@b@@b@ public void appendTo(StringBuffer buffer, Calendar calendar)@b@ {@b@ buffer.append(this.mValues[calendar.get(this.mField)]);@b@ }@b@@b@ public int estimateLength()@b@ {@b@ int max = 0;@b@ for (int i = this.mValues.length; --i >= 0; ) {@b@ int len = this.mValues[i].length();@b@ if (len <= max) break label28;@b@ label28: max = len;@b@ }@b@@b@ return max;@b@ }@b@ }@b@@b@ private static class UnpaddedNumberField@b@ implements FastDateFormat.NumberRule@b@ {@b@ static final UnpaddedNumberField INSTANCE_YEAR = new UnpaddedNumberField(1);@b@ private final int mField;@b@@b@ UnpaddedNumberField(int field)@b@ {@b@ this.mField = field;@b@ }@b@@b@ public final void appendTo(StringBuffer buffer, int value)@b@ {@b@ if (value < 10) {@b@ buffer.append((char)(value + 48));@b@ } else if (value < 100) {@b@ buffer.append((char)(value / 10 + 48));@b@ buffer.append((char)(value % 10 + 48));@b@ } else {@b@ buffer.append(Integer.toString(value));@b@ }@b@ }@b@@b@ public void appendTo(StringBuffer buffer, Calendar calendar)@b@ {@b@ appendTo(buffer, calendar.get(this.mField));@b@ }@b@@b@ public int estimateLength()@b@ {@b@ return 4;@b@ }@b@ }@b@@b@ private static class UnpaddedMonthField@b@ implements FastDateFormat.NumberRule@b@ {@b@ static final UnpaddedMonthField INSTANCE = new UnpaddedMonthField();@b@@b@ public final void appendTo(StringBuffer buffer, int value)@b@ {@b@ if (value < 10) {@b@ buffer.append((char)(value + 48));@b@ } else {@b@ buffer.append((char)(value / 10 + 48));@b@ buffer.append((char)(value % 10 + 48));@b@ }@b@ }@b@@b@ public void appendTo(StringBuffer buffer, Calendar calendar)@b@ {@b@ appendTo(buffer, calendar.get(2) + 1);@b@ }@b@@b@ public int estimateLength()@b@ {@b@ return 2;@b@ }@b@ }@b@@b@ private static class PaddedNumberField@b@ implements FastDateFormat.NumberRule@b@ {@b@ private final int mField;@b@ private final int mSize;@b@@b@ PaddedNumberField(int field, int size)@b@ {@b@ if (size < 3)@b@ {@b@ throw new IllegalArgumentException();@b@ }@b@ this.mField = field;@b@ this.mSize = size;@b@ }@b@@b@ public final void appendTo(StringBuffer buffer, int value)@b@ {@b@ if (value < 100) {@b@ for (int i = this.mSize; --i >= 2; )@b@ buffer.append('0');@b@@b@ buffer.append((char)(value / 10 + 48));@b@ buffer.append((char)(value % 10 + 48));@b@ }@b@ else {@b@ int digits;@b@ if (value < 1000)@b@ digits = 3;@b@ else@b@ digits = (int)(Math.log(value) / FastDateFormat.LOG_10) + 1;@b@@b@ for (int i = this.mSize; --i >= digits; )@b@ buffer.append('0');@b@@b@ buffer.append(Integer.toString(value));@b@ }@b@ }@b@@b@ public void appendTo(StringBuffer buffer, Calendar calendar)@b@ {@b@ appendTo(buffer, calendar.get(this.mField));@b@ }@b@@b@ public int estimateLength()@b@ {@b@ return 4;@b@ }@b@ }@b@@b@ private static class TwoDigitNumberField@b@ implements FastDateFormat.NumberRule@b@ {@b@ private final int mField;@b@@b@ TwoDigitNumberField(int field)@b@ {@b@ this.mField = field;@b@ }@b@@b@ public final void appendTo(StringBuffer buffer, int value)@b@ {@b@ if (value < 100) {@b@ buffer.append((char)(value / 10 + 48));@b@ buffer.append((char)(value % 10 + 48));@b@ } else {@b@ buffer.append(Integer.toString(value));@b@ }@b@ }@b@@b@ public void appendTo(StringBuffer buffer, Calendar calendar)@b@ {@b@ appendTo(buffer, calendar.get(this.mField));@b@ }@b@@b@ public int estimateLength()@b@ {@b@ return 2;@b@ }@b@ }@b@@b@ private static class TwoDigitYearField@b@ implements FastDateFormat.NumberRule@b@ {@b@ static final TwoDigitYearField INSTANCE = new TwoDigitYearField();@b@@b@ public final void appendTo(StringBuffer buffer, int value)@b@ {@b@ buffer.append((char)(value / 10 + 48));@b@ buffer.append((char)(value % 10 + 48));@b@ }@b@@b@ public void appendTo(StringBuffer buffer, Calendar calendar)@b@ {@b@ appendTo(buffer, calendar.get(1) % 100);@b@ }@b@@b@ public int estimateLength()@b@ {@b@ return 2;@b@ }@b@ }@b@@b@ private static class TwoDigitMonthField@b@ implements FastDateFormat.NumberRule@b@ {@b@ static final TwoDigitMonthField INSTANCE = new TwoDigitMonthField();@b@@b@ public final void appendTo(StringBuffer buffer, int value)@b@ {@b@ buffer.append((char)(value / 10 + 48));@b@ buffer.append((char)(value % 10 + 48));@b@ }@b@@b@ public void appendTo(StringBuffer buffer, Calendar calendar)@b@ {@b@ appendTo(buffer, calendar.get(2) + 1);@b@ }@b@@b@ public int estimateLength()@b@ {@b@ return 2;@b@ }@b@ }@b@@b@ private static class TwelveHourField@b@ implements FastDateFormat.NumberRule@b@ {@b@ private final FastDateFormat.NumberRule mRule;@b@@b@ TwelveHourField(FastDateFormat.NumberRule rule)@b@ {@b@ this.mRule = rule;@b@ }@b@@b@ public void appendTo(StringBuffer buffer, int value)@b@ {@b@ this.mRule.appendTo(buffer, value);@b@ }@b@@b@ public void appendTo(StringBuffer buffer, Calendar calendar)@b@ {@b@ int value = calendar.get(10);@b@ if (value == 0)@b@ value = calendar.getLeastMaximum(10) + 1;@b@@b@ this.mRule.appendTo(buffer, value);@b@ }@b@@b@ public int estimateLength()@b@ {@b@ return this.mRule.estimateLength();@b@ }@b@ }@b@@b@ private static class TwentyFourHourField@b@ implements FastDateFormat.NumberRule@b@ {@b@ private final FastDateFormat.NumberRule mRule;@b@@b@ TwentyFourHourField(FastDateFormat.NumberRule rule)@b@ {@b@ this.mRule = rule;@b@ }@b@@b@ public void appendTo(StringBuffer buffer, int value)@b@ {@b@ this.mRule.appendTo(buffer, value);@b@ }@b@@b@ public void appendTo(StringBuffer buffer, Calendar calendar)@b@ {@b@ int value = calendar.get(11);@b@ if (value == 0)@b@ value = calendar.getMaximum(11) + 1;@b@@b@ this.mRule.appendTo(buffer, value);@b@ }@b@@b@ public int estimateLength()@b@ {@b@ return this.mRule.estimateLength();@b@ }@b@ }@b@@b@ private static class TimeZoneNameRule@b@ implements FastDateFormat.Rule@b@ {@b@ private final TimeZone mTimeZone;@b@ private final boolean mTimeZoneForced;@b@ private final Locale mLocale;@b@ private final int mStyle;@b@ private final String mStandard;@b@ private final String mDaylight;@b@@b@ TimeZoneNameRule(TimeZone timeZone, boolean timeZoneForced, Locale locale, int style)@b@ {@b@ this.mTimeZone = timeZone;@b@ this.mTimeZoneForced = timeZoneForced;@b@ this.mLocale = locale;@b@ this.mStyle = style;@b@@b@ if (timeZoneForced) {@b@ this.mStandard = FastDateFormat.getTimeZoneDisplay(timeZone, false, style, locale);@b@ this.mDaylight = FastDateFormat.getTimeZoneDisplay(timeZone, true, style, locale);@b@ } else {@b@ this.mStandard = null;@b@ this.mDaylight = null;@b@ }@b@ }@b@@b@ public void appendTo(StringBuffer buffer, Calendar calendar)@b@ {@b@ if (this.mTimeZoneForced) {@b@ if ((this.mTimeZone.useDaylightTime()) && (calendar.get(16) != 0))@b@ buffer.append(this.mDaylight);@b@ else@b@ buffer.append(this.mStandard);@b@ }@b@ else {@b@ TimeZone timeZone = calendar.getTimeZone();@b@ if ((timeZone.useDaylightTime()) && (calendar.get(16) != 0))@b@ buffer.append(FastDateFormat.getTimeZoneDisplay(timeZone, true, this.mStyle, this.mLocale));@b@ else@b@ buffer.append(FastDateFormat.getTimeZoneDisplay(timeZone, false, this.mStyle, this.mLocale));@b@ }@b@ }@b@@b@ public int estimateLength()@b@ {@b@ if (this.mTimeZoneForced)@b@ return Math.max(this.mStandard.length(), this.mDaylight.length());@b@ if (this.mStyle == 0)@b@ return 4;@b@@b@ return 40;@b@ }@b@ }@b@@b@ private static class TimeZoneNumberRule@b@ implements FastDateFormat.Rule@b@ {@b@ static final TimeZoneNumberRule INSTANCE_COLON = new TimeZoneNumberRule(true);@b@ static final TimeZoneNumberRule INSTANCE_NO_COLON = new TimeZoneNumberRule(false);@b@ final boolean mColon;@b@@b@ TimeZoneNumberRule(boolean colon)@b@ {@b@ this.mColon = colon;@b@ }@b@@b@ public void appendTo(StringBuffer buffer, Calendar calendar)@b@ {@b@ int offset = calendar.get(15) + calendar.get(16);@b@@b@ if (offset < 0) {@b@ buffer.append('-');@b@ offset = -offset;@b@ } else {@b@ buffer.append('+');@b@ }@b@@b@ int hours = offset / 3600000;@b@ buffer.append((char)(hours / 10 + 48));@b@ buffer.append((char)(hours % 10 + 48));@b@@b@ if (this.mColon) {@b@ buffer.append(':');@b@ }@b@@b@ int minutes = offset / 60000 - 60 * hours;@b@ buffer.append((char)(minutes / 10 + 48));@b@ buffer.append((char)(minutes % 10 + 48));@b@ }@b@@b@ public int estimateLength()@b@ {@b@ return 5;@b@ }@b@ }@b@@b@ private static class TimeZoneDisplayKey@b@ {@b@ private final TimeZone mTimeZone;@b@ private final int mStyle;@b@ private final Locale mLocale;@b@@b@ TimeZoneDisplayKey(TimeZone timeZone, boolean daylight, int style, Locale locale)@b@ {@b@ this.mTimeZone = timeZone;@b@ if (daylight)@b@ style |= -2147483648;@b@@b@ this.mStyle = style;@b@ this.mLocale = locale;@b@ }@b@@b@ public boolean equals(Object obj)@b@ {@b@ if (this == obj)@b@ return true;@b@@b@ if (obj instanceof TimeZoneDisplayKey) {@b@ TimeZoneDisplayKey other = (TimeZoneDisplayKey)obj;@b@ return @b@ ((this.mTimeZone.equals(other.mTimeZone)) && @b@ (this.mStyle == other.mStyle) && @b@ (this.mLocale.equals(other.mLocale)));@b@ }@b@ return false;@b@ }@b@@b@ public int hashCode()@b@ {@b@ return (this.mStyle * 31 + this.mLocale.hashCode());@b@ }@b@ }@b@@b@ private static class Pair@b@ {@b@ private final Object mObj1;@b@ private final Object mObj2;@b@@b@ public Pair(Object obj1, Object obj2)@b@ {@b@ this.mObj1 = obj1;@b@ this.mObj2 = obj2;@b@ }@b@@b@ public boolean equals(Object obj) {@b@ if (this == obj) {@b@ return true;@b@ }@b@@b@ if (!(obj instanceof Pair)) {@b@ return false;@b@ }@b@@b@ Pair key = (Pair)obj;@b@@b@ if (this.mObj1 == null);@b@ if (@b@ ((key.mObj1 != null) ? false : this.mObj1.equals(key.mObj1)))@b@ if (this.mObj2 == null);@b@ return @b@ (@b@ ((key.mObj2 != null) ? false : this.mObj2.equals(key.mObj2)));@b@ }@b@@b@ public int hashCode() {@b@ return @b@ (((this.mObj1 == null) ? 0 : this.mObj1.hashCode()) + @b@ ((this.mObj2 == null) ? 0 : this.mObj2.hashCode()));@b@ }@b@@b@ public String toString() {@b@ return "[" + this.mObj1 + ':' + this.mObj2 + ']';@b@ }@b@ }@b@}