mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-11 08:01:32 +00:00
ICU-13183 for compatibility, get(Base)Skeleton should not include 'a' added by DateTimeMatcher; add tests
X-SVN-Rev: 40133
This commit is contained in:
parent
6e8c655270
commit
e2e48c9dce
5 changed files with 90 additions and 47 deletions
|
@ -1917,6 +1917,10 @@ DateTimeMatcher::set(const UnicodeString& pattern, FormatParser* fp, PtnSkeleton
|
|||
for (i=0; i<UDATPG_FIELD_COUNT; ++i) {
|
||||
skeletonResult.type[i] = NONE;
|
||||
}
|
||||
skeletonResult.original.clear();
|
||||
skeletonResult.baseOriginal.clear();
|
||||
skeletonResult.addedDefaultDayPeriod = FALSE;
|
||||
|
||||
fp->set(pattern);
|
||||
for (i=0; i < fp->itemNumber; i++) {
|
||||
const UnicodeString& value = fp->items[i];
|
||||
|
@ -1955,6 +1959,7 @@ DateTimeMatcher::set(const UnicodeString& pattern, FormatParser* fp, PtnSkeleton
|
|||
skeletonResult.original.populate(UDATPG_DAYPERIOD_FIELD, dtTypes[i].patternChar, dtTypes[i].minLen);
|
||||
skeletonResult.baseOriginal.populate(UDATPG_DAYPERIOD_FIELD, dtTypes[i].patternChar, dtTypes[i].minLen);
|
||||
skeletonResult.type[UDATPG_DAYPERIOD_FIELD] = dtTypes[i].type;
|
||||
skeletonResult.addedDefaultDayPeriod = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -2387,13 +2392,27 @@ PtnSkeleton::equals(const PtnSkeleton& other) const {
|
|||
UnicodeString
|
||||
PtnSkeleton::getSkeleton() const {
|
||||
UnicodeString result;
|
||||
return original.appendTo(result);
|
||||
result = original.appendTo(result);
|
||||
int32_t pos;
|
||||
if (addedDefaultDayPeriod && (pos = result.indexOf(LOW_A)) >= 0) {
|
||||
// for backward compatibility: if DateTimeMatcher.set added a single 'a' that
|
||||
// was not in the provided skeleton, remove it here before returning skeleton.
|
||||
result.remove(pos, 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
UnicodeString
|
||||
PtnSkeleton::getBaseSkeleton() const {
|
||||
UnicodeString result;
|
||||
return baseOriginal.appendTo(result);
|
||||
result = baseOriginal.appendTo(result);
|
||||
int32_t pos;
|
||||
if (addedDefaultDayPeriod && (pos = result.indexOf(LOW_A)) >= 0) {
|
||||
// for backward compatibility: if DateTimeMatcher.set added a single 'a' that
|
||||
// was not in the provided skeleton, remove it here before returning skeleton.
|
||||
result.remove(pos, 1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
UChar
|
||||
|
|
|
@ -156,6 +156,7 @@ public:
|
|||
int32_t type[UDATPG_FIELD_COUNT];
|
||||
SkeletonFields original;
|
||||
SkeletonFields baseOriginal;
|
||||
UBool addedDefaultDayPeriod;
|
||||
|
||||
PtnSkeleton();
|
||||
PtnSkeleton(const PtnSkeleton& other);
|
||||
|
|
|
@ -356,6 +356,16 @@ void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/)
|
|||
UnicodeString("MMMMMd"),
|
||||
};
|
||||
|
||||
const char* testGetSkeletonAndBase[][3] = {
|
||||
// pattern skeleton baseSkeleton
|
||||
{ "dd-MMM", "MMMdd", "MMMd" },
|
||||
{ "dd/MMMM/yy", "yyMMMMdd", "yMMMMd" },
|
||||
{ "h", "h", "h" },
|
||||
{ "ah", "ah", "ah" },
|
||||
{ "aaaah", "aaaah", "aaaah" },
|
||||
{ "Bh", "Bh", "Bh" }
|
||||
};
|
||||
|
||||
UnicodeString newDecimal(" "); // space
|
||||
UnicodeString newAppendItemName("hrs.");
|
||||
UnicodeString newAppendItemFormat("{1} {0}");
|
||||
|
@ -511,34 +521,25 @@ void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/)
|
|||
}
|
||||
|
||||
// ======== Test getSkeleton and getBaseSkeleton
|
||||
status = U_ZERO_ERROR;
|
||||
pattern = UnicodeString("dd-MMM");
|
||||
UnicodeString expectedSkeleton = UnicodeString("MMMdd");
|
||||
UnicodeString expectedBaseSkeleton = UnicodeString("MMMd");
|
||||
UnicodeString retSkeleton = gen->getSkeleton(pattern, status);
|
||||
if(U_FAILURE(status) || retSkeleton != expectedSkeleton ) {
|
||||
errln("ERROR: Unexpected result from getSkeleton().\n");
|
||||
errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected: ") + expectedSkeleton );
|
||||
}
|
||||
retSkeleton = gen->getBaseSkeleton(pattern, status);
|
||||
if(U_FAILURE(status) || retSkeleton != expectedBaseSkeleton) {
|
||||
errln("ERROR: Unexpected result from getBaseSkeleton().\n");
|
||||
errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected:")+ expectedBaseSkeleton);
|
||||
|
||||
int32_t i, count = UPRV_LENGTHOF(testGetSkeletonAndBase);
|
||||
for (i = 0; i < count; i++) {
|
||||
status = U_ZERO_ERROR;
|
||||
pattern = UnicodeString(testGetSkeletonAndBase[i][0]);
|
||||
UnicodeString expectedSkeleton = UnicodeString(testGetSkeletonAndBase[i][1]);
|
||||
UnicodeString expectedBaseSkeleton = UnicodeString(testGetSkeletonAndBase[i][2]);
|
||||
UnicodeString retSkeleton = gen->getSkeleton(pattern, status);
|
||||
if(U_FAILURE(status) || retSkeleton != expectedSkeleton ) {
|
||||
errln("ERROR: Unexpected result from getSkeleton().\n");
|
||||
errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected: ") + expectedSkeleton );
|
||||
}
|
||||
retSkeleton = gen->getBaseSkeleton(pattern, status);
|
||||
if(U_FAILURE(status) || retSkeleton != expectedBaseSkeleton) {
|
||||
errln("ERROR: Unexpected result from getBaseSkeleton().\n");
|
||||
errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected:")+ expectedBaseSkeleton);
|
||||
}
|
||||
}
|
||||
|
||||
pattern = UnicodeString("dd/MMMM/yy");
|
||||
expectedSkeleton = UnicodeString("yyMMMMdd");
|
||||
expectedBaseSkeleton = UnicodeString("yMMMMd");
|
||||
retSkeleton = gen->getSkeleton(pattern, status);
|
||||
if(U_FAILURE(status) || retSkeleton != expectedSkeleton ) {
|
||||
errln("ERROR: Unexpected result from getSkeleton().\n");
|
||||
errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected: ") + expectedSkeleton );
|
||||
}
|
||||
retSkeleton = gen->getBaseSkeleton(pattern, status);
|
||||
if(U_FAILURE(status) || retSkeleton != expectedBaseSkeleton) {
|
||||
errln("ERROR: Unexpected result from getBaseSkeleton().\n");
|
||||
errln(UnicodeString(" Got: ") + retSkeleton + UnicodeString(" Expected:")+ expectedBaseSkeleton);
|
||||
}
|
||||
delete format;
|
||||
delete zone;
|
||||
delete gen;
|
||||
|
@ -711,7 +712,6 @@ void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/)
|
|||
return;
|
||||
}
|
||||
UChar newChar;
|
||||
int32_t i;
|
||||
for (i=0; i<10; ++i) {
|
||||
UnicodeString randomSkeleton;
|
||||
int32_t len = rand() % 20;
|
||||
|
@ -771,7 +771,7 @@ void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/)
|
|||
}
|
||||
UnicodeString returnPattern, *ptrSkeleton;
|
||||
ptrSkeletonEnum->reset(status);
|
||||
int32_t count=ptrSkeletonEnum->count(status);
|
||||
count=ptrSkeletonEnum->count(status);
|
||||
for (i=0; i<count; ++i) {
|
||||
ptrSkeleton = (UnicodeString *)ptrSkeletonEnum->snext(status);
|
||||
returnPattern = test->getPatternForSkeleton(*ptrSkeleton);
|
||||
|
@ -1137,14 +1137,14 @@ enum { kCharBufMax = 31 };
|
|||
void IntlTestDateTimePatternGeneratorAPI::testSkeletonsWithDayPeriods() {
|
||||
const char * patterns[] = {
|
||||
// since icu4c getEmptyInstance does not call addCanonicalItems (unlike J), set these here:
|
||||
"a", // should get skeleton a
|
||||
"H", // should get skeleton H
|
||||
"m", // should get skeleton m
|
||||
"s", // should get skeleton s
|
||||
"a", // should get internal skeleton a
|
||||
"H", // should get internalskeleton H
|
||||
"m", // should get internalskeleton m
|
||||
"s", // should get internalskeleton s
|
||||
// patterns from which to construct sample data for a locale
|
||||
//"H", // should get skeleton H
|
||||
"h a", // should get skeleton ah
|
||||
"B h", // should get skeleton Bh
|
||||
//"H", // should get internalskeleton H
|
||||
"h a", // should get internalskeleton ah
|
||||
"B h", // should get internalskeleton Bh
|
||||
};
|
||||
const char* testItems[][2] = {
|
||||
// sample requested skeletons and results
|
||||
|
|
|
@ -2353,19 +2353,30 @@ public class DateTimePatternGenerator implements Freezable<DateTimePatternGenera
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return appendTo(new StringBuilder()).toString();
|
||||
return appendTo(new StringBuilder(), false, false).toString();
|
||||
}
|
||||
|
||||
public String toString(boolean skipDayPeriod) {
|
||||
return appendTo(new StringBuilder(), false, skipDayPeriod).toString();
|
||||
}
|
||||
|
||||
public String toCanonicalString() {
|
||||
return appendTo(new StringBuilder(), true).toString();
|
||||
return appendTo(new StringBuilder(), true, false).toString();
|
||||
}
|
||||
|
||||
public String toCanonicalString(boolean skipDayPeriod) {
|
||||
return appendTo(new StringBuilder(), true, skipDayPeriod).toString();
|
||||
}
|
||||
|
||||
public StringBuilder appendTo(StringBuilder sb) {
|
||||
return appendTo(sb, false);
|
||||
return appendTo(sb, false, false);
|
||||
}
|
||||
|
||||
private StringBuilder appendTo(StringBuilder sb, boolean canonical) {
|
||||
private StringBuilder appendTo(StringBuilder sb, boolean canonical, boolean skipDayPeriod) {
|
||||
for (int i=0; i<TYPE_LIMIT; ++i) {
|
||||
if (skipDayPeriod && i == DAYPERIOD) {
|
||||
continue;
|
||||
}
|
||||
appendFieldTo(i, sb, canonical);
|
||||
}
|
||||
return sb;
|
||||
|
@ -2421,6 +2432,7 @@ public class DateTimePatternGenerator implements Freezable<DateTimePatternGenera
|
|||
private int[] type = new int[TYPE_LIMIT];
|
||||
private SkeletonFields original = new SkeletonFields();
|
||||
private SkeletonFields baseOriginal = new SkeletonFields();
|
||||
private boolean addedDefaultDayPeriod = false;
|
||||
|
||||
// just for testing; fix to make multi-threaded later
|
||||
// private static FormatParser fp = new FormatParser();
|
||||
|
@ -2431,18 +2443,27 @@ public class DateTimePatternGenerator implements Freezable<DateTimePatternGenera
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return original.toString();
|
||||
// for backward compatibility: addedDefaultDayPeriod true => DateTimeMatcher.set
|
||||
// added a single 'a' that was not in the provided skeleton, and it will be
|
||||
// removed when generating the skeleton to return.
|
||||
return original.toString(addedDefaultDayPeriod);
|
||||
}
|
||||
|
||||
// returns a string like toString but using the canonical character for most types,
|
||||
// e.g. M for M or L, E for E or c, y for y or U, etc. The hour field is canonicalized
|
||||
// to 'H' (for 24-hour types) or 'h' (for 12-hour types)
|
||||
public String toCanonicalString() {
|
||||
return original.toCanonicalString();
|
||||
// for backward compatibility: addedDefaultDayPeriod true => DateTimeMatcher.set
|
||||
// added a single 'a' that was not in the provided skeleton, and it will be
|
||||
// removed when generating the skeleton to return.
|
||||
return original.toCanonicalString(addedDefaultDayPeriod);
|
||||
}
|
||||
|
||||
String getBasePattern() {
|
||||
return baseOriginal.toString();
|
||||
// for backward compatibility: addedDefaultDayPeriod true => DateTimeMatcher.set
|
||||
// added a single 'a' that was not in the provided skeleton, and it will be
|
||||
// removed when generating the skeleton to return.
|
||||
return baseOriginal.toString(addedDefaultDayPeriod);
|
||||
}
|
||||
|
||||
DateTimeMatcher set(String pattern, FormatParser fp, boolean allowDuplicateFields) {
|
||||
|
@ -2450,6 +2471,7 @@ public class DateTimePatternGenerator implements Freezable<DateTimePatternGenera
|
|||
Arrays.fill(type, NONE);
|
||||
original.clear();
|
||||
baseOriginal.clear();
|
||||
addedDefaultDayPeriod = false;
|
||||
|
||||
fp.set(pattern);
|
||||
for (Object obj : fp.getItems()) {
|
||||
|
@ -2499,6 +2521,7 @@ public class DateTimePatternGenerator implements Freezable<DateTimePatternGenera
|
|||
original.populate(DAYPERIOD, (char)row[0], row[3]);
|
||||
baseOriginal.populate(DAYPERIOD, (char)row[0], row[3]);
|
||||
type[DAYPERIOD] = row[2];
|
||||
addedDefaultDayPeriod = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,7 +91,7 @@ public class DateTimeGeneratorTest extends TestFmwk {
|
|||
// sample data in a locale (base is not in locale, just here for test)
|
||||
// skel (base) pattern
|
||||
{ "aH", "H", "H" }, // should ignore a
|
||||
{ "h", "ah", "h a"},
|
||||
{ "h", "h", "h a"},
|
||||
{ "Bh", "Bh", "B h"},
|
||||
};
|
||||
String[][] testItems = {
|
||||
|
@ -871,8 +871,8 @@ public class DateTimeGeneratorTest extends TestFmwk {
|
|||
@Test
|
||||
public void TestGetSkeleton(){
|
||||
DateTimePatternGenerator dtpg = DateTimePatternGenerator.getInstance();
|
||||
String[] cases = {"MMDD","MMMDD","MMM-DD","DD/MMM","ddM","MMMMd"};
|
||||
String[] results = {"MMDD","MMMDD","MMMDD","MMMDD","Mdd","MMMMd"};
|
||||
String[] cases = {"MMDD","MMMDD","MMM-DD","DD/MMM","ddM","MMMMd","h","ah","aaaah","Bh"};
|
||||
String[] results = {"MMDD","MMMDD","MMMDD","MMMDD","Mdd","MMMMd","h","ah","aaaah","Bh"};
|
||||
for(int i=0; i<cases.length; i++){
|
||||
if(!dtpg.getSkeleton(cases[i]).equals(results[i])){
|
||||
errln("DateTimePatternGenerator.getSkeleton(String) did " +
|
||||
|
|
Loading…
Add table
Reference in a new issue