You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by to...@apache.org on 2007/11/18 04:24:27 UTC
svn commit: r596044 [3/3] - in /harmony/enhanced/classlib/trunk/modules:
luni/make/ luni/src/main/java/java/util/
luni/src/main/java/org/apache/harmony/luni/internal/locale/
luni/src/test/api/common/tests/api/java/util/ text/make/
text/src/main/java/ja...
Modified: harmony/enhanced/classlib/trunk/modules/text/src/main/java/java/text/SimpleDateFormat.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/text/src/main/java/java/text/SimpleDateFormat.java?rev=596044&r1=596043&r2=596044&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/text/src/main/java/java/text/SimpleDateFormat.java (original)
+++ harmony/enhanced/classlib/trunk/modules/text/src/main/java/java/text/SimpleDateFormat.java Sat Nov 17 19:24:06 2007
@@ -25,6 +25,10 @@
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
+import java.util.ResourceBundle;
+import java.util.SimpleTimeZone;
+import java.util.TimeZone;
+import java.util.Vector;
import org.apache.harmony.text.internal.nls.Messages;
@@ -40,7 +44,7 @@
private static final long serialVersionUID = 4774881970558875024L;
- private static final String patternChars = "GyMdkHmsSEDFwWahKzYeugAZvcLQqV"; //$NON-NLS-1$
+ private static final String patternChars = "GyMdkHmsSEDFwWahKzZ"; //$NON-NLS-1$
private String pattern;
@@ -50,16 +54,13 @@
private Date defaultCenturyStart;
- private transient com.ibm.icu.text.SimpleDateFormat icuFormat;
-
/**
* Constructs a new SimpleDateFormat for formatting and parsing dates and
* times in the SHORT style for the default Locale.
*/
public SimpleDateFormat() {
this(Locale.getDefault());
- icuFormat = new com.ibm.icu.text.SimpleDateFormat();
- pattern = (String)getInternalField("pattern",icuFormat);
+ pattern = defaultPattern();
formatData = new DateFormatSymbols(Locale.getDefault());
}
@@ -80,86 +81,7 @@
public SimpleDateFormat(String pattern) {
this(pattern, Locale.getDefault());
}
-
- /**
- * Validate the format character.
- *
- * @param format
- * the format character
- *
- * @throws IllegalArgumentException
- * when the format character is invalid
- */
- private void validateFormat(char format) {
- int index = patternChars.indexOf(format);
- if (index == -1) {
- // text.03=Unknown pattern character - '{0}'
- throw new IllegalArgumentException(Messages.getString(
- "text.03", format)); //$NON-NLS-1$
- }
- }
-
- /**
- * Validate the pattern.
- *
- * @param template
- * the pattern to validate.
- *
- * @throws NullPointerException
- * if the pattern is null
- * @throws IllegalArgumentException
- * if the pattern is invalid
- */
- private void validatePattern(String template) {
- boolean quote = false;
- int next, last = -1, count = 0;
-
- final int patternLength = template.length();
- for (int i = 0; i < patternLength; i++) {
- next = (template.charAt(i));
- if (next == '\'') {
- if (count > 0) {
- validateFormat((char) last);
- count = 0;
- }
- if (last == next) {
- 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) {
- validateFormat((char) last);
- }
- last = next;
- count = 1;
- }
- } else {
- if (count > 0) {
- validateFormat((char) last);
- count = 0;
- }
- last = -1;
- }
- }
- if (count > 0) {
- validateFormat((char) last);
- }
-
- if (quote) {
- // text.04=Unterminated quote {0}
- throw new IllegalArgumentException(Messages.getString("text.04")); //$NON-NLS-1$
- }
- }
-
/**
* Constructs a new SimpleDateFormat using the specified non-localized
* pattern and DateFormatSymbols and the Calendar for the default Locale.
@@ -177,22 +99,10 @@
public SimpleDateFormat(String template, DateFormatSymbols value) {
this(Locale.getDefault());
validatePattern(template);
- icuFormat = new com.ibm.icu.text.SimpleDateFormat(template, Locale.getDefault());
pattern = template;
formatData = (DateFormatSymbols) value.clone();
}
- private void copySymbols(DateFormatSymbols value, com.ibm.icu.text.DateFormatSymbols icuSymbols) {
- icuSymbols.setAmPmStrings(value.getAmPmStrings());
- icuSymbols.setEras(value.getEras());
- icuSymbols.setLocalPatternChars(value.getLocalPatternChars());
- icuSymbols.setMonths(value.getMonths());
- icuSymbols.setShortMonths(value.getShortMonths());
- icuSymbols.setShortWeekdays(value.getShortWeekdays());
- icuSymbols.setWeekdays(value.getWeekdays());
- icuSymbols.setZoneStrings(value.getZoneStrings());
- }
-
/**
* Constructs a new SimpleDateFormat using the specified non-localized
* pattern and the DateFormatSymbols and Calendar for the specified Locale.
@@ -210,18 +120,10 @@
public SimpleDateFormat(String template, Locale locale) {
this(locale);
validatePattern(template);
- icuFormat = new com.ibm.icu.text.SimpleDateFormat(template, locale);
pattern = template;
formatData = new DateFormatSymbols(locale);
}
- SimpleDateFormat(Locale locale, com.ibm.icu.text.SimpleDateFormat icuFormat){
- this(locale);
- this.icuFormat = icuFormat;
- pattern = (String)Format.getInternalField("pattern", icuFormat);
- formatData = new DateFormatSymbols(locale);
- }
-
private SimpleDateFormat(Locale locale) {
numberFormat = NumberFormat.getInstance(locale);
numberFormat.setParseIntegerOnly(true);
@@ -232,6 +134,194 @@
defaultCenturyStart = calendar.getTime();
}
+ private void append(StringBuffer buffer, FieldPosition position,
+ Vector<FieldPosition> fields, char format, int count) {
+ int field = -1;
+ int index = patternChars.indexOf(format);
+ if (index == -1) {
+ // text.03=Unknown pattern character - '{0}'
+ throw new IllegalArgumentException(Messages.getString(
+ "text.03", format)); //$NON-NLS-1$
+ }
+
+ 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);
+ if (count < 4) {
+ appendNumber(buffer, 2, year %= 100);
+ } else {
+ appendNumber(buffer, count, year);
+ }
+ break;
+ case MONTH_FIELD:
+ dateFormatField = Field.MONTH;
+ int month = calendar.get(Calendar.MONTH);
+ if (count <= 2) {
+ appendNumber(buffer, count, month + 1);
+ } else if (count == 3) {
+ buffer.append(formatData.shortMonths[month]);
+ } else {
+ buffer.append(formatData.months[month]);
+ }
+ 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 DAY_OF_WEEK_FIELD:
+ dateFormatField = Field.DAY_OF_WEEK;
+ int day = calendar.get(Calendar.DAY_OF_WEEK);
+ if (count < 4) {
+ buffer.append(formatData.shortWeekdays[day]);
+ } else {
+ buffer.append(formatData.weekdays[day]);
+ }
+ 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 (TIMEZONE_FIELD + 1): // Z
+ dateFormatField = Field.TIME_ZONE;
+ appendTimeZone(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 void appendTimeZone(StringBuffer buffer, int count,
+ boolean generalTimezone) {
+ // cannot call TimeZone.getDisplayName() because it would not use
+ // the DateFormatSymbols of this SimpleDateFormat
+
+ if (generalTimezone) {
+ String id = calendar.getTimeZone().getID();
+ String[][] zones = formatData.zoneStrings;
+ String[] zone = null;
+ for (String[] element : zones) {
+ if (id.equals(element[0])) {
+ zone = element;
+ break;
+ }
+ }
+ if (zone == null) {
+ int offset = calendar.get(Calendar.ZONE_OFFSET)
+ + calendar.get(Calendar.DST_OFFSET);
+ char sign = '+';
+ if (offset < 0) {
+ sign = '-';
+ offset = -offset;
+ }
+ buffer.append("GMT"); //$NON-NLS-1$
+ buffer.append(sign);
+ appendNumber(buffer, 2, offset / 3600000);
+ buffer.append(':');
+ appendNumber(buffer, 2, (offset % 3600000) / 60000);
+ } else {
+ int daylight = calendar.get(Calendar.DST_OFFSET) == 0 ? 0 : 2;
+ if (count < 4) {
+ buffer.append(zone[2 + daylight]);
+ } else {
+ buffer.append(zone[1 + daylight]);
+ }
+ }
+ } else {
+ int offset = calendar.get(Calendar.ZONE_OFFSET)
+ + calendar.get(Calendar.DST_OFFSET);
+ char sign = '+';
+ if (offset < 0) {
+ sign = '-';
+ offset = -offset;
+ }
+ buffer.append(sign);
+ appendNumber(buffer, 2, offset / 3600000);
+ appendNumber(buffer, 2, (offset % 3600000) / 60000);
+ }
+ }
+
+ private void appendNumber(StringBuffer buffer, int count, int value) {
+ int minimumIntegerDigits = numberFormat.getMinimumIntegerDigits();
+ numberFormat.setMinimumIntegerDigits(count);
+ numberFormat.format(new Integer(value), buffer, new FieldPosition(0));
+ numberFormat.setMinimumIntegerDigits(minimumIntegerDigits);
+ }
+
/**
* Changes the pattern of this SimpleDateFormat to the specified pattern
* which uses localized pattern characters.
@@ -240,8 +330,8 @@
* the localized pattern
*/
public void applyLocalizedPattern(String template) {
- icuFormat.applyLocalizedPattern(template);
- pattern = icuFormat.toPattern();
+ pattern = convertPattern(template, formatData.getLocalPatternChars(),
+ patternChars, true);
}
/**
@@ -258,7 +348,6 @@
*/
public void applyPattern(String template) {
validatePattern(template);
- icuFormat.applyPattern(template);
pattern = template;
}
@@ -278,6 +367,13 @@
return clone;
}
+ private static String defaultPattern() {
+ ResourceBundle bundle = getBundle(Locale.getDefault());
+ String styleName = getStyleName(SHORT);
+ return bundle.getString("Date_" + styleName) + " " //$NON-NLS-1$ //$NON-NLS-2$
+ + bundle.getString("Time_" + styleName); //$NON-NLS-1$
+ }
+
/**
* Compares the specified object to this SimpleDateFormat and answer if they
* are equal. The object must be an instance of SimpleDateFormat and have
@@ -304,6 +400,12 @@
&& formatData.equals(simple.formatData);
}
+ private Date error(ParsePosition position, int offset, TimeZone zone) {
+ position.setErrorIndex(offset);
+ calendar.setTimeZone(zone);
+ return null;
+ }
+
/**
* Formats the specified object using the rules of this SimpleDateFormat and
* returns an AttributedCharacterIterator with the formatted Date and
@@ -321,7 +423,39 @@
*/
@Override
public AttributedCharacterIterator formatToCharacterIterator(Object object) {
- return icuFormat.formatToCharacterIterator(object);
+ if (object == null) {
+ throw new NullPointerException();
+ }
+ if (object instanceof Date) {
+ return formatToCharacterIteratorImpl((Date) object);
+ }
+ if (object instanceof Number) {
+ return formatToCharacterIteratorImpl(new Date(((Number) object)
+ .longValue()));
+ }
+ throw new IllegalArgumentException();
+ }
+
+ private AttributedCharacterIterator formatToCharacterIteratorImpl(Date date) {
+ StringBuffer buffer = new StringBuffer();
+ Vector<FieldPosition> fields = new Vector<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 (int i = 0; i < fields.size(); i++) {
+ FieldPosition pos = fields.elementAt(i);
+ Format.Field attribute = pos.getFieldAttribute();
+ as.addAttribute(attribute, attribute, pos.getBeginIndex(), pos
+ .getEndIndex());
+ }
+
+ // return the CharacterIterator from AttributedString
+ return as.getIterator();
}
/**
@@ -344,11 +478,167 @@
@Override
public StringBuffer format(Date date, StringBuffer buffer,
FieldPosition field) {
- icuFormat.setTimeZone(com.ibm.icu.util.TimeZone.getTimeZone(calendar
- .getTimeZone().getID()));
- return icuFormat.format(date, buffer, field);
+ return formatImpl(date, buffer, field, null);
}
+ /**
+ * Validate the format character.
+ *
+ * @param format
+ * the format character
+ *
+ * @throws IllegalArgumentException
+ * when the format character is invalid
+ */
+ private void validateFormat(char format) {
+ int index = patternChars.indexOf(format);
+ if (index == -1) {
+ // text.03=Unknown pattern character - '{0}'
+ throw new IllegalArgumentException(Messages.getString(
+ "text.03", format)); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * Validate the pattern.
+ *
+ * @param template
+ * the pattern to validate.
+ *
+ * @throws NullPointerException
+ * if the pattern is null
+ * @throws IllegalArgumentException
+ * if the pattern is invalid
+ */
+ private void validatePattern(String template) {
+ boolean quote = false;
+ int next, last = -1, count = 0;
+
+ final int patternLength = template.length();
+ for (int i = 0; i < patternLength; i++) {
+ next = (template.charAt(i));
+ if (next == '\'') {
+ if (count > 0) {
+ validateFormat((char) last);
+ count = 0;
+ }
+ if (last == next) {
+ 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) {
+ validateFormat((char) last);
+ }
+ last = next;
+ count = 1;
+ }
+ } else {
+ if (count > 0) {
+ validateFormat((char) last);
+ count = 0;
+ }
+ last = -1;
+ }
+ }
+ if (count > 0) {
+ validateFormat((char) last);
+ }
+
+ if (quote) {
+ // text.04=Unterminated quote {0}
+ throw new IllegalArgumentException(Messages.getString("text.04")); //$NON-NLS-1$
+ }
+
+ }
+
+ /**
+ * Formats the date.
+ * <p>
+ * If the FieldPosition <code>field</code> 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 Vector <code>fields</code> 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
+ * Vector used to store the FieldPositions for each field in this
+ * date
+ *
+ * @return the formatted Date
+ *
+ * @exception IllegalArgumentException
+ * when the object cannot be formatted by this Format
+ */
+ private StringBuffer formatImpl(Date date, StringBuffer buffer,
+ FieldPosition field, Vector<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;
+ }
/**
* Answers the Date which is the start of the one hundred year period for
@@ -384,6 +674,131 @@
+ creationYear;
}
+ private int parse(String string, int offset, char format, int count) {
+ int index = patternChars.indexOf(format);
+ if (index == -1) {
+ // text.03=Unknown pattern character - '{0}'
+ throw new IllegalArgumentException(Messages.getString(
+ "text.03", format)); //$NON-NLS-1$
+ }
+ int field = -1;
+ int absolute = 0;
+ if (count < 0) {
+ count = -count;
+ absolute = count;
+ }
+ switch (index) {
+ case ERA_FIELD:
+ return parseText(string, offset, formatData.eras, Calendar.ERA);
+ case YEAR_FIELD:
+ if (count >= 3) {
+ field = Calendar.YEAR;
+ } else {
+ ParsePosition position = new ParsePosition(offset);
+ Number result = parseNumber(absolute, string, position);
+ if (result == null) {
+ return -position.getErrorIndex() - 1;
+ }
+ int year = result.intValue();
+ // A two digit year must be exactly two digits, i.e. 01
+ if ((position.getIndex() - offset) == 2 && year >= 0) {
+ year += creationYear / 100 * 100;
+ if (year < creationYear) {
+ year += 100;
+ }
+ }
+ calendar.set(Calendar.YEAR, year);
+ return position.getIndex();
+ }
+ break;
+ case MONTH_FIELD:
+ if (count <= 2) {
+ return parseNumber(absolute, string, offset,
+ Calendar.MONTH, -1);
+ }
+ index = parseText(string, offset, formatData.months,
+ Calendar.MONTH);
+ if (index < 0) {
+ return parseText(string, offset, formatData.shortMonths,
+ Calendar.MONTH);
+ }
+ return index;
+ case DATE_FIELD:
+ field = Calendar.DATE;
+ break;
+ case HOUR_OF_DAY1_FIELD:
+ ParsePosition position = new ParsePosition(offset);
+ Number result = parseNumber(absolute, string, position);
+ if (result == null) {
+ return -position.getErrorIndex() - 1;
+ }
+ int hour = result.intValue();
+ if (hour == 24) {
+ hour = 0;
+ }
+ calendar.set(Calendar.HOUR_OF_DAY, hour);
+ return position.getIndex();
+ case HOUR_OF_DAY0_FIELD:
+ field = Calendar.HOUR_OF_DAY;
+ break;
+ case MINUTE_FIELD:
+ field = Calendar.MINUTE;
+ break;
+ case SECOND_FIELD:
+ field = Calendar.SECOND;
+ break;
+ case MILLISECOND_FIELD:
+ field = Calendar.MILLISECOND;
+ break;
+ case DAY_OF_WEEK_FIELD:
+ index = parseText(string, offset, formatData.weekdays,
+ Calendar.DAY_OF_WEEK);
+ if (index < 0) {
+ return parseText(string, offset, formatData.shortWeekdays,
+ Calendar.DAY_OF_WEEK);
+ }
+ return index;
+ case DAY_OF_YEAR_FIELD:
+ field = Calendar.DAY_OF_YEAR;
+ break;
+ case DAY_OF_WEEK_IN_MONTH_FIELD:
+ field = Calendar.DAY_OF_WEEK_IN_MONTH;
+ break;
+ case WEEK_OF_YEAR_FIELD:
+ field = Calendar.WEEK_OF_YEAR;
+ break;
+ case WEEK_OF_MONTH_FIELD:
+ field = Calendar.WEEK_OF_MONTH;
+ break;
+ case AM_PM_FIELD:
+ return parseText(string, offset, formatData.ampms,
+ Calendar.AM_PM);
+ case HOUR1_FIELD:
+ position = new ParsePosition(offset);
+ result = parseNumber(absolute, string, position);
+ if (result == null) {
+ return -position.getErrorIndex() - 1;
+ }
+ hour = result.intValue();
+ if (hour == 12) {
+ hour = 0;
+ }
+ calendar.set(Calendar.HOUR, hour);
+ return position.getIndex();
+ case HOUR0_FIELD:
+ field = Calendar.HOUR;
+ break;
+ case TIMEZONE_FIELD:
+ return parseTimeZone(string, offset);
+ case (TIMEZONE_FIELD + 1):
+ return parseTimeZone(string, offset);
+ }
+ if (field != -1) {
+ return parseNumber(absolute, string, offset, field, 0);
+ }
+ return offset;
+ }
+
/**
* Parse a Date from the specified String starting at the index specified by
* the ParsePosition. If the string is successfully parsed, the index of the
@@ -403,9 +818,192 @@
*/
@Override
public Date parse(String string, ParsePosition position) {
- icuFormat.setTimeZone(com.ibm.icu.util.TimeZone.getTimeZone(calendar
- .getTimeZone().getID()));
- return icuFormat.parse(string,position);
+ boolean quote = false;
+ int next, last = -1, count = 0, offset = position.getIndex();
+ int length = string.length();
+ calendar.clear();
+ TimeZone zone = calendar.getTimeZone();
+ final int patternLength = pattern.length();
+ for (int i = 0; i < patternLength; i++) {
+ next = pattern.charAt(i);
+ if (next == '\'') {
+ if (count > 0) {
+ if ((offset = parse(string, offset, (char) last, count)) < 0) {
+ return error(position, -offset - 1, zone);
+ }
+ count = 0;
+ }
+ if (last == next) {
+ if (offset >= length || string.charAt(offset) != '\'') {
+ return error(position, offset, zone);
+ }
+ offset++;
+ 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) {
+ if ((offset = parse(string, offset, (char) last, -count)) < 0) {
+ return error(position, -offset - 1, zone);
+ }
+ }
+ last = next;
+ count = 1;
+ }
+ } else {
+ if (count > 0) {
+ if ((offset = parse(string, offset, (char) last, count)) < 0) {
+ return error(position, -offset - 1, zone);
+ }
+ count = 0;
+ }
+ last = -1;
+ if (offset >= length || string.charAt(offset) != next) {
+ return error(position, offset, zone);
+ }
+ offset++;
+ }
+ }
+ if (count > 0) {
+ if ((offset = parse(string, offset, (char) last, count)) < 0) {
+ return error(position, -offset - 1, zone);
+ }
+ }
+ Date date;
+ try {
+ date = calendar.getTime();
+ } catch (IllegalArgumentException e) {
+ return error(position, offset, zone);
+ }
+ position.setIndex(offset);
+ calendar.setTimeZone(zone);
+ return date;
+ }
+
+ private Number parseNumber(int max, String string, ParsePosition position) {
+ int digit, length = string.length(), result = 0;
+ int index = position.getIndex();
+ if (max > 0 && max < length - index) {
+ length = index + max;
+ }
+ while (index < length
+ && (string.charAt(index) == ' ' || string.charAt(index) == '\t')) {
+ index++;
+ }
+ if (max == 0) {
+ position.setIndex(index);
+ return numberFormat.parse(string, position);
+ }
+
+ while (index < length
+ && (digit = Character.digit(string.charAt(index), 10)) != -1) {
+ index++;
+ result = result * 10 + digit;
+ }
+ if (index == position.getIndex()) {
+ position.setErrorIndex(index);
+ return null;
+ }
+ position.setIndex(index);
+ return new Integer(result);
+ }
+
+ private int parseNumber(int max, String string, int offset, int field,
+ int skew) {
+ ParsePosition position = new ParsePosition(offset);
+ Number result = parseNumber(max, string, position);
+ if (result == null) {
+ return -position.getErrorIndex() - 1;
+ }
+ calendar.set(field, result.intValue() + skew);
+ return position.getIndex();
+ }
+
+ private int parseText(String string, int offset, String[] text, int field) {
+ int found = -1;
+ for (int i = 0; i < text.length; i++) {
+ if (text[i].length() == 0) {
+ continue;
+ }
+ if (string
+ .regionMatches(true, offset, text[i], 0, text[i].length())) {
+ // Search for the longest match, in case some fields are subsets
+ if (found == -1 || text[i].length() > text[found].length()) {
+ found = i;
+ }
+ }
+ }
+ if (found != -1) {
+ calendar.set(field, found);
+ return offset + text[found].length();
+ }
+ return -offset - 1;
+ }
+
+ private int parseTimeZone(String string, int offset) {
+ String[][] zones = formatData.zoneStrings;
+ boolean foundGMT = string.regionMatches(offset, "GMT", 0, 3); //$NON-NLS-1$
+ if (foundGMT) {
+ offset += 3;
+ }
+ char sign;
+ if (offset < string.length()
+ && ((sign = string.charAt(offset)) == '+' || sign == '-')) {
+ ParsePosition position = new ParsePosition(offset + 1);
+ Number result = numberFormat.parse(string, position);
+ if (result == null) {
+ return -position.getErrorIndex() - 1;
+ }
+ int hour = result.intValue();
+ int raw = hour * 3600000;
+ int index = position.getIndex();
+ if (index < string.length() && string.charAt(index) == ':') {
+ position.setIndex(index + 1);
+ result = numberFormat.parse(string, position);
+ if (result == null) {
+ return -position.getErrorIndex() - 1;
+ }
+ int minute = result.intValue();
+ raw += minute * 60000;
+ } else if (hour >= 24) {
+ raw = (hour / 100 * 3600000) + (hour % 100 * 60000);
+ }
+ if (sign == '-') {
+ raw = -raw;
+ }
+ calendar.setTimeZone(new SimpleTimeZone(raw, "")); //$NON-NLS-1$
+ return position.getIndex();
+ }
+ if (foundGMT) {
+ calendar.setTimeZone(TimeZone.getTimeZone("GMT")); //$NON-NLS-1$
+ return offset;
+ }
+ for (String[] element : zones) {
+ for (int j = 1; j < 5; j++) {
+ if (string.regionMatches(true, offset, element[j], 0,
+ element[j].length())) {
+ TimeZone zone = TimeZone.getTimeZone(element[0]);
+ if (zone == null) {
+ return -offset - 1;
+ }
+ int raw = zone.getRawOffset();
+ if (j >= 3 && zone.useDaylightTime()) {
+ raw += 3600000;
+ }
+ calendar.setTimeZone(new SimpleTimeZone(raw, "")); //$NON-NLS-1$
+ return offset + element[j].length();
+ }
+ }
+ }
+ return -offset - 1;
}
/**
@@ -416,7 +1014,6 @@
* the Date
*/
public void set2DigitYearStart(Date date) {
- icuFormat.set2DigitYearStart(date);
defaultCenturyStart = date;
Calendar cal = new GregorianCalendar();
cal.setTime(date);
@@ -430,9 +1027,6 @@
* the DateFormatSymbols
*/
public void setDateFormatSymbols(DateFormatSymbols value) {
- com.ibm.icu.text.DateFormatSymbols icuSymbols = new com.ibm.icu.text.DateFormatSymbols();
- copySymbols(value, icuSymbols);
- icuFormat.setDateFormatSymbols(icuSymbols);
formatData = (DateFormatSymbols) value.clone();
}
@@ -443,7 +1037,8 @@
* @return the localized pattern
*/
public String toLocalizedPattern() {
- return icuFormat.toLocalizedPattern();
+ return convertPattern(pattern, patternChars, formatData
+ .getLocalPatternChars(), false);
}
/**
Modified: harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/CollationElementIteratorTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/CollationElementIteratorTest.java?rev=596044&r1=596043&r2=596044&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/CollationElementIteratorTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/CollationElementIteratorTest.java Sat Nov 17 19:24:06 2007
@@ -167,7 +167,7 @@
CollationElementIterator iterator = rbColl
.getCollationElementIterator(text);
iterator.setOffset(1);
- assertEquals(1, iterator.getOffset());
+ assertEquals(0, iterator.getOffset());
}
/*
@@ -183,7 +183,7 @@
assertEquals(1, iterator.getOffset());
iterator.setText("cha");
iterator.setOffset(1);
- assertEquals(1, iterator.getOffset());
+ assertEquals(0, iterator.getOffset());
}
/*
@@ -199,6 +199,6 @@
assertEquals(1, iterator.getOffset());
iterator.setText(new StringCharacterIterator("cha"));
iterator.setOffset(1);
- assertEquals(1, iterator.getOffset());
+ assertEquals(0, iterator.getOffset());
}
}
Modified: harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/DateFormatSymbolsTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/DateFormatSymbolsTest.java?rev=596044&r1=596043&r2=596044&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/DateFormatSymbolsTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/DateFormatSymbolsTest.java Sat Nov 17 19:24:06 2007
@@ -99,9 +99,9 @@
// java.text.DateFormatSymbols.getLocalPatternChars()
String retVal = dfs.getLocalPatternChars();
- String val = "GyMdkHmsSEDFwWahKzYeugAZvcLQqV";
+ String val = "GyMdkHmsSEDFwWahKzZ";
- assertEquals("Returned incorrect pattern string", val, retVal);
+ assertTrue("Returned incorrect pattern string", retVal.equals(val));
}
/**
@@ -113,8 +113,9 @@
String[] retVal = dfs.getMonths();
String[] val = { "January", "February", "March", "April", "May",
"June", "July", "August", "September", "October", "November",
- "December"};
- assertEquals("Returned wrong array: ", val.length, retVal.length);
+ "December", "" };
+ if (retVal.length != val.length)
+ fail("Returned wrong array: " + retVal.length);
for (int i = 0; i < val.length; i++)
assertTrue("Array values do not match", retVal[i].equals(val[i]));
}
@@ -127,8 +128,9 @@
// java.text.DateFormatSymbols.getShortMonths()
String[] retVal = dfs.getShortMonths();
String[] val = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
- "Aug", "Sep", "Oct", "Nov", "Dec"};
- assertEquals("Returned wrong array: ", val.length, retVal.length);
+ "Aug", "Sep", "Oct", "Nov", "Dec", "" };
+ if (retVal.length != val.length)
+ fail("Returned wrong array");
for (int i = 0; i < val.length; i++)
assertTrue("Array values do not match", retVal[i].equals(val[i]));
}
Modified: harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java?rev=596044&r1=596043&r2=596044&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/DecimalFormatSymbolsTest.java Sat Nov 17 19:24:06 2007
@@ -68,8 +68,8 @@
*/
public void test_getCurrency() {
Currency currency = Currency.getInstance("USD");
- assertEquals("Returned incorrect currency",
- dfsUS.getCurrency(), currency);
+ assertTrue("Returned incorrect currency",
+ dfsUS.getCurrency() == currency);
Currency currK = Currency.getInstance("KRW");
Currency currX = Currency.getInstance("XXX");
@@ -239,8 +239,8 @@
dfs.setCurrency(currency);
assertTrue("Returned incorrect currency", currency == dfs.getCurrency());
- assertEquals("Returned incorrect currency symbol", currency.getSymbol(
- locale), dfs.getCurrencySymbol());
+ assertTrue("Returned incorrect currency symbol", currency.getSymbol(
+ locale).equals(dfs.getCurrencySymbol()));
assertTrue("Returned incorrect international currency symbol", currency
.getCurrencyCode().equals(dfs.getInternationalCurrencySymbol()));
}
@@ -292,14 +292,17 @@
assertTrue("Test1: Returned incorrect currency", currency == dfs
.getCurrency());
- assertEquals("Test1: Returned incorrect currency symbol", currency
- .getSymbol(locale), dfs.getCurrencySymbol());
+ assertTrue("Test1: Returned incorrect currency symbol", currency
+ .getSymbol(locale).equals(dfs.getCurrencySymbol()));
assertTrue("Test1: Returned incorrect international currency symbol",
currency.getCurrencyCode().equals(
dfs.getInternationalCurrencySymbol()));
+ String symbol = dfs.getCurrencySymbol();
dfs.setInternationalCurrencySymbol("bogus");
- assertNotNull("Test2: Returned incorrect currency", dfs.getCurrency());
+ assertNull("Test2: Returned incorrect currency", dfs.getCurrency());
+ assertTrue("Test2: Returned incorrect currency symbol", dfs
+ .getCurrencySymbol().equals(symbol));
assertEquals("Test2: Returned incorrect international currency symbol",
"bogus", dfs.getInternationalCurrencySymbol());
}
Modified: harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java
URL: http://svn.apache.org/viewvc/harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java?rev=596044&r1=596043&r2=596044&view=diff
==============================================================================
--- harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java (original)
+++ harmony/enhanced/classlib/trunk/modules/text/src/test/java/org/apache/harmony/text/tests/java/text/RuleBasedCollatorTest.java Sat Nov 17 19:24:06 2007
@@ -130,7 +130,7 @@
String source = "cha";
CollationElementIterator iterator = coll
.getCollationElementIterator(source);
- int[] e_offset = { 0, 1, 2 ,3};
+ int[] e_offset = { 0, 2, 3 };
int offset = iterator.getOffset();
int i = 0;
assertEquals(e_offset[i++], offset);
@@ -180,7 +180,7 @@
StringCharacterIterator source = new StringCharacterIterator(text);
CollationElementIterator iterator = coll
.getCollationElementIterator(source);
- int[] e_offset = { 0, 1, 2, 3 };
+ int[] e_offset = { 0, 2, 3 };
int offset = iterator.getOffset();
int i = 0;
assertEquals(e_offset[i++], offset);