src/share/classes/java/text/SimpleDateFormat.java

Print this page

        

@@ -46,16 +46,17 @@
 import java.util.Date;
 import java.util.GregorianCalendar;
 import java.util.Locale;
 import java.util.Map;
 import java.util.SimpleTimeZone;
+import java.util.SortedMap;
 import java.util.TimeZone;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-import sun.util.locale.provider.LocaleProviderAdapter;
 import sun.util.calendar.CalendarUtils;
 import sun.util.calendar.ZoneInfoFile;
+import sun.util.locale.provider.LocaleProviderAdapter;
 
 /**
  * <code>SimpleDateFormat</code> is a concrete class for formatting and
  * parsing dates in a locale-sensitive manner. It allows for formatting
  * (date -> text), parsing (text -> date), and normalization.

@@ -1591,10 +1592,21 @@
      * String[].
      */
     private int matchString(String text, int start, int field,
                             Map<String,Integer> data, CalendarBuilder calb) {
         if (data != null) {
+            // TODO: make this default when it's in the spec.
+            if (data instanceof SortedMap) {
+                for (String name : data.keySet()) {
+                    if (text.regionMatches(true, start, name, 0, name.length())) {
+                        calb.set(field, data.get(name));
+                        return start + name.length();
+                    }
+                }
+                return -start;
+            }
+
             String bestMatch = null;
 
             for (String name : data.keySet()) {
                 int length = name.length();
                 if (bestMatch == null || length > bestMatch.length()) {

@@ -1801,11 +1813,11 @@
      */
     private int subParse(String text, int start, int patternCharIndex, int count,
                          boolean obeyCount, boolean[] ambiguousYear,
                          ParsePosition origPos,
                          boolean useFollowingMinusSignAsDelimiter, CalendarBuilder calb) {
-        Number number = null;
+        Number number;
         int value = 0;
         ParsePosition pos = new ParsePosition(0);
         pos.index = start;
         if (patternCharIndex == PATTERN_WEEK_YEAR && !calendar.isWeekDateSupported()) {
             // use calendar year 'y' instead

@@ -1874,13 +1886,11 @@
                 if (useDateFormatSymbols) {
                     if ((index = matchString(text, start, Calendar.ERA, formatData.getEras(), calb)) > 0) {
                         return index;
                     }
                 } else {
-                    Map<String, Integer> map = calendar.getDisplayNames(field,
-                                                                        Calendar.ALL_STYLES,
-                                                                        locale);
+                    Map<String, Integer> map = getDisplayNamesMap(field, locale);
                     if ((index = matchString(text, start, field, map, calb)) > 0) {
                         return index;
                     }
                 }
                 break parsing;

@@ -1938,24 +1948,22 @@
 
                 if (useDateFormatSymbols) {
                     // count >= 3 // i.e., MMM or MMMM
                     // Want to be able to parse both short and long forms.
                     // Try count == 4 first:
-                    int newStart = 0;
+                    int newStart;
                     if ((newStart = matchString(text, start, Calendar.MONTH,
                                                 formatData.getMonths(), calb)) > 0) {
                         return newStart;
                     }
                     // count == 4 failed, now try count == 3
                     if ((index = matchString(text, start, Calendar.MONTH,
                                              formatData.getShortMonths(), calb)) > 0) {
                         return index;
                     }
                 } else {
-                    Map<String, Integer> map = calendar.getDisplayNames(field,
-                                                                        Calendar.ALL_STYLES,
-                                                                        locale);
+                    Map<String, Integer> map = getDisplayNamesMap(field, locale);
                     if ((index = matchString(text, start, field, map, calb)) > 0) {
                         return index;
                     }
                 }
                 break parsing;

@@ -1977,11 +1985,11 @@
             case PATTERN_DAY_OF_WEEK:  // 'E'
                 {
                     if (useDateFormatSymbols) {
                         // Want to be able to parse both short and long forms.
                         // Try count == 4 (DDDD) first:
-                        int newStart = 0;
+                        int newStart;
                         if ((newStart=matchString(text, start, Calendar.DAY_OF_WEEK,
                                                   formatData.getWeekdays(), calb)) > 0) {
                             return newStart;
                         }
                         // DDDD failed, now try DDD

@@ -2006,11 +2014,11 @@
                     if ((index = matchString(text, start, Calendar.AM_PM,
                                              formatData.getAmPmStrings(), calb)) > 0) {
                         return index;
                     }
                 } else {
-                    Map<String,Integer> map = calendar.getDisplayNames(field, Calendar.ALL_STYLES, locale);
+                    Map<String,Integer> map = getDisplayNamesMap(field, locale);
                     if ((index = matchString(text, start, field, map, calb)) > 0) {
                         return index;
                     }
                 }
                 break parsing;

@@ -2096,11 +2104,11 @@
                 {
                     if ((text.length() - pos.index) <= 0) {
                         break parsing;
                     }
 
-                    int sign = 0;
+                    int sign;
                     char c = text.charAt(pos.index);
                     if (c == 'Z') {
                         calb.set(Calendar.ZONE_OFFSET, 0).set(Calendar.DST_OFFSET, 0);
                         return ++pos.index;
                     }

@@ -2338,10 +2346,25 @@
         SimpleDateFormat that = (SimpleDateFormat) obj;
         return (pattern.equals(that.pattern)
                 && formatData.equals(that.formatData));
     }
 
+    private static final int[] REST_OF_STYLES = {
+        Calendar.SHORT_STANDALONE, Calendar.LONG_FORMAT, Calendar.LONG_STANDALONE,
+    };
+    private Map<String, Integer> getDisplayNamesMap(int field, Locale locale) {
+        Map<String, Integer> map = calendar.getDisplayNames(field, Calendar.SHORT_FORMAT, locale);
+        // Get all SHORT and LONG styles (avoid NARROW styles).
+        for (int style : REST_OF_STYLES) {
+            Map<String, Integer> m = calendar.getDisplayNames(field, style, locale);
+            if (m != null) {
+                map.putAll(m);
+            }
+        }
+        return map;
+    }
+
     /**
      * After reading an object from the input stream, the format
      * pattern in the object is verified.
      * <p>
      * @exception InvalidObjectException if the pattern is invalid