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];
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;
}
}
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
int32_t type[UDATPG_FIELD_COUNT];
SkeletonFields original;
SkeletonFields baseOriginal;
+ UBool addedDefaultDayPeriod;
PtnSkeleton();
PtnSkeleton(const PtnSkeleton& other);
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}");
}
// ======== 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;
return;
}
UChar newChar;
- int32_t i;
for (i=0; i<10; ++i) {
UnicodeString randomSkeleton;
int32_t len = rand() % 20;
}
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);
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
@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;
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();
@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) {
Arrays.fill(type, NONE);
original.clear();
baseOriginal.clear();
+ addedDefaultDayPeriod = false;
fp.set(pattern);
for (Object obj : fp.getItems()) {
original.populate(DAYPERIOD, (char)row[0], row[3]);
baseOriginal.populate(DAYPERIOD, (char)row[0], row[3]);
type[DAYPERIOD] = row[2];
+ addedDefaultDayPeriod = true;
break;
}
}
// 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 = {
@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 " +