harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ton...@apache.org
Subject 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...
Date Sun, 18 Nov 2007 03:24:27 GMT
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);



Mime
View raw message