From: Michael Ow Date: Wed, 9 May 2012 21:00:40 +0000 (+0000) Subject: ICU-9242 Fix format parsing in ICU4C calendar code X-Git-Tag: milestone-59-0-1~3834 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=22dda186690ec2f0ce481607942a832452980b2a;p=icu ICU-9242 Fix format parsing in ICU4C calendar code X-SVN-Rev: 31805 --- diff --git a/icu4c/source/i18n/calendar.cpp b/icu4c/source/i18n/calendar.cpp index a5200899064..225ca2a5b96 100644 --- a/icu4c/source/i18n/calendar.cpp +++ b/icu4c/source/i18n/calendar.cpp @@ -2542,6 +2542,7 @@ UCalendarDateFields Calendar::newerField(UCalendarDateFields defaultField, UCale UCalendarDateFields Calendar::resolveFields(const UFieldResolutionTable* precedenceTable) { int32_t bestField = UCAL_FIELD_COUNT; + int32_t tempBestField; for (int32_t g=0; precedenceTable[g][0][0] != -1 && (bestField == UCAL_FIELD_COUNT); ++g) { int32_t bestStamp = kUnset; for (int32_t l=0; precedenceTable[g][l][0] != -1; ++l) { @@ -2559,14 +2560,26 @@ UCalendarDateFields Calendar::resolveFields(const UFieldResolutionTable* precede } // Record new maximum stamp & field no. if (lineStamp > bestStamp) { - bestStamp = lineStamp; - bestField = precedenceTable[g][l][0]; // First field refers to entire line + tempBestField = precedenceTable[g][l][0]; // First field refers to entire line + if (tempBestField >= kResolveRemap) { + tempBestField &= (kResolveRemap-1); + // This check is needed to resolve some issues with UCAL_YEAR precedence mapping + if (tempBestField != UCAL_DATE || (fStamp[UCAL_WEEK_OF_MONTH] < fStamp[tempBestField])) { + bestField = tempBestField; + } + } else { + bestField = tempBestField; + } + + if (bestField == tempBestField) { + bestStamp = lineStamp; + } } linesInGroup: ; } } - return (UCalendarDateFields)( (bestField>=kResolveRemap)?(bestField&(kResolveRemap-1)):bestField ); + return (UCalendarDateFields)bestField; } const UFieldResolutionTable Calendar::kDatePrecedence[] = diff --git a/icu4c/source/test/intltest/dtfmrgts.cpp b/icu4c/source/test/intltest/dtfmrgts.cpp index 1f12b65e28e..6ebce281636 100644 --- a/icu4c/source/test/intltest/dtfmrgts.cpp +++ b/icu4c/source/test/intltest/dtfmrgts.cpp @@ -56,6 +56,7 @@ DateFormatRegressionTest::runIndexedTest( int32_t index, UBool exec, const char* CASE(25,Test1684) CASE(26,Test5554) CASE(27,Test9237) + CASE(28,TestParsing) default: name = ""; break; } } @@ -1496,6 +1497,34 @@ void DateFormatRegressionTest::Test9237(void) } } +void DateFormatRegressionTest::TestParsing(void) { + UErrorCode status = U_ZERO_ERROR; + UnicodeString pattern("EEE-WW-MMMM-yyyy"); + UnicodeString text("mon-02-march-2011"); + int32_t expectedDay = 7; + + SimpleDateFormat format(pattern, status); + if (U_FAILURE(status)) { + dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status)); + return; + } + + Calendar *cal = new GregorianCalendar(status); + if (cal == NULL || U_FAILURE(status)) { + errln("Unable to create calendar - %s", u_errorName(status)); + return; + } + + ParsePosition pos(0); + format.parse(text, *cal, pos); + + if (cal->get(UCAL_DAY_OF_MONTH, status) != expectedDay) { + errln("Parsing failed: day of month should be '7' with pattern: \"" + pattern + "\" for text: \"" + text + "\""); + } + + delete cal; +} + #endif /* #if !UCONFIG_NO_FORMATTING */ //eof diff --git a/icu4c/source/test/intltest/dtfmrgts.h b/icu4c/source/test/intltest/dtfmrgts.h index be08953989c..21e2db015ce 100644 --- a/icu4c/source/test/intltest/dtfmrgts.h +++ b/icu4c/source/test/intltest/dtfmrgts.h @@ -52,6 +52,7 @@ public: void Test1684(void); void Test5554(void); void Test9237(void); + void TestParsing(void); }; #endif /* #if !UCONFIG_NO_FORMATTING */