setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status);
setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
setBooleanAttribute(UDAT_PARSE_PARTIAL_MATCH, true, status);
+ setBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, true, status);
}
/* Define one-century window into which to disambiguate dates using
}
int32_t newStart = 0;
if (patternCharIndex==UDAT_MONTH_FIELD) {
- newStart = matchString(text, start, UCAL_MONTH, fSymbols->fMonths, fSymbols->fMonthsCount, wideMonthPat, cal); // try MMMM
- if (newStart > 0) {
- return newStart;
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
+ newStart = matchString(text, start, UCAL_MONTH, fSymbols->fMonths, fSymbols->fMonthsCount, wideMonthPat, cal); // try MMMM
+ if (newStart > 0) {
+ return newStart;
+ }
+ }
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
+ newStart = matchString(text, start, UCAL_MONTH, fSymbols->fShortMonths, fSymbols->fShortMonthsCount, shortMonthPat, cal); // try MMM
}
- newStart = matchString(text, start, UCAL_MONTH, fSymbols->fShortMonths, fSymbols->fShortMonthsCount, shortMonthPat, cal); // try MMM
} else {
- newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStandaloneMonths, fSymbols->fStandaloneMonthsCount, wideMonthPat, cal); // try LLLL
- if (newStart > 0) {
- return newStart;
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
+ newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStandaloneMonths, fSymbols->fStandaloneMonthsCount, wideMonthPat, cal); // try LLLL
+ if (newStart > 0) {
+ return newStart;
+ }
+ }
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
+ newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStandaloneShortMonths, fSymbols->fStandaloneShortMonthsCount, shortMonthPat, cal); // try LLL
}
- newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStandaloneShortMonths, fSymbols->fStandaloneShortMonthsCount, shortMonthPat, cal); // try LLL
}
if (newStart > 0 || !getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)) // currently we do not try to parse MMMMM/LLLLL: #8860
return newStart;
// Want to be able to parse both short and long forms.
// Try count == 4 (EEEE) wide first:
int32_t newStart = 0;
- if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
- fSymbols->fWeekdays, fSymbols->fWeekdaysCount, NULL, cal)) > 0)
- return newStart;
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ fSymbols->fWeekdays, fSymbols->fWeekdaysCount, NULL, cal)) > 0)
+ return newStart;
+ }
// EEEE wide failed, now try EEE abbreviated
- else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
- fSymbols->fShortWeekdays, fSymbols->fShortWeekdaysCount, NULL, cal)) > 0)
- return newStart;
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ fSymbols->fShortWeekdays, fSymbols->fShortWeekdaysCount, NULL, cal)) > 0)
+ return newStart;
+ }
// EEE abbreviated failed, now try EEEEEE short
- else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
- fSymbols->fShorterWeekdays, fSymbols->fShorterWeekdaysCount, NULL, cal)) > 0)
- return newStart;
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 6) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ fSymbols->fShorterWeekdays, fSymbols->fShorterWeekdaysCount, NULL, cal)) > 0)
+ return newStart;
+ }
// EEEEEE short failed, now try EEEEE narrow
- else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
- fSymbols->fNarrowWeekdays, fSymbols->fNarrowWeekdaysCount, NULL, cal)) > 0)
- return newStart;
- else if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status) || patternCharIndex == UDAT_DAY_OF_WEEK_FIELD)
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 5) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ fSymbols->fNarrowWeekdays, fSymbols->fNarrowWeekdaysCount, NULL, cal)) > 0)
+ return newStart;
+ }
+ if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status) || patternCharIndex == UDAT_DAY_OF_WEEK_FIELD)
return newStart;
// else we allowing parsing as number, below
}
// Want to be able to parse both short and long forms.
// Try count == 4 (cccc) first:
int32_t newStart = 0;
- if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
fSymbols->fStandaloneWeekdays, fSymbols->fStandaloneWeekdaysCount, NULL, cal)) > 0)
- return newStart;
- else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ return newStart;
+ }
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
fSymbols->fStandaloneShortWeekdays, fSymbols->fStandaloneShortWeekdaysCount, NULL, cal)) > 0)
- return newStart;
- else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ return newStart;
+ }
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 6) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
fSymbols->fStandaloneShorterWeekdays, fSymbols->fStandaloneShorterWeekdaysCount, NULL, cal)) > 0)
- return newStart;
- else if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
+ return newStart;
+ }
+ if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
return newStart;
// else we allowing parsing as number, below
}
// Try count == 4 first:
int32_t newStart = 0;
- if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
+ if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
fSymbols->fQuarters, fSymbols->fQuartersCount, cal)) > 0)
- return newStart;
- else if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
+ return newStart;
+ }
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
+ if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
fSymbols->fShortQuarters, fSymbols->fShortQuartersCount, cal)) > 0)
- return newStart;
- else if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
+ return newStart;
+ }
+ if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
return newStart;
// else we allowing parsing as number, below
+ if(!getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status))
+ return -start;
}
break;
// Try count == 4 first:
int32_t newStart = 0;
- if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
+ if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
fSymbols->fStandaloneQuarters, fSymbols->fStandaloneQuartersCount, cal)) > 0)
- return newStart;
- else if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
+ return newStart;
+ }
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
+ if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
fSymbols->fStandaloneShortQuarters, fSymbols->fStandaloneShortQuartersCount, cal)) > 0)
- return newStart;
- else if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
+ return newStart;
+ }
+ if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
return newStart;
// else we allowing parsing as number, below
+ if(!getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status))
+ return -start;
}
break;
*/
TESTCASE_AUTO(TestDotAndAtLeniency);
TESTCASE_AUTO(TestDateFormatLeniency);
+ TESTCASE_AUTO(TestParseMultiPatternMatch);
+
TESTCASE_AUTO_END;
}
UBool leniency;
UnicodeString parseString;
UnicodeString pattern;
- UnicodeString expectedResult; // null indicates expected error
+ UnicodeString expectedResult; // empty string indicates expected error
} TestDateFormatLeniencyItem;
void DateFormatTest::TestDateFormatLeniency() {
}
}
+
+typedef struct {
+ UBool leniency;
+ UnicodeString parseString;
+ UnicodeString pattern;
+ UnicodeString expectedResult; // empty string indicates expected error
+} TestMultiPatternMatchItem;
+
+void DateFormatTest::TestParseMultiPatternMatch() {
+ // For details see http://bugs.icu-project.org/trac/ticket/10336
+
+ const TestMultiPatternMatchItem items[] = {
+ // leniency parse String pattern expected result
+ {true, UnicodeString("2013-Sep 13"), UnicodeString("yyyy-MMM dd"), UnicodeString("2013-Sep 13")},
+ {true, UnicodeString("2013-September 14"), UnicodeString("yyyy-MMM dd"), UnicodeString("2013-Sep 14")},
+ {false, UnicodeString("2013-September 15"), UnicodeString("yyyy-MMM dd"), UnicodeString("")},
+ {false, UnicodeString("2013-September 16"), UnicodeString("yyyy-MMMM dd"), UnicodeString("2013-September 16")},
+ {true, UnicodeString("2013-Sep 17"), UnicodeString("yyyy-LLL dd"), UnicodeString("2013-Sep 17")},
+ {true, UnicodeString("2013-September 18"), UnicodeString("yyyy-LLL dd"), UnicodeString("2013-Sep 18")},
+ {false, UnicodeString("2013-September 19"), UnicodeString("yyyy-LLL dd"), UnicodeString("")},
+ {false, UnicodeString("2013-September 20"), UnicodeString("yyyy-LLLL dd"), UnicodeString("2013-September 20")},
+ {true, UnicodeString("2013 Sat Sep 21"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("2013 Sat Sep 21")},
+ {true, UnicodeString("2013 Sunday Sep 22"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("2013 Sun Sep 22")},
+ {false, UnicodeString("2013 Monday Sep 23"), UnicodeString("yyyy EEE MMM dd"), UnicodeString("")},
+ {false, UnicodeString("2013 Tuesday Sep 24"), UnicodeString("yyyy EEEE MMM dd"), UnicodeString("2013 Tuesday Sep 24")},
+ {true, UnicodeString("2013 Wed Sep 25"), UnicodeString("yyyy eee MMM dd"), UnicodeString("2013 Wed Sep 25")},
+ {true, UnicodeString("2013 Thu Sep 26"), UnicodeString("yyyy eee MMM dd"), UnicodeString("2013 Thu Sep 26")},
+ {false, UnicodeString("2013 Friday Sep 27"), UnicodeString("yyyy eee MMM dd"), UnicodeString("")},
+ {false, UnicodeString("2013 Saturday Sep 28"), UnicodeString("yyyy eeee MMM dd"), UnicodeString("2013 Saturday Sep 28")},
+ {true, UnicodeString("2013 Sun Sep 29"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("2013 Sun Sep 29")},
+ {true, UnicodeString("2013 Monday Sep 30"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("2013 Mon Sep 30")},
+ {false, UnicodeString("2013 Sunday Oct 13"), UnicodeString("yyyy ccc MMM dd"), UnicodeString("")},
+ {false, UnicodeString("2013 Monday Oct 14"), UnicodeString("yyyy cccc MMM dd"), UnicodeString("2013 Monday Oct 14")},
+ {true, UnicodeString("2013 Oct 15 Q4"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 15 Q4")},
+ {true, UnicodeString("2013 Oct 16 4th quarter"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 16 Q4")},
+ {false, UnicodeString("2013 Oct 17 4th quarter"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("")},
+ {false, UnicodeString("2013 Oct 18 Q4"), UnicodeString("yyyy MMM dd QQQ"), UnicodeString("2013 Oct 18 Q4")},
+ {true, UnicodeString("2013 Oct 19 Q4"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 19 4th quarter")},
+ {true, UnicodeString("2013 Oct 20 4th quarter"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 20 4th quarter")},
+ {false, UnicodeString("2013 Oct 21 Q4"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("")},
+ {false, UnicodeString("2013 Oct 22 4th quarter"), UnicodeString("yyyy MMM dd qqqq"), UnicodeString("2013 Oct 22 4th quarter")},
+ {false, NULL, NULL, NULL},
+ };
+
+ UErrorCode status = U_ZERO_ERROR;
+ LocalPointer<Calendar> cal(Calendar::createInstance(status));
+ if (U_FAILURE(status)) {
+ dataerrln(UnicodeString("FAIL: Unable to create Calendar for default timezone and locale."));
+ return;
+ }
+ const TestMultiPatternMatchItem * itemPtr;
+ DateFormat* sdmft = DateFormat::createDateInstance();
+ int32_t cnt = 0;
+ for (itemPtr = items; itemPtr->parseString != NULL; itemPtr++ ) {
+ status = U_ZERO_ERROR;
+ ParsePosition pos(0);
+ ((SimpleDateFormat*) sdmft)->applyPattern(itemPtr->pattern);
+ if (U_FAILURE(status)) {
+ dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
+ continue;
+ }
+ ++cnt;
+ sdmft->setLenient(itemPtr->leniency);
+ sdmft->setBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, itemPtr->leniency, status);
+ UDate d = sdmft->parse(itemPtr->parseString, pos);
+
+ if(itemPtr->expectedResult.length() == 0) {
+ if(pos.getErrorIndex() != -1) {
+ continue;
+ } else {
+ errln("error: unexpected parse success - " + itemPtr->parseString +
+ " - error index " + pos.getErrorIndex() +
+ " - leniency " + itemPtr->leniency);
+ continue;
+ }
+ }
+ if(pos.getErrorIndex() != -1) {
+ errln("error: parse error for string - " +itemPtr->parseString + " -- idx["+pos.getIndex()+"] errIdx["+pos.getErrorIndex()+"]");
+ continue;
+ }
+
+ UnicodeString formatResult("");
+ sdmft->format(d, formatResult);
+ if(formatResult.compare(itemPtr->expectedResult) != 0) {
+ errln("error: unexpected format result. expected[" + itemPtr->expectedResult + "] but result was[" + formatResult + "]");
+ } else {
+ logln("formatted results match! - " + formatResult);
+ }
+ }
+ delete sdmft;
+ }
+
#endif /* #if !UCONFIG_NO_FORMATTING */
//eof