src/share/classes/java/text/SimpleDateFormat.java
Print this page
*** 46,61 ****
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.Map;
import java.util.SimpleTimeZone;
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;
/**
* <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.
--- 46,62 ----
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.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,1600 ****
--- 1592,1612 ----
* 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,1811 ****
*/
private int subParse(String text, int start, int patternCharIndex, int count,
boolean obeyCount, boolean[] ambiguousYear,
ParsePosition origPos,
boolean useFollowingMinusSignAsDelimiter, CalendarBuilder calb) {
! Number number = null;
int value = 0;
ParsePosition pos = new ParsePosition(0);
pos.index = start;
if (patternCharIndex == PATTERN_WEEK_YEAR && !calendar.isWeekDateSupported()) {
// use calendar year 'y' instead
--- 1813,1823 ----
*/
private int subParse(String text, int start, int patternCharIndex, int count,
boolean obeyCount, boolean[] ambiguousYear,
ParsePosition origPos,
boolean useFollowingMinusSignAsDelimiter, CalendarBuilder calb) {
! 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,1886 ****
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);
if ((index = matchString(text, start, field, map, calb)) > 0) {
return index;
}
}
break parsing;
--- 1886,1896 ----
if (useDateFormatSymbols) {
if ((index = matchString(text, start, Calendar.ERA, formatData.getEras(), calb)) > 0) {
return index;
}
} else {
! Map<String, Integer> map = getDisplayNamesMap(field, locale);
if ((index = matchString(text, start, field, map, calb)) > 0) {
return index;
}
}
break parsing;
*** 1938,1961 ****
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;
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);
if ((index = matchString(text, start, field, map, calb)) > 0) {
return index;
}
}
break parsing;
--- 1948,1969 ----
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;
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 = getDisplayNamesMap(field, locale);
if ((index = matchString(text, start, field, map, calb)) > 0) {
return index;
}
}
break parsing;
*** 1977,1987 ****
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;
if ((newStart=matchString(text, start, Calendar.DAY_OF_WEEK,
formatData.getWeekdays(), calb)) > 0) {
return newStart;
}
// DDDD failed, now try DDD
--- 1985,1995 ----
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;
if ((newStart=matchString(text, start, Calendar.DAY_OF_WEEK,
formatData.getWeekdays(), calb)) > 0) {
return newStart;
}
// DDDD failed, now try DDD
*** 2006,2016 ****
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);
if ((index = matchString(text, start, field, map, calb)) > 0) {
return index;
}
}
break parsing;
--- 2014,2024 ----
if ((index = matchString(text, start, Calendar.AM_PM,
formatData.getAmPmStrings(), calb)) > 0) {
return index;
}
} else {
! Map<String,Integer> map = getDisplayNamesMap(field, locale);
if ((index = matchString(text, start, field, map, calb)) > 0) {
return index;
}
}
break parsing;
*** 2096,2106 ****
{
if ((text.length() - pos.index) <= 0) {
break parsing;
}
! int sign = 0;
char c = text.charAt(pos.index);
if (c == 'Z') {
calb.set(Calendar.ZONE_OFFSET, 0).set(Calendar.DST_OFFSET, 0);
return ++pos.index;
}
--- 2104,2114 ----
{
if ((text.length() - pos.index) <= 0) {
break parsing;
}
! 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,2347 ****
--- 2346,2370 ----
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