📄 simpledateformat.java
字号:
return false; return true; } /** * 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. */ public StringBuffer format(Date date, StringBuffer buffer, FieldPosition pos) { String temp; calendar.setTime(date); // go through vector, filling in fields where applicable, else toString Enumeration e = tokens.elements(); while (e.hasMoreElements()) { Object o = e.nextElement(); if (o instanceof FieldSizePair) { FieldSizePair p = (FieldSizePair) o; int beginIndex = buffer.length(); switch (p.field) { case ERA_FIELD: buffer.append(formatData.eras[calendar.get(Calendar.ERA)]); break; case YEAR_FIELD: temp = String.valueOf(calendar.get(Calendar.YEAR)); if (p.size < 4) buffer.append(temp.substring(temp.length()-2)); else buffer.append(temp); break; case MONTH_FIELD: if (p.size < 3) withLeadingZeros(calendar.get(Calendar.MONTH)+1,p.size,buffer); else if (p.size < 4) buffer.append(formatData.shortMonths[calendar.get(Calendar.MONTH)]); else buffer.append(formatData.months[calendar.get(Calendar.MONTH)]); break; case DATE_FIELD: withLeadingZeros(calendar.get(Calendar.DATE),p.size,buffer); break; case HOUR_OF_DAY1_FIELD: // 1-24 withLeadingZeros(((calendar.get(Calendar.HOUR_OF_DAY)+23)%24)+1,p.size,buffer); break; case HOUR_OF_DAY0_FIELD: // 0-23 withLeadingZeros(calendar.get(Calendar.HOUR_OF_DAY),p.size,buffer); break; case MINUTE_FIELD: withLeadingZeros(calendar.get(Calendar.MINUTE),p.size,buffer); break; case SECOND_FIELD: withLeadingZeros(calendar.get(Calendar.SECOND),p.size,buffer); break; case MILLISECOND_FIELD: withLeadingZeros(calendar.get(Calendar.MILLISECOND),p.size,buffer); break; case DAY_OF_WEEK_FIELD: if (p.size < 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: withLeadingZeros(calendar.get(Calendar.DAY_OF_YEAR),p.size,buffer); break; case DAY_OF_WEEK_IN_MONTH_FIELD: withLeadingZeros(calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH),p.size,buffer); break; case WEEK_OF_YEAR_FIELD: withLeadingZeros(calendar.get(Calendar.WEEK_OF_YEAR),p.size,buffer); break; case WEEK_OF_MONTH_FIELD: withLeadingZeros(calendar.get(Calendar.WEEK_OF_MONTH),p.size,buffer); break; case AM_PM_FIELD: buffer.append(formatData.ampms[calendar.get(Calendar.AM_PM)]); break; case HOUR1_FIELD: // 1-12 withLeadingZeros(((calendar.get(Calendar.HOUR)+11)%12)+1,p.size,buffer); break; case HOUR0_FIELD: // 0-11 withLeadingZeros(calendar.get(Calendar.HOUR),p.size,buffer); break; case TIMEZONE_FIELD: 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, p.size > 3 ? TimeZone.LONG : TimeZone.SHORT); buffer.append(zoneID); break; default: throw new IllegalArgumentException("Illegal pattern character"); } if (pos != null && p.field == pos.getField()) { pos.setBeginIndex(beginIndex); pos.setEndIndex(buffer.length()); } } else { buffer.append(o.toString()); } } return buffer; } private void withLeadingZeros(int value, int length, StringBuffer buffer) { String valStr = String.valueOf(value); for (length -= valStr.length(); length > 0; length--) buffer.append('0'); buffer.append(valStr); } private final boolean expect (String source, ParsePosition pos, char ch) { int x = pos.getIndex(); boolean r = x < source.length() && source.charAt(x) == ch; if (r) pos.setIndex(x + 1); else pos.setErrorIndex(x); return r; } /** * This method parses the specified string into a date. * * @param dateStr The date string to parse. * @param pos The input and output parse position * * @return The parsed date, or <code>null</code> if the string cannot be * parsed. */ public Date parse (String dateStr, ParsePosition pos) { int fmt_index = 0; int fmt_max = pattern.length(); calendar.clear(); boolean saw_timezone = false; int quote_start = -1; boolean is2DigitYear = false; for (; fmt_index < fmt_max; ++fmt_index) { char ch = pattern.charAt(fmt_index); if (ch == '\'') { int index = pos.getIndex(); if (fmt_index < fmt_max - 1 && pattern.charAt(fmt_index + 1) == '\'') { if (! expect (dateStr, pos, ch)) return null; ++fmt_index; } else quote_start = quote_start < 0 ? fmt_index : -1; continue; } if (quote_start != -1 || ((ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z'))) { if (! expect (dateStr, pos, ch)) return null; continue; } // We've arrived at a potential pattern character in the // pattern. int first = fmt_index; while (++fmt_index < fmt_max && pattern.charAt(fmt_index) == ch) ; int fmt_count = fmt_index - first; --fmt_index; // We can handle most fields automatically: most either are // numeric or are looked up in a string vector. In some cases // we need an offset. When numeric, `offset' is added to the // resulting value. When doing a string lookup, offset is the // initial index into the string array. int calendar_field; boolean is_numeric = true; String[] match = null; int offset = 0; boolean maybe2DigitYear = false; switch (ch) { case 'd': calendar_field = Calendar.DATE; break; case 'D': calendar_field = Calendar.DAY_OF_YEAR; break; case 'F': calendar_field = Calendar.DAY_OF_WEEK_IN_MONTH; break; case 'E': is_numeric = false; offset = 1; calendar_field = Calendar.DAY_OF_WEEK; match = (fmt_count <= 3 ? formatData.getShortWeekdays() : formatData.getWeekdays()); break; case 'w': calendar_field = Calendar.WEEK_OF_YEAR; break; case 'W': calendar_field = Calendar.WEEK_OF_MONTH; break; case 'M': calendar_field = Calendar.MONTH; if (fmt_count <= 2) offset = -1; else { is_numeric = false; match = (fmt_count <= 3 ? formatData.getShortMonths() : formatData.getMonths()); } break; case 'y': calendar_field = Calendar.YEAR; if (fmt_count <= 2) maybe2DigitYear = true; break; case 'K': calendar_field = Calendar.HOUR; break; case 'h': calendar_field = Calendar.HOUR; break; case 'H': calendar_field = Calendar.HOUR_OF_DAY; break; case 'k': calendar_field = Calendar.HOUR_OF_DAY; break; case 'm': calendar_field = Calendar.MINUTE; break; case 's': calendar_field = Calendar.SECOND; break; case 'S': calendar_field = Calendar.MILLISECOND; break; case 'a': is_numeric = false; calendar_field = Calendar.AM_PM; match = formatData.getAmPmStrings(); break; case 'z': // We need a special case for the timezone, because it // uses a different data structure than the other cases. is_numeric = false; calendar_field = Calendar.DST_OFFSET; String[][] zoneStrings = formatData.getZoneStrings(); int zoneCount = zoneStrings.length; int index = pos.getIndex(); boolean found_zone = false; for (int j = 0; j < zoneCount; j++) { String[] strings = zoneStrings[j]; int k; for (k = 1; k < strings.length; ++k) { if (dateStr.startsWith(strings[k], index)) break; } if (k != strings.length) { found_zone = true; saw_timezone = true; TimeZone tz = TimeZone.getTimeZone (strings[0]); calendar.setTimeZone (tz); calendar.set (Calendar.ZONE_OFFSET, tz.getRawOffset ()); offset = 0; if (k > 2 && tz instanceof SimpleTimeZone) { SimpleTimeZone stz = (SimpleTimeZone) tz; offset = stz.getDSTSavings (); } pos.setIndex(index + strings[k].length()); break; } } if (! found_zone) { pos.setErrorIndex(pos.getIndex()); return null; } break; default: pos.setErrorIndex(pos.getIndex()); return null; } // Compute the value we should assign to the field. int value; int index = -1; if (is_numeric) { numberFormat.setMinimumIntegerDigits(fmt_count); if (maybe2DigitYear) index = pos.getIndex(); Number n = numberFormat.parse(dateStr, pos); if (pos == null || ! (n instanceof Long)) return null; value = n.intValue() + offset; } else if (match != null) { index = pos.getIndex(); int i; for (i = offset; i < match.length; ++i) { if (dateStr.startsWith(match[i], index)) break; } if (i == match.length) { pos.setErrorIndex(index); return null; } pos.setIndex(index + match[i].length()); value = i; } else value = offset; if (maybe2DigitYear) { // Parse into default century if the numeric year string has // exactly 2 digits. int digit_count = pos.getIndex() - index; if (digit_count == 2) is2DigitYear = true; } // Assign the value and move on. calendar.set(calendar_field, value); } if (is2DigitYear) { // Apply the 80-20 heuristic to dermine the full year based on // defaultCenturyStart. int year = defaultCentury + calendar.get(Calendar.YEAR); calendar.set(Calendar.YEAR, year); if (calendar.getTime().compareTo(defaultCenturyStart) < 0) calendar.set(Calendar.YEAR, year + 100); } try { if (! saw_timezone) { // Use the real rules to determine whether or not this // particular time is in daylight savings. calendar.clear (Calendar.DST_OFFSET); calendar.clear (Calendar.ZONE_OFFSET); } return calendar.getTime(); } catch (IllegalArgumentException x) { pos.setErrorIndex(pos.getIndex()); return null; } } // Compute the start of the current century as defined by // get2DigitYearStart. private void computeCenturyStart() { int year = calendar.get(Calendar.YEAR); calendar.set(Calendar.YEAR, year - 80); set2DigitYearStart(calendar.getTime()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -