package com.xiaoleilu.hutool.date.format; import java.text.DateFormat; import java.text.FieldPosition; import java.text.Format; import java.text.ParseException; import java.text.ParsePosition; import java.util.Calendar; import java.util.Date; import java.util.Locale; import java.util.TimeZone; /** * <p> * FastDateFormat 是一个线程安全的 {@link java.text.SimpleDateFormat} 实现。 * </p> * * <p> * 通过以下静态方法获得此对象: <br> * {@link #getInstance(String, TimeZone, Locale)}<br> * {@link #getDateInstance(int, TimeZone, Locale)}<br> * {@link #getTimeInstance(int, TimeZone, Locale)}<br> * {@link #getDateTimeInstance(int, int, TimeZone, Locale)} * </p> * * Thanks to Apache Commons Lang 3.5 * @since 2.16.2 */ public class FastDateFormat extends Format implements DateParser, DatePrinter { private static final long serialVersionUID = 8097890768636183236L; /** FULL locale dependent date or time style. */ public static final int FULL = DateFormat.FULL; /** LONG locale dependent date or time style. */ public static final int LONG = DateFormat.LONG; /** MEDIUM locale dependent date or time style. */ public static final int MEDIUM = DateFormat.MEDIUM; /** SHORT locale dependent date or time style. */ public static final int SHORT = DateFormat.SHORT; private static final FormatCache<FastDateFormat> cache = new FormatCache<FastDateFormat>(){ @Override protected FastDateFormat createInstance(final String pattern, final TimeZone timeZone, final Locale locale) { return new FastDateFormat(pattern, timeZone, locale); } }; private final FastDatePrinter printer; private final FastDateParser parser; // ----------------------------------------------------------------------- /** * 获得 {@link FastDateFormat} 实例,使用默认格式和地区 * * @return {@link FastDateFormat} */ public static FastDateFormat getInstance() { return cache.getInstance(); } /** * 获得 {@link FastDateFormat} 实例,使用默认地区 * * @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式 * @return {@link FastDateFormat} * @throws IllegalArgumentException 日期格式问题 */ public static FastDateFormat getInstance(final String pattern) { return cache.getInstance(pattern, null, null); } /** * 获得 {@link FastDateFormat} 实例 * * @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式 * @param timeZone 时区{@link TimeZone} * @return {@link FastDateFormat} * @throws IllegalArgumentException 日期格式问题 */ public static FastDateFormat getInstance(final String pattern, final TimeZone timeZone) { return cache.getInstance(pattern, timeZone, null); } /** * 获得 {@link FastDateFormat} 实例 * * @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式 * @param locale {@link Locale} 日期地理位置 * @return {@link FastDateFormat} * @throws IllegalArgumentException 日期格式问题 */ public static FastDateFormat getInstance(final String pattern, final Locale locale) { return cache.getInstance(pattern, null, locale); } /** * 获得 {@link FastDateFormat} 实例 * * @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式 * @param timeZone 时区{@link TimeZone} * @param locale {@link Locale} 日期地理位置 * @return {@link FastDateFormat} * @throws IllegalArgumentException 日期格式问题 */ public static FastDateFormat getInstance(final String pattern, final TimeZone timeZone, final Locale locale) { return cache.getInstance(pattern, timeZone, locale); } // ----------------------------------------------------------------------- /** * 获得 {@link FastDateFormat} 实例 * * @param style date style: FULL, LONG, MEDIUM, or SHORT * @return 本地化 {@link FastDateFormat} * @throws IllegalArgumentException */ public static FastDateFormat getDateInstance(final int style) { return cache.getDateInstance(style, null, null); } /** * 获得 {@link FastDateFormat} 实例 * * @param style date style: FULL, LONG, MEDIUM, or SHORT * @param locale {@link Locale} 日期地理位置 * @return 本地化 {@link FastDateFormat} * @throws IllegalArgumentException */ public static FastDateFormat getDateInstance(final int style, final Locale locale) { return cache.getDateInstance(style, null, locale); } /** * 获得 {@link FastDateFormat} 实例 * * @param style date style: FULL, LONG, MEDIUM, or SHORT * @param timeZone 时区{@link TimeZone} * @return 本地化 {@link FastDateFormat} * @throws IllegalArgumentException */ public static FastDateFormat getDateInstance(final int style, final TimeZone timeZone) { return cache.getDateInstance(style, timeZone, null); } /** * 获得 {@link FastDateFormat} 实例 * * @param style date style: FULL, LONG, MEDIUM, or SHORT * @param timeZone 时区{@link TimeZone} * @param locale {@link Locale} 日期地理位置 * @return 本地化 {@link FastDateFormat} * @throws IllegalArgumentException */ public static FastDateFormat getDateInstance(final int style, final TimeZone timeZone, final Locale locale) { return cache.getDateInstance(style, timeZone, locale); } // ----------------------------------------------------------------------- /** * 获得 {@link FastDateFormat} 实例 * * @param style time style: FULL, LONG, MEDIUM, or SHORT * @return 本地化 {@link FastDateFormat} * @throws IllegalArgumentException */ public static FastDateFormat getTimeInstance(final int style) { return cache.getTimeInstance(style, null, null); } /** * 获得 {@link FastDateFormat} 实例 * * @param style time style: FULL, LONG, MEDIUM, or SHORT * @param locale {@link Locale} 日期地理位置 * @return 本地化 {@link FastDateFormat} * @throws IllegalArgumentException */ public static FastDateFormat getTimeInstance(final int style, final Locale locale) { return cache.getTimeInstance(style, null, locale); } /** * 获得 {@link FastDateFormat} 实例 * * @param style time style: FULL, LONG, MEDIUM, or SHORT * @param timeZone optional time zone, overrides time zone of formatted time * @return 本地化 {@link FastDateFormat} * @throws IllegalArgumentException */ public static FastDateFormat getTimeInstance(final int style, final TimeZone timeZone) { return cache.getTimeInstance(style, timeZone, null); } /** * 获得 {@link FastDateFormat} 实例 * * @param style time style: FULL, LONG, MEDIUM, or SHORT * @param timeZone optional time zone, overrides time zone of formatted time * @param locale {@link Locale} 日期地理位置 * @return 本地化 {@link FastDateFormat} * @throws IllegalArgumentException */ public static FastDateFormat getTimeInstance(final int style, final TimeZone timeZone, final Locale locale) { return cache.getTimeInstance(style, timeZone, locale); } // ----------------------------------------------------------------------- /** * 获得 {@link FastDateFormat} 实例 * * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT * @return 本地化 {@link FastDateFormat} * @throws IllegalArgumentException * @since 2.1 */ public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle) { return cache.getDateTimeInstance(dateStyle, timeStyle, null, null); } /** * 获得 {@link FastDateFormat} 实例 * * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT * @param locale {@link Locale} 日期地理位置 * @return 本地化 {@link FastDateFormat} * @throws IllegalArgumentException * @since 2.1 */ public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle, final Locale locale) { return cache.getDateTimeInstance(dateStyle, timeStyle, null, locale); } /** * 获得 {@link FastDateFormat} 实例 * * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT * @param timeZone 时区{@link TimeZone} * @return 本地化 {@link FastDateFormat} * @throws IllegalArgumentException * @since 2.1 */ public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle, final TimeZone timeZone) { return getDateTimeInstance(dateStyle, timeStyle, timeZone, null); } /** * 获得 {@link FastDateFormat} 实例 * * @param dateStyle date style: FULL, LONG, MEDIUM, or SHORT * @param timeStyle time style: FULL, LONG, MEDIUM, or SHORT * @param timeZone 时区{@link TimeZone} * @param locale {@link Locale} 日期地理位置 * @return 本地化 {@link FastDateFormat} * @throws IllegalArgumentException */ public static FastDateFormat getDateTimeInstance(final int dateStyle, final int timeStyle, final TimeZone timeZone, final Locale locale) { return cache.getDateTimeInstance(dateStyle, timeStyle, timeZone, locale); } // ----------------------------------------------------------------------- Constructor start /** * 构造 * * @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式 * @param timeZone 非空时区 {@link TimeZone} * @param locale {@link Locale} 日期地理位置 * @throws NullPointerException if pattern, timeZone, or locale is null. */ protected FastDateFormat(final String pattern, final TimeZone timeZone, final Locale locale) { this(pattern, timeZone, locale, null); } /** * 构造 * * @param pattern 使用{@link java.text.SimpleDateFormat} 相同的日期格式 * @param timeZone 非空时区 {@link TimeZone} * @param locale {@link Locale} 日期地理位置 * @param centuryStart The start of the 100 year period to use as the "default century" for 2 digit year parsing. If centuryStart is null, defaults to now - 80 years * @throws NullPointerException if pattern, timeZone, or locale is null. */ protected FastDateFormat(final String pattern, final TimeZone timeZone, final Locale locale, final Date centuryStart) { printer = new FastDatePrinter(pattern, timeZone, locale); parser = new FastDateParser(pattern, timeZone, locale, centuryStart); } // ----------------------------------------------------------------------- Constructor end // ----------------------------------------------------------------------- Format methods @Override public StringBuffer format(final Object obj, final StringBuffer toAppendTo, final FieldPosition pos) { return toAppendTo.append(printer.format(obj)); } @Override public String format(final long millis) { return printer.format(millis); } @Override public String format(final Date date) { return printer.format(date); } @Override public String format(final Calendar calendar) { return printer.format(calendar); } @Override public <B extends Appendable> B format(final long millis, final B buf) { return printer.format(millis, buf); } @Override public <B extends Appendable> B format(final Date date, final B buf) { return printer.format(date, buf); } @Override public <B extends Appendable> B format(final Calendar calendar, final B buf) { return printer.format(calendar, buf); } // ----------------------------------------------------------------------- Parsing @Override public Date parse(final String source) throws ParseException { return parser.parse(source); } @Override public Date parse(final String source, final ParsePosition pos) { return parser.parse(source, pos); } @Override public boolean parse(final String source, final ParsePosition pos, final Calendar calendar) { return parser.parse(source, pos, calendar); } @Override public Object parseObject(final String source, final ParsePosition pos) { return parser.parseObject(source, pos); } // ----------------------------------------------------------------------- Accessors @Override public String getPattern() { return printer.getPattern(); } @Override public TimeZone getTimeZone() { return printer.getTimeZone(); } @Override public Locale getLocale() { return printer.getLocale(); } /** *估算生成的日期字符串长度<br> * 实际生成的字符串长度小于或等于此值 * * @return 日期字符串长度 */ public int getMaxLengthEstimate() { return printer.getMaxLengthEstimate(); } // Basics // ----------------------------------------------------------------------- @Override public boolean equals(final Object obj) { if (obj instanceof FastDateFormat == false) { return false; } final FastDateFormat other = (FastDateFormat) obj; // no need to check parser, as it has same invariants as printer return printer.equals(other.printer); } @Override public int hashCode() { return printer.hashCode(); } @Override public String toString() { return "FastDateFormat[" + printer.getPattern() + "," + printer.getLocale() + "," + printer.getTimeZone().getID() + "]"; } }