📄 simpledateformat.java
字号:
this(pattern, Locale.getDefault()); } /** * Creates a date formatter using the specified non-localized pattern, * with the default DateFormatSymbols for the given locale. * * @param pattern the non-localized pattern to use. * @param locale the locale to use for the formatting symbols. * @throws NullPointerException if the pattern is null. * @throws IllegalArgumentException if the pattern is invalid. */ public SimpleDateFormat(String pattern, Locale locale) { super(); calendar = new GregorianCalendar(locale); computeCenturyStart(); tokens = new ArrayList(); formatData = new DateFormatSymbols(locale); compileFormat(pattern); this.pattern = pattern; numberFormat = NumberFormat.getInstance(locale); numberFormat.setGroupingUsed (false); numberFormat.setParseIntegerOnly (true); numberFormat.setMaximumFractionDigits (0); } /** * Creates a date formatter using the specified non-localized * pattern. The specified DateFormatSymbols will be used when * formatting. * * @param pattern the non-localized pattern to use. * @param formatData the formatting symbols to use. * @throws NullPointerException if the pattern or formatData is null. * @throws IllegalArgumentException if the pattern is invalid. */ public SimpleDateFormat(String pattern, DateFormatSymbols formatData) { super(); calendar = new GregorianCalendar(); computeCenturyStart (); tokens = new ArrayList(); if (formatData == null) throw new NullPointerException("formatData"); this.formatData = formatData; compileFormat(pattern); this.pattern = pattern; numberFormat = NumberFormat.getInstance(); numberFormat.setGroupingUsed (false); numberFormat.setParseIntegerOnly (true); numberFormat.setMaximumFractionDigits (0); } /** * This method returns a string with the formatting pattern being used * by this object. This string is unlocalized. * * @return The format string. */ public String toPattern() { return pattern; } /** * This method returns a string with the formatting pattern being used * by this object. This string is localized. * * @return The format string. */ public String toLocalizedPattern() { String localChars = formatData.getLocalPatternChars(); return translateLocalizedPattern(pattern, standardChars, localChars); } /** * This method sets the formatting pattern that should be used by this * object. This string is not localized. * * @param pattern The new format pattern. * @throws NullPointerException if the pattern is null. * @throws IllegalArgumentException if the pattern is invalid. */ public void applyPattern(String pattern) { tokens = new ArrayList(); compileFormat(pattern); this.pattern = pattern; } /** * This method sets the formatting pattern that should be used by this * object. This string is localized. * * @param pattern The new format pattern. * @throws NullPointerException if the pattern is null. * @throws IllegalArgumentException if the pattern is invalid. */ public void applyLocalizedPattern(String pattern) { String localChars = formatData.getLocalPatternChars(); pattern = translateLocalizedPattern(pattern, localChars, standardChars); applyPattern(pattern); } /** * Translates either from or to a localized variant of the pattern * string. For example, in the German locale, 't' (for 'tag') is * used instead of 'd' (for 'date'). This method translates * a localized pattern (such as 'ttt') to a non-localized pattern * (such as 'ddd'), or vice versa. Non-localized patterns use * a standard set of characters, which match those of the U.S. English * locale. * * @param pattern the pattern to translate. * @param oldChars the old set of characters (used in the pattern). * @param newChars the new set of characters (which will be used in the * pattern). * @return a version of the pattern using the characters in * <code>newChars</code>. */ private String translateLocalizedPattern(String pattern, String oldChars, String newChars) { int len = pattern.length(); StringBuffer buf = new StringBuffer(len); boolean quoted = false; for (int i = 0; i < len; i++) { char ch = pattern.charAt(i); if (ch == '\'') quoted = ! quoted; if (! quoted) { int j = oldChars.indexOf(ch); if (j >= 0) ch = newChars.charAt(j); } buf.append(ch); } return buf.toString(); } /** * Returns the start of the century used for two digit years. * * @return A <code>Date</code> representing the start of the century * for two digit years. */ public Date get2DigitYearStart() { return defaultCenturyStart; } /** * Sets the start of the century used for two digit years. * * @param date A <code>Date</code> representing the start of the century for * two digit years. */ public void set2DigitYearStart(Date date) { defaultCenturyStart = date; calendar.clear(); calendar.setTime(date); int year = calendar.get(Calendar.YEAR); defaultCentury = year - (year % 100); } /** * This method returns a copy of the format symbol information used * for parsing and formatting dates. * * @return a copy of the date format symbols. */ public DateFormatSymbols getDateFormatSymbols() { return (DateFormatSymbols) formatData.clone(); } /** * This method sets the format symbols information used for parsing * and formatting dates. * * @param formatData The date format symbols. * @throws NullPointerException if <code>formatData</code> is null. */ public void setDateFormatSymbols(DateFormatSymbols formatData) { if (formatData == null) { throw new NullPointerException("The supplied format data was null."); } this.formatData = formatData; } /** * This methods tests whether the specified object is equal to this * object. This will be true if and only if the specified object: * <p> * <ul> * <li>Is not <code>null</code>.</li> * <li>Is an instance of <code>SimpleDateFormat</code>.</li> * <li>Is equal to this object at the superclass (i.e., <code>DateFormat</code>) * level.</li> * <li>Has the same formatting pattern.</li> * <li>Is using the same formatting symbols.</li> * <li>Is using the same century for two digit years.</li> * </ul> * * @param o The object to compare for equality against. * * @return <code>true</code> if the specified object is equal to this object, * <code>false</code> otherwise. */ public boolean equals(Object o) { if (!super.equals(o)) return false; if (!(o instanceof SimpleDateFormat)) return false; SimpleDateFormat sdf = (SimpleDateFormat)o; if (defaultCentury != sdf.defaultCentury) return false; if (!toPattern().equals(sdf.toPattern())) return false; if (!getDateFormatSymbols().equals(sdf.getDateFormatSymbols())) return false; return true; } /** * This method returns a hash value for this object. * * @return A hash value for this object. */ public int hashCode() { return super.hashCode() ^ toPattern().hashCode() ^ defaultCentury ^ getDateFormatSymbols().hashCode(); } /** * Formats the date input according to the format string in use, * appending to the specified StringBuffer. The input StringBuffer * is returned as output for convenience. */ private void formatWithAttribute(Date date, FormatBuffer buffer, FieldPosition pos) { String temp; AttributedCharacterIterator.Attribute attribute; calendar.setTime(date); // go through vector, filling in fields where applicable, else toString Iterator iter = tokens.iterator(); while (iter.hasNext()) { Object o = iter.next(); if (o instanceof CompiledField) { CompiledField cf = (CompiledField) o; int beginIndex = buffer.length(); switch (cf.getField()) { case ERA_FIELD: buffer.append (formatData.eras[calendar.get (Calendar.ERA)], DateFormat.Field.ERA); break; case YEAR_FIELD: // If we have two digits, then we truncate. Otherwise, we // use the size of the pattern, and zero pad. buffer.setDefaultAttribute (DateFormat.Field.YEAR); if (cf.getSize() == 2) { temp = "00"+String.valueOf (calendar.get (Calendar.YEAR)); buffer.append (temp.substring (temp.length() - 2)); } else withLeadingZeros (calendar.get (Calendar.YEAR), cf.getSize(), buffer); break; case MONTH_FIELD: buffer.setDefaultAttribute (DateFormat.Field.MONTH); if (cf.getSize() < 3) withLeadingZeros (calendar.get (Calendar.MONTH) + 1, cf.getSize(), buffer); else if (cf.getSize() < 4) buffer.append (formatData.shortMonths[calendar.get (Calendar.MONTH)]); else buffer.append (formatData.months[calendar.get (Calendar.MONTH)]); break; case DATE_FIELD: buffer.setDefaultAttribute (DateFormat.Field.DAY_OF_MONTH); withLeadingZeros (calendar.get (Calendar.DATE), cf.getSize(), buffer); break; case HOUR_OF_DAY1_FIELD: // 1-24 buffer.setDefaultAttribute(DateFormat.Field.HOUR_OF_DAY1); withLeadingZeros ( ((calendar.get (Calendar.HOUR_OF_DAY) + 23) % 24) + 1, cf.getSize(), buffer); break; case HOUR_OF_DAY0_FIELD: // 0-23 buffer.setDefaultAttribute (DateFormat.Field.HOUR_OF_DAY0); withLeadingZeros (calendar.get (Calendar.HOUR_OF_DAY), cf.getSize(), buffer); break; case MINUTE_FIELD: buffer.setDefaultAttribute (DateFormat.Field.MINUTE); withLeadingZeros (calendar.get (Calendar.MINUTE), cf.getSize(), buffer); break; case SECOND_FIELD: buffer.setDefaultAttribute (DateFormat.Field.SECOND); withLeadingZeros(calendar.get (Calendar.SECOND), cf.getSize(), buffer); break; case MILLISECOND_FIELD: buffer.setDefaultAttribute (DateFormat.Field.MILLISECOND); withLeadingZeros (calendar.get (Calendar.MILLISECOND), cf.getSize(), buffer); break; case DAY_OF_WEEK_FIELD: buffer.setDefaultAttribute (DateFormat.Field.DAY_OF_WEEK); if (cf.getSize() < 4) buffer.append (formatData.shortWeekdays[calendar.get (Calendar.DAY_OF_WEEK)]); else buffer.append (formatData.weekdays[calendar.get (Calendar.DAY_OF_WEEK)]); break; case DAY_OF_YEAR_FIELD: buffer.setDefaultAttribute (DateFormat.Field.DAY_OF_YEAR); withLeadingZeros (calendar.get (Calendar.DAY_OF_YEAR), cf.getSize(), buffer); break; case DAY_OF_WEEK_IN_MONTH_FIELD: buffer.setDefaultAttribute (DateFormat.Field.DAY_OF_WEEK_IN_MONTH); withLeadingZeros (calendar.get (Calendar.DAY_OF_WEEK_IN_MONTH), cf.getSize(), buffer); break; case WEEK_OF_YEAR_FIELD: buffer.setDefaultAttribute (DateFormat.Field.WEEK_OF_YEAR); withLeadingZeros (calendar.get (Calendar.WEEK_OF_YEAR), cf.getSize(), buffer); break; case WEEK_OF_MONTH_FIELD: buffer.setDefaultAttribute (DateFormat.Field.WEEK_OF_MONTH); withLeadingZeros (calendar.get (Calendar.WEEK_OF_MONTH), cf.getSize(), buffer); break; case AM_PM_FIELD: buffer.setDefaultAttribute (DateFormat.Field.AM_PM); buffer.append (formatData.ampms[calendar.get (Calendar.AM_PM)]); break; case HOUR1_FIELD: // 1-12 buffer.setDefaultAttribute (DateFormat.Field.HOUR1); withLeadingZeros (((calendar.get (Calendar.HOUR) + 11) % 12) + 1, cf.getSize(), buffer); break; case HOUR0_FIELD: // 0-11 buffer.setDefaultAttribute (DateFormat.Field.HOUR0); withLeadingZeros (calendar.get (Calendar.HOUR), cf.getSize(), buffer); break; case TIMEZONE_FIELD: buffer.setDefaultAttribute (DateFormat.Field.TIME_ZONE); TimeZone zone = calendar.getTimeZone(); boolean isDST = calendar.get (Calendar.DST_OFFSET) != 0; // FIXME: XXX: This should be a localized time zone. String zoneID = zone.getDisplayName (isDST, cf.getSize() > 3 ? TimeZone.LONG : TimeZone.SHORT); buffer.append (zoneID); break; case RFC822_TIMEZONE_FIELD: buffer.setDefaultAttribute(DateFormat.Field.RFC822_TIME_ZONE); int pureMinutes = (calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)) / (1000 * 60); String sign = (pureMinutes < 0) ? "-" : "+"; int hours = pureMinutes / 60; int minutes = pureMinutes % 60; buffer.append(sign); withLeadingZeros(hours, 2, buffer); withLeadingZeros(minutes, 2, buffer); break; default: throw new IllegalArgumentException ("Illegal pattern character " + cf.getCharacter()); } if (pos != null && (buffer.getDefaultAttribute() == pos.getFieldAttribute() || cf.getField() == pos.getField())) { pos.setBeginIndex(beginIndex); pos.setEndIndex(buffer.length()); } } else { buffer.append(o.toString(), null); } } } public StringBuffer format(Date date, StringBuffer buffer, FieldPosition pos) { formatWithAttribute(date, new StringFormatBuffer (buffer), pos); return buffer; } public AttributedCharacterIterator formatToCharacterIterator(Object date) throws IllegalArgumentException { if (date == null) throw new NullPointerException("null argument"); if (!(date instanceof Date)) throw new IllegalArgumentException("argument should be an instance of java.util.Date"); AttributedFormatBuffer buf = new AttributedFormatBuffer(); formatWithAttribute((Date)date, buf, null); buf.sync(); return new FormatCharacterIterator(buf.getBuffer().toString(), buf.getRanges(), buf.getAttributes()); } private void withLeadingZeros(int value, int length, FormatBuffer buffer)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -