ICU-9497 Add support for short(er) weekday names: format, parse, get/set symbols (J)

X-SVN-Rev: 33256
This commit is contained in:
Peter Edberg 2013-02-17 17:14:10 +00:00
parent ebbc5423ef
commit e0488a1ab8
4 changed files with 170 additions and 44 deletions

View File

@ -121,12 +121,18 @@ public class DateFormatSymbols implements Serializable, Cloneable {
*/
public static final int NARROW = 2;
/**
* {@icu} Constant for width; only supported for weekdays.
* @draft ICU 51
*/
public static final int SHORT = 3;
/**
* {@icu} Constant for width.
* @internal
* @deprecated This API is ICU internal only.
*/
public static final int DT_WIDTH_COUNT = 3;
public static final int DT_WIDTH_COUNT = 4;
/**
* {@icu} Somewhat temporary constant for leap month pattern type, adequate for Chinese calendar.
@ -372,8 +378,8 @@ public class DateFormatSymbols implements Serializable, Cloneable {
String standaloneNarrowMonths[] = null;
/**
* Weekday strings. For example: "Sunday", "Monday", etc. An array
* of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
* Format wide weekday strings, for example: "Sunday", "Monday", etc.
* An array of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
* The element <code>weekdays[0]</code> is ignored.
* @serial
@ -381,8 +387,9 @@ public class DateFormatSymbols implements Serializable, Cloneable {
String weekdays[] = null;
/**
* Short weekday strings. For example: "Sun", "Mon", etc. An array
* of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
* CLDR-style format abbreviated (not short) weekday strings,
* for example: "Sun", "Mon", etc.
* An array of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
* The element <code>shortWeekdays[0]</code> is ignored.
* @serial
@ -390,8 +397,18 @@ public class DateFormatSymbols implements Serializable, Cloneable {
String shortWeekdays[] = null;
/**
* Narrow weekday strings. For example: "S", "M", etc. An array
* of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
* CLDR-style format short weekday strings, for example: "Su", "Mo", etc.
* An array of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
* The element <code>shorterWeekdays[0]</code> is ignored.
* @serial
*/
// Note, serialization restore from pre-ICU-51 will leave this null.
String shorterWeekdays[] = null;
/**
* CLDR-style format narrow weekday strings, for example: "S", "M", etc.
* An array of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
* The element <code>narrowWeekdays[0]</code> is ignored.
* @serial
@ -399,8 +416,8 @@ public class DateFormatSymbols implements Serializable, Cloneable {
String narrowWeekdays[] = null;
/**
* Standalone weekday strings. For example: "Sunday", "Monday", etc. An array
* of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
* Standalone wide weekday strings. For example: "Sunday", "Monday", etc.
* An array of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
* The element <code>standaloneWeekdays[0]</code> is ignored.
* @serial
@ -408,14 +425,25 @@ public class DateFormatSymbols implements Serializable, Cloneable {
String standaloneWeekdays[] = null;
/**
* Standalone short weekday strings. For example: "Sun", "Mon", etc. An array
* of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
* CLDR-style standalone abbreviated (not short) weekday strings,
* for example: "Sun", "Mon", etc.
* An array of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
* The element <code>standaloneShortWeekdays[0]</code> is ignored.
* @serial
*/
String standaloneShortWeekdays[] = null;
/**
* CLDR-style standalone short weekday strings, for example: "Sun", "Mon", etc.
* An array of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
* The element <code>standaloneShorterWeekdays[0]</code> is ignored.
* @serial
*/
// Note, serialization restore from pre-ICU-51 will leave this null.
String standaloneShorterWeekdays[] = null;
/**
* Standalone narrow weekday strings. For example: "S", "M", etc. An array
* of 8 strings, indexed by <code>Calendar.SUNDAY</code>,
@ -657,6 +685,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
returnValue = months;
break;
case ABBREVIATED :
case SHORT : // no month data for this, defaults to ABBREVIATED
returnValue = shortMonths;
break;
case NARROW :
@ -670,6 +699,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
returnValue = standaloneMonths;
break;
case ABBREVIATED :
case SHORT : // no month data for this, defaults to ABBREVIATED
returnValue = standaloneShortMonths;
break;
case NARROW :
@ -711,6 +741,8 @@ public class DateFormatSymbols implements Serializable, Cloneable {
case NARROW :
narrowMonths = duplicate(newMonths);
break;
default : // HANDLE SHORT, etc.
break;
}
break;
case STANDALONE :
@ -724,6 +756,8 @@ public class DateFormatSymbols implements Serializable, Cloneable {
case NARROW :
standaloneNarrowMonths = duplicate(newMonths);
break;
default : // HANDLE SHORT, etc.
break;
}
break;
}
@ -748,7 +782,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
}
/**
* Returns weekday strings. For example: "Sunday", "Monday", etc.
* Returns wide weekday strings. For example: "Sunday", "Monday", etc.
* @return the weekday strings. Use <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc. to index the result array.
* @stable ICU 2.0
@ -763,7 +797,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* <code>Calendar.MONDAY</code>, etc. to index the result array.
* @param context Formatting context, either FORMAT or STANDALONE.
* @param width Width of strings to be returned, either
* WIDE, ABBREVIATED, or NARROW
* WIDE, ABBREVIATED, SHORT, or NARROW
* @stable ICU 3.4
*/
public String[] getWeekdays(int context, int width) {
@ -777,6 +811,9 @@ public class DateFormatSymbols implements Serializable, Cloneable {
case ABBREVIATED :
returnValue = shortWeekdays;
break;
case SHORT :
returnValue = (shorterWeekdays != null)? shorterWeekdays: shortWeekdays;
break;
case NARROW :
returnValue = narrowWeekdays;
break;
@ -790,6 +827,9 @@ public class DateFormatSymbols implements Serializable, Cloneable {
case ABBREVIATED :
returnValue = standaloneShortWeekdays;
break;
case SHORT :
returnValue = (standaloneShorterWeekdays != null)? standaloneShorterWeekdays: standaloneShortWeekdays;
break;
case NARROW :
returnValue = standaloneNarrowWeekdays;
break;
@ -804,7 +844,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
* @param newWeekdays The new weekday strings.
* @param context The formatting context, FORMAT or STANDALONE.
* @param width The width of the strings,
* either WIDE, ABBREVIATED, or NARROW.
* either WIDE, ABBREVIATED, SHORT, or NARROW.
* @stable ICU 3.8
*/
public void setWeekdays(String[] newWeekdays, int context, int width) {
@ -817,6 +857,9 @@ public class DateFormatSymbols implements Serializable, Cloneable {
case ABBREVIATED :
shortWeekdays = duplicate(newWeekdays);
break;
case SHORT :
shorterWeekdays = duplicate(newWeekdays);
break;
case NARROW :
narrowWeekdays = duplicate(newWeekdays);
break;
@ -830,6 +873,9 @@ public class DateFormatSymbols implements Serializable, Cloneable {
case ABBREVIATED :
standaloneShortWeekdays = duplicate(newWeekdays);
break;
case SHORT :
standaloneShorterWeekdays = duplicate(newWeekdays);
break;
case NARROW :
standaloneNarrowWeekdays = duplicate(newWeekdays);
break;
@ -839,7 +885,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
}
/**
* Sets weekday strings. For example: "Sunday", "Monday", etc.
* Sets wide weekday strings. For example: "Sunday", "Monday", etc.
* @param newWeekdays the new weekday strings. The array should
* be indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
@ -850,8 +896,10 @@ public class DateFormatSymbols implements Serializable, Cloneable {
}
/**
* Returns short weekday strings. For example: "Sun", "Mon", etc.
* @return the short weekday strings. Use <code>Calendar.SUNDAY</code>,
* Returns abbreviated weekday strings; for example: "Sun", "Mon", etc.
* (Note: the method name is misleading; it does not get the CLDR-style
* "short" weekday strings, e.g. "Su", "Mo", etc.)
* @return the abbreviated weekday strings. Use <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc. to index the result array.
* @stable ICU 2.0
*/
@ -860,14 +908,16 @@ public class DateFormatSymbols implements Serializable, Cloneable {
}
/**
* Sets short weekday strings. For example: "Sun", "Mon", etc.
* @param newShortWeekdays the new short weekday strings. The array should
* Sets abbreviated weekday strings; for example: "Sun", "Mon", etc.
* (Note: the method name is misleading; it does not set the CLDR-style
* "short" weekday strings, e.g. "Su", "Mo", etc.)
* @param newAbbrevWeekdays the new abbreviated weekday strings. The array should
* be indexed by <code>Calendar.SUNDAY</code>,
* <code>Calendar.MONDAY</code>, etc.
* @stable ICU 2.0
*/
public void setShortWeekdays(String[] newShortWeekdays) {
shortWeekdays = duplicate(newShortWeekdays);
public void setShortWeekdays(String[] newAbbrevWeekdays) {
shortWeekdays = duplicate(newAbbrevWeekdays);
}
/**
* {@icu} Returns quarter strings. For example: "1st Quarter", "2nd Quarter", etc.
@ -886,6 +936,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
returnValue = quarters;
break;
case ABBREVIATED :
case SHORT : // no quarter data for this, defaults to ABBREVIATED
returnValue = shortQuarters;
break;
case NARROW :
@ -900,6 +951,7 @@ public class DateFormatSymbols implements Serializable, Cloneable {
returnValue = standaloneQuarters;
break;
case ABBREVIATED :
case SHORT : // no quarter data for this, defaults to ABBREVIATED
returnValue = standaloneShortQuarters;
break;
case NARROW:
@ -932,6 +984,8 @@ public class DateFormatSymbols implements Serializable, Cloneable {
case NARROW :
//narrowQuarters = duplicate(newQuarters);
break;
default : // HANDLE SHORT, etc.
break;
}
break;
case STANDALONE :
@ -945,6 +999,8 @@ public class DateFormatSymbols implements Serializable, Cloneable {
case NARROW :
//standaloneNarrowQuarters = duplicate(newQuarters);
break;
default : // HANDLE SHORT, etc.
break;
}
break;
}
@ -1107,9 +1163,11 @@ public class DateFormatSymbols implements Serializable, Cloneable {
&& Utility.arrayEquals(standaloneNarrowMonths, that.standaloneNarrowMonths)
&& Utility.arrayEquals(weekdays, that.weekdays)
&& Utility.arrayEquals(shortWeekdays, that.shortWeekdays)
&& Utility.arrayEquals(shorterWeekdays, that.shorterWeekdays)
&& Utility.arrayEquals(narrowWeekdays, that.narrowWeekdays)
&& Utility.arrayEquals(standaloneWeekdays, that.standaloneWeekdays)
&& Utility.arrayEquals(standaloneShortWeekdays, that.standaloneShortWeekdays)
&& Utility.arrayEquals(standaloneShorterWeekdays, that.standaloneShorterWeekdays)
&& Utility.arrayEquals(standaloneNarrowWeekdays, that.standaloneNarrowWeekdays)
&& Utility.arrayEquals(ampms, that.ampms)
&& arrayOfArrayEquals(zoneStrings, that.zoneStrings)
@ -1175,9 +1233,11 @@ public class DateFormatSymbols implements Serializable, Cloneable {
this.standaloneNarrowMonths = dfs.standaloneNarrowMonths;
this.weekdays = dfs.weekdays;
this.shortWeekdays = dfs.shortWeekdays;
this.shorterWeekdays = dfs.shorterWeekdays;
this.narrowWeekdays = dfs.narrowWeekdays;
this.standaloneWeekdays = dfs.standaloneWeekdays;
this.standaloneShortWeekdays = dfs.standaloneShortWeekdays;
this.standaloneShorterWeekdays = dfs.standaloneShorterWeekdays;
this.standaloneNarrowWeekdays = dfs.standaloneNarrowWeekdays;
this.ampms = dfs.ampms;
this.shortQuarters = dfs.shortQuarters;
@ -1229,10 +1289,15 @@ public class DateFormatSymbols implements Serializable, Cloneable {
weekdays[0] = ""; // 1-based
System.arraycopy(lWeekdays, 0, weekdays, 1, lWeekdays.length);
String[] sWeekdays = calData.getStringArray("dayNames", "abbreviated");
String[] aWeekdays = calData.getStringArray("dayNames", "abbreviated");
shortWeekdays = new String[8];
shortWeekdays[0] = ""; // 1-based
System.arraycopy(sWeekdays, 0, shortWeekdays, 1, sWeekdays.length);
System.arraycopy(aWeekdays, 0, shortWeekdays, 1, aWeekdays.length);
String[] sWeekdays = calData.getStringArray("dayNames", "short");
shorterWeekdays = new String[8];
shorterWeekdays[0] = ""; // 1-based
System.arraycopy(sWeekdays, 0, shorterWeekdays, 1, sWeekdays.length);
String [] nWeekdays = null;
try {
@ -1250,17 +1315,23 @@ public class DateFormatSymbols implements Serializable, Cloneable {
narrowWeekdays[0] = ""; // 1-based
System.arraycopy(nWeekdays, 0, narrowWeekdays, 1, nWeekdays.length);
String [] saWeekdays = null;
saWeekdays = calData.getStringArray("dayNames", "stand-alone", "wide");
String [] swWeekdays = null;
swWeekdays = calData.getStringArray("dayNames", "stand-alone", "wide");
standaloneWeekdays = new String[8];
standaloneWeekdays[0] = ""; // 1-based
System.arraycopy(saWeekdays, 0, standaloneWeekdays, 1, saWeekdays.length);
System.arraycopy(swWeekdays, 0, standaloneWeekdays, 1, swWeekdays.length);
String [] ssWeekdays = null;
ssWeekdays = calData.getStringArray("dayNames", "stand-alone", "abbreviated");
String [] saWeekdays = null;
saWeekdays = calData.getStringArray("dayNames", "stand-alone", "abbreviated");
standaloneShortWeekdays = new String[8];
standaloneShortWeekdays[0] = ""; // 1-based
System.arraycopy(ssWeekdays, 0, standaloneShortWeekdays, 1, ssWeekdays.length);
System.arraycopy(saWeekdays, 0, standaloneShortWeekdays, 1, saWeekdays.length);
String [] ssWeekdays = null;
ssWeekdays = calData.getStringArray("dayNames", "stand-alone", "short");
standaloneShorterWeekdays = new String[8];
standaloneShorterWeekdays[0] = ""; // 1-based
System.arraycopy(ssWeekdays, 0, standaloneShorterWeekdays, 1, ssWeekdays.length);
String [] snWeekdays = null;
snWeekdays = calData.getStringArray("dayNames", "stand-alone", "narrow");

View File

@ -1108,6 +1108,9 @@ public class SimpleDateFormat extends DateFormat {
} else if (count == 4) {
safeAppend(formatData.weekdays, value, buf);
capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_FORMAT;
} else if (count == 6 && formatData.shorterWeekdays != null) {
safeAppend(formatData.shorterWeekdays, value, buf);
capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_FORMAT;
} else {// count <= 3, use abbreviated form if exists
safeAppend(formatData.shortWeekdays, value, buf);
capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_FORMAT;
@ -1242,6 +1245,9 @@ public class SimpleDateFormat extends DateFormat {
} else if (count == 4) {
safeAppend(formatData.standaloneWeekdays, value, buf);
capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_STANDALONE;
} else if (count == 6 && formatData.standaloneShorterWeekdays != null) {
safeAppend(formatData.standaloneShorterWeekdays, value, buf);
capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_STANDALONE;
} else { // count == 3
safeAppend(formatData.standaloneShortWeekdays, value, buf);
capContextUsageType = DateFormatSymbols.CapitalizationContextUsage.DAY_STANDALONE;
@ -2429,28 +2435,28 @@ public class SimpleDateFormat extends DateFormat {
cal.set(Calendar.MILLISECOND, value);
return pos.getIndex();
case 9: { // 'E' - DAY_OF_WEEK
// Want to be able to parse both short and long forms.
// Try count == 4 (EEEE) first:
int newStart = matchString(text, start, Calendar.DAY_OF_WEEK,
formatData.weekdays, null, cal);
// Want to be able to parse at least wide, abbrev, short forms.
int newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.weekdays, null, cal); // try EEEE wide
if (newStart > 0) {
return newStart;
} else { // EEEE failed, now try EEE
return matchString(text, start, Calendar.DAY_OF_WEEK,
formatData.shortWeekdays, null, cal);
} else if ((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.shortWeekdays, null, cal)) > 0) { // try EEE abbrev
return newStart;
} else if (formatData.shorterWeekdays != null) {
return matchString(text, start, Calendar.DAY_OF_WEEK, formatData.shorterWeekdays, null, cal); // try EEEEEE short
}
return newStart;
}
case 25: { // 'c' - STAND_ALONE_DAY_OF_WEEK
// Want to be able to parse both short and long forms.
// Try count == 4 (cccc) first:
int newStart = matchString(text, start, Calendar.DAY_OF_WEEK,
formatData.standaloneWeekdays, null, cal);
// Want to be able to parse at least wide, abbrev, short forms.
int newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.standaloneWeekdays, null, cal); // try cccc wide
if (newStart > 0) {
return newStart;
} else { // cccc failed, now try ccc
return matchString(text, start, Calendar.DAY_OF_WEEK,
formatData.standaloneShortWeekdays, null, cal);
} else if ((newStart = matchString(text, start, Calendar.DAY_OF_WEEK, formatData.standaloneShortWeekdays, null, cal)) > 0) { // try ccc abbrev
return newStart;
} else if (formatData.standaloneShorterWeekdays != null) {
return matchString(text, start, Calendar.DAY_OF_WEEK, formatData.standaloneShorterWeekdays, null, cal); // try cccccc short
}
return newStart;
}
case 14: // 'a' - AM_PM
return matchString(text, start, Calendar.AM_PM, formatData.ampms, null, cal);

View File

@ -2784,6 +2784,32 @@ public class DateFormatTest extends com.ibm.icu.dev.test.TestFmwk {
expect(CS_DATA, new Locale("cs", "", ""));
}
public void TestShortDays()
{
String EN_DATA[] = {
"yyyy MM dd HH:mm:ss",
"EEEEEE, MMM d y", "fp", "2013 01 13 0:00:00", "Su, Jan 13 2013", "2013 01 13 0:00:00",
"EEEEEE, MMM d y", "fp", "2013 01 16 0:00:00", "We, Jan 16 2013", "2013 01 16 0:00:00",
"EEEEEE d", "fp", "1970 01 17 0:00:00", "Sa 17", "1970 01 17 0:00:00",
"cccccc d", "fp", "1970 01 17 0:00:00", "Sa 17", "1970 01 17 0:00:00",
"cccccc", "fp", "1970 01 03 0:00:00", "Sa", "1970 01 03 0:00:00",
};
String SV_DATA[] = {
"yyyy MM dd HH:mm:ss",
"EEEEEE d MMM y", "fp", "2013 01 13 0:00:00", "s\u00F6 13 jan 2013", "2013 01 13 0:00:00",
"EEEEEE d MMM y", "fp", "2013 01 16 0:00:00", "on 16 jan 2013", "2013 01 16 0:00:00",
"EEEEEE d", "fp", "1970 01 17 0:00:00", "l\u00F6 17", "1970 01 17 0:00:00",
"cccccc d", "fp", "1970 01 17 0:00:00", "L\u00F6 17", "1970 01 17 0:00:00",
"cccccc", "fp", "1970 01 03 0:00:00", "L\u00F6", "1970 01 03 0:00:00",
};
expect(EN_DATA, new Locale("en", "", ""));
expect(SV_DATA, new Locale("sv", "", ""));
}
public void TestNarrowNames()
{
String EN_DATA[] = {

View File

@ -1,6 +1,6 @@
/*****************************************************************************************
*
* Copyright (C) 1996-2011, International Business Machines
* Copyright (C) 1996-2013, International Business Machines
* Corporation and others. All Rights Reserved.
**/
@ -101,6 +101,21 @@ public class IntlTestDateFormatSymbols extends com.ibm.icu.dev.test.TestFmwk
}
private boolean UnicodeStringsArePrefixes(String[] prefixArray, String[] baseArray){
if (prefixArray.length != baseArray.length) {
return false;
}
int i;
for (i = 0; i < baseArray.length; i++) {
if (!baseArray[i].startsWith(prefixArray[i])) {
errln("ERROR: Mismatch example, index " + i + ": expect prefix \"" + prefixArray[i] + "\" of base \"" + baseArray[i] + "\".");
return false;
}
}
return true;
}
// Test the API of DateFormatSymbols; primarily a simple get/set set.
public void TestSymbols()
{
@ -298,6 +313,10 @@ public class IntlTestDateFormatSymbols extends com.ibm.icu.dev.test.TestFmwk
}
final String[] abbrWeekdays = en.getWeekdays(DateFormatSymbols.FORMAT,DateFormatSymbols.ABBREVIATED);
final String[] shorterWeekdays = en.getWeekdays(DateFormatSymbols.FORMAT,DateFormatSymbols.SHORT);
if ( !UnicodeStringsArePrefixes(shorterWeekdays, abbrWeekdays) ) {
errln("ERROR: English format short weekday names don't match prefixes of format abbreviated names");
}
fr2.setWeekdays(abbrWeekdays,DateFormatSymbols.FORMAT,DateFormatSymbols.ABBREVIATED);
final String[] abbrWeekdays1 = fr2.getWeekdays(DateFormatSymbols.FORMAT,DateFormatSymbols.ABBREVIATED);
count = abbrWeekdays.length;
@ -343,6 +362,10 @@ public class IntlTestDateFormatSymbols extends com.ibm.icu.dev.test.TestFmwk
}
final String[] standaloneShortWeekdays = en.getWeekdays(DateFormatSymbols.STANDALONE,DateFormatSymbols.ABBREVIATED);
final String[] standaloneShorterWeekdays = en.getWeekdays(DateFormatSymbols.STANDALONE,DateFormatSymbols.SHORT);
if ( !UnicodeStringsArePrefixes(standaloneShorterWeekdays, standaloneShortWeekdays) ) {
errln("ERROR: English standalone short weekday names don't match prefixes of standalone abbreviated names");
}
fr.setWeekdays(standaloneShortWeekdays,DateFormatSymbols.STANDALONE,DateFormatSymbols.ABBREVIATED);
final String[] standaloneShortWeekdays1 = fr.getWeekdays(DateFormatSymbols.STANDALONE,DateFormatSymbols.ABBREVIATED);
count = standaloneShortWeekdays.length;