private AttributedCharacterIterator formatToCharacterIteratorImpl(Date date) { StringBuffer buffer = new StringBuffer(); ArrayList<FieldPosition> fields = new ArrayList<FieldPosition>(); // format the date, and find fields formatImpl(date, buffer, null, fields); // create and AttributedString with the formatted buffer AttributedString as = new AttributedString(buffer.toString()); // add DateFormat field attributes to the AttributedString for (FieldPosition pos : fields) { Format.Field attribute = pos.getFieldAttribute(); as.addAttribute(attribute, attribute, pos.getBeginIndex(), pos.getEndIndex()); } // return the CharacterIterator from AttributedString return as.getIterator(); }
@Override public StringBuffer format(Date d, StringBuffer toAppendTo, FieldPosition pos) { /* delegate to SimpleDateFormat for easy stuff */ super.format(d, toAppendTo, pos); /* worry aboutthe milliseconds ourselves */ long millis = d.getTime() % 1000l; if (0L == millis) { return toAppendTo; } if (millis < 0L) { // original date was prior to epoch millis += 1000L; } int posBegin = toAppendTo.length(); toAppendTo.append(millisFormat.format(millis / 1000d)); if (DateFormat.MILLISECOND_FIELD == pos.getField()) { pos.setBeginIndex(posBegin); pos.setEndIndex(toAppendTo.length()); } return toAppendTo; }
/** * Formats the date. * * <p>If the FieldPosition {@code field} is not null, and the field specified by this * FieldPosition is formatted, set the begin and end index of the formatted field in the * FieldPosition. * * <p>If the list {@code fields} is not null, find fields of this date, set FieldPositions with * these fields, and add them to the fields vector. * * @param date Date to Format * @param buffer StringBuffer to store the resulting formatted String * @param field FieldPosition to set begin and end index of the field specified, if it is part of * the format for this date * @param fields list used to store the FieldPositions for each field in this date * @return the formatted Date * @throws IllegalArgumentException if the object cannot be formatted by this Format. */ private StringBuffer formatImpl( Date date, StringBuffer buffer, FieldPosition field, List<FieldPosition> fields) { boolean quote = false; int next, last = -1, count = 0; calendar.setTime(date); if (field != null) { field.clear(); } final int patternLength = pattern.length(); for (int i = 0; i < patternLength; i++) { next = (pattern.charAt(i)); if (next == '\'') { if (count > 0) { append(buffer, field, fields, (char) last, count); count = 0; } if (last == next) { buffer.append('\''); last = -1; } else { last = next; } quote = !quote; continue; } if (!quote && (last == next || (next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z'))) { if (last == next) { count++; } else { if (count > 0) { append(buffer, field, fields, (char) last, count); } last = next; count = 1; } } else { if (count > 0) { append(buffer, field, fields, (char) last, count); count = 0; } last = -1; buffer.append((char) next); } } if (count > 0) { append(buffer, field, fields, (char) last, count); } return buffer; }
/** * 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 = 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); } } }
private void append( StringBuffer buffer, FieldPosition position, List<FieldPosition> fields, char format, int count) { int field = -1; int index = PATTERN_CHARS.indexOf(format); if (index == -1) { throw new IllegalArgumentException("Unknown pattern character '" + format + "'"); } int beginPosition = buffer.length(); Field dateFormatField = null; switch (index) { case ERA_FIELD: dateFormatField = Field.ERA; buffer.append(formatData.eras[calendar.get(Calendar.ERA)]); break; case YEAR_FIELD: dateFormatField = Field.YEAR; int year = calendar.get(Calendar.YEAR); /* * For 'y' and 'yyy', we're consistent with Unicode and previous releases * of Android. But this means we're inconsistent with the RI. * http://unicode.org/reports/tr35/ */ if (count == 2) { appendNumber(buffer, 2, year % 100); } else { appendNumber(buffer, count, year); } break; case STAND_ALONE_MONTH_FIELD: // 'L' dateFormatField = Field.MONTH; appendMonth(buffer, count, true); break; case MONTH_FIELD: // 'M' dateFormatField = Field.MONTH; appendMonth(buffer, count, false); break; case DATE_FIELD: dateFormatField = Field.DAY_OF_MONTH; field = Calendar.DATE; break; case HOUR_OF_DAY1_FIELD: // 'k' dateFormatField = Field.HOUR_OF_DAY1; int hour = calendar.get(Calendar.HOUR_OF_DAY); appendNumber(buffer, count, hour == 0 ? 24 : hour); break; case HOUR_OF_DAY0_FIELD: // 'H' dateFormatField = Field.HOUR_OF_DAY0; field = Calendar.HOUR_OF_DAY; break; case MINUTE_FIELD: dateFormatField = Field.MINUTE; field = Calendar.MINUTE; break; case SECOND_FIELD: dateFormatField = Field.SECOND; field = Calendar.SECOND; break; case MILLISECOND_FIELD: dateFormatField = Field.MILLISECOND; int value = calendar.get(Calendar.MILLISECOND); appendNumber(buffer, count, value); break; case STAND_ALONE_DAY_OF_WEEK_FIELD: dateFormatField = Field.DAY_OF_WEEK; appendDayOfWeek(buffer, count, true); break; case DAY_OF_WEEK_FIELD: dateFormatField = Field.DAY_OF_WEEK; appendDayOfWeek(buffer, count, false); break; case DAY_OF_YEAR_FIELD: dateFormatField = Field.DAY_OF_YEAR; field = Calendar.DAY_OF_YEAR; break; case DAY_OF_WEEK_IN_MONTH_FIELD: dateFormatField = Field.DAY_OF_WEEK_IN_MONTH; field = Calendar.DAY_OF_WEEK_IN_MONTH; break; case WEEK_OF_YEAR_FIELD: dateFormatField = Field.WEEK_OF_YEAR; field = Calendar.WEEK_OF_YEAR; break; case WEEK_OF_MONTH_FIELD: dateFormatField = Field.WEEK_OF_MONTH; field = Calendar.WEEK_OF_MONTH; break; case AM_PM_FIELD: dateFormatField = Field.AM_PM; buffer.append(formatData.ampms[calendar.get(Calendar.AM_PM)]); break; case HOUR1_FIELD: // 'h' dateFormatField = Field.HOUR1; hour = calendar.get(Calendar.HOUR); appendNumber(buffer, count, hour == 0 ? 12 : hour); break; case HOUR0_FIELD: // 'K' dateFormatField = Field.HOUR0; field = Calendar.HOUR; break; case TIMEZONE_FIELD: // 'z' dateFormatField = Field.TIME_ZONE; appendTimeZone(buffer, count, true); break; case RFC_822_TIMEZONE_FIELD: // 'Z' dateFormatField = Field.TIME_ZONE; appendNumericTimeZone(buffer, count, false); break; } if (field != -1) { appendNumber(buffer, count, calendar.get(field)); } if (fields != null) { position = new FieldPosition(dateFormatField); position.setBeginIndex(beginPosition); position.setEndIndex(buffer.length()); fields.add(position); } else { // Set to the first occurrence if ((position.getFieldAttribute() == dateFormatField || (position.getFieldAttribute() == null && position.getField() == index)) && position.getEndIndex() == 0) { position.setBeginIndex(beginPosition); position.setEndIndex(buffer.length()); } } }
private StringBuffer formatInternal( Object arguments[], StringBuffer appendBuf, FieldPosition fp, FormatCharacterIterator output_iterator) { appendBuf.append(leader); if (output_iterator != null) output_iterator.append(leader); for (int i = 0; i < elements.length; ++i) { Object thisArg = null; boolean unavailable = false; if (arguments == null || elements[i].argNumber >= arguments.length) unavailable = true; else thisArg = arguments[elements[i].argNumber]; AttributedCharacterIterator iterator = null; Format formatter = null; if (fp != null && i == fp.getField() && fp.getFieldAttribute() == Field.ARGUMENT) fp.setBeginIndex(appendBuf.length()); if (unavailable) appendBuf.append("{" + elements[i].argNumber + "}"); else { if (elements[i].setFormat != null) formatter = elements[i].setFormat; else if (elements[i].format != null) { if (elements[i].formatClass != null && !elements[i].formatClass.isInstance(thisArg)) throw new IllegalArgumentException("Wrong format class"); formatter = elements[i].format; } else if (thisArg instanceof Number) formatter = NumberFormat.getInstance(locale); else if (thisArg instanceof Date) formatter = DateFormat.getTimeInstance(DateFormat.DEFAULT, locale); else appendBuf.append(thisArg); } if (fp != null && fp.getField() == i && fp.getFieldAttribute() == Field.ARGUMENT) fp.setEndIndex(appendBuf.length()); if (formatter != null) { // Special-case ChoiceFormat. if (formatter instanceof ChoiceFormat) { StringBuffer buf = new StringBuffer(); formatter.format(thisArg, buf, fp); MessageFormat mf = new MessageFormat(); mf.setLocale(locale); mf.applyPattern(buf.toString()); mf.format(arguments, appendBuf, fp); } else { if (output_iterator != null) iterator = formatter.formatToCharacterIterator(thisArg); else formatter.format(thisArg, appendBuf, fp); } elements[i].format = formatter; } if (output_iterator != null) { HashMap hash_argument = new HashMap(); int position = output_iterator.getEndIndex(); hash_argument.put(MessageFormat.Field.ARGUMENT, new Integer(elements[i].argNumber)); if (iterator != null) { output_iterator.append(iterator); output_iterator.addAttributes(hash_argument, position, output_iterator.getEndIndex()); } else output_iterator.append(thisArg.toString(), hash_argument); output_iterator.append(elements[i].trailer); } appendBuf.append(elements[i].trailer); } return appendBuf; }