diff --git a/icu4c/source/i18n/dtptngen.cpp b/icu4c/source/i18n/dtptngen.cpp index e67018143c..cd06c29400 100644 --- a/icu4c/source/i18n/dtptngen.cpp +++ b/icu4c/source/i18n/dtptngen.cpp @@ -1,6 +1,6 @@ /* ******************************************************************************* -* Copyright (C) 2007, International Business Machines Corporation and +* Copyright (C) 2008, International Business Machines Corporation and * others. All Rights Reserved. ******************************************************************************* * @@ -119,6 +119,8 @@ static const char* Resource_Fields[] = { "day", "dayperiod", "era", "hour", "minute", "month", "second", "week", "weekday", "year", "zone", "quarter" }; +static const char* CJKLangName[] = { "zh", "ja", "ko" }; // for ChineseMonthHack + // For appendItems static const UChar UDATPG_ItemFormat[]= {0x7B, 0x30, 0x7D, 0x20, 0x251C, 0x7B, 0x32, 0x7D, 0x3A, 0x20, 0x7B, 0x31, 0x7D, 0x2524, 0}; // {0} \u251C{2}: {1}\u2524 @@ -157,6 +159,7 @@ DateTimePatternGenerator::DateTimePatternGenerator(UErrorCode &status) : UObject fStatus = U_ZERO_ERROR; skipMatcher = NULL; fAvailableFormatKeyHash=NULL; + chineseMonthHack = FALSE; fp = new FormatParser(); dtMatcher = new DateTimeMatcher(); distanceInfo = new DistanceInfo(); @@ -201,6 +204,7 @@ DateTimePatternGenerator::operator=(const DateTimePatternGenerator& other) { *distanceInfo = *(other.distanceInfo); dateTimeFormat = other.dateTimeFormat; decimal = other.decimal; + chineseMonthHack = other.chineseMonthHack; // NUL-terminate for the C API. dateTimeFormat.getTerminatedBuffer(); decimal.getTerminatedBuffer(); @@ -230,7 +234,8 @@ DateTimePatternGenerator::operator==(const DateTimePatternGenerator& other) cons return TRUE; } if ((pLocale==other.pLocale) && (patternMap->equals(*other.patternMap)) && - (dateTimeFormat==other.dateTimeFormat) && (decimal==other.decimal)) { + (dateTimeFormat==other.dateTimeFormat) && (decimal==other.decimal) && + (chineseMonthHack == other.chineseMonthHack)) { for ( int32_t i=0 ; iset(patternForm, fp); + if ( chineseMonthHack ) { + dtMatcher->set(getCJKPattern(patternForm), fp); + } + else { + dtMatcher->set(patternForm, fp); + } bestPattern=getBestRaw(*dtMatcher, -1, distanceInfo); if ( distanceInfo->missingFieldMask==0 && distanceInfo->extraFieldMask==0 ) { resultPattern = adjustFieldTypes(*bestPattern, FALSE); @@ -981,6 +998,31 @@ DateTimePatternGenerator::clone() const { return new DateTimePatternGenerator(*this); } +// If the pattern contains more than 3 'M', replace with "MM" +UnicodeString +DateTimePatternGenerator::getCJKPattern(const UnicodeString& origPattern) { + UnicodeString result = UnicodeString(origPattern); + int32_t start, count; + + start=0; + if ((start < result.length()) && + ((start = result.indexOf(CAP_M, start)) >=0 )) { + count=1; + while ( result.charAt(start+count) == CAP_M ) { + if ( start+count++ >= result.length() ) { + break; + } + } + if ( count >=3 ) { + UChar sMM[3] = { CAP_M, CAP_M, 0 }; + UnicodeString shortMM = UnicodeString(sMM); + result = result.replace(start, count, shortMM); + } + start+=count; + } + return result; +} + PatternMap::PatternMap() { for (int32_t i=0; i < MAX_PATTERN_ENTRIES; ++i ) { boot[i]=NULL; diff --git a/icu4c/source/i18n/unicode/dtptngen.h b/icu4c/source/i18n/unicode/dtptngen.h index 09f6b84590..c1eedd551f 100644 --- a/icu4c/source/i18n/unicode/dtptngen.h +++ b/icu4c/source/i18n/unicode/dtptngen.h @@ -387,6 +387,7 @@ private: UnicodeString hackPattern; UErrorCode fStatus; UnicodeString emptyString; + UBool chineseMonthHack; void initData(const Locale &locale); void addCanonicalItems(); @@ -396,6 +397,7 @@ private: void initHashtable(UErrorCode& status); void setDateTimeFromCalendar(const Locale& locale, UErrorCode& status); void setDecimalSymbols(const Locale& locale, UErrorCode& status); + UnicodeString getCJKPattern(const UnicodeString& patternForm); UDateTimePatternField getAppendFormatNumber(const char* field) const; UDateTimePatternField getAppendNameNumber(const char* field) const; void getAppendName(UDateTimePatternField field, UnicodeString& value); diff --git a/icu4c/source/test/intltest/dtptngts.cpp b/icu4c/source/test/intltest/dtptngts.cpp index 5da0a34f1f..e78cffc2fb 100644 --- a/icu4c/source/test/intltest/dtptngts.cpp +++ b/icu4c/source/test/intltest/dtptngts.cpp @@ -1,6 +1,6 @@ /******************************************************************** * COPYRIGHT: - * Copyright (c) 2007, International Business Machines Corporation and + * Copyright (c) 2008, International Business Machines Corporation and * others. All Rights Reserved. ********************************************************************/ @@ -72,11 +72,11 @@ void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/) UnicodeString("23:58"), UnicodeString("58:59"), UnicodeString("1999-1"), // zh_Hans_CN - UnicodeString("1999 1"), - CharsToUnicodeString("1999\\u5E741\\u670813\\u65E5"), + UnicodeString("1999-01"), CharsToUnicodeString("1999\\u5E741\\u670813\\u65E5"), + CharsToUnicodeString("1999\\u5E7401\\u670813\\u65E5"), UnicodeString("1-13"), - UnicodeString("1 13"), + UnicodeString("01-13"), CharsToUnicodeString("1999 Q1"), CharsToUnicodeString("\\u4E0B\\u534811:58"), CharsToUnicodeString("23:58"), @@ -340,6 +340,57 @@ void IntlTestDateTimePatternGeneratorAPI::testAPI(/*char *par*/) delete zone; delete gen; + { + // Trac# 6104 + status = U_ZERO_ERROR; + pattern = UnicodeString("YYYYMMM"); + UnicodeString expR = UnicodeString("1999-01"); + Locale loc("ja"); + UDate testDate1= LocaleTest::date(99, 0, 13, 23, 58, 59); + DateTimePatternGenerator *patGen=DateTimePatternGenerator::createInstance(loc, status); + if(U_FAILURE(status)) { + dataerrln("ERROR: Could not create DateTimePatternGenerator"); + return; + } + UnicodeString bPattern = patGen->getBestPattern(pattern, status); + UnicodeString rDate; + SimpleDateFormat sdf(bPattern, loc, status); + rDate.remove(); + rDate = sdf.format(testDate1, rDate); + + logln(UnicodeString(" ja locale with skeleton: YYYYMMM Best Pattern:") + bPattern); + logln(UnicodeString(" Formatted date:") + rDate); + + if ( expR!= rDate ) { + errln(UnicodeString("\nERROR: Test Japanese month hack Got: ") + rDate + + UnicodeString(" Expected: ") + expR ); + } + delete patGen; + } + { // Trac# 6104 + Locale loc("zh"); + UnicodeString expR = UnicodeString("1999-01"); + UDate testDate1= LocaleTest::date(99, 0, 13, 23, 58, 59); + DateTimePatternGenerator *patGen=DateTimePatternGenerator::createInstance(loc, status); + if(U_FAILURE(status)) { + dataerrln("ERROR: Could not create DateTimePatternGenerator"); + return; + } + UnicodeString bPattern = patGen->getBestPattern(pattern, status); + UnicodeString rDate; + SimpleDateFormat sdf(bPattern, loc, status); + rDate.remove(); + rDate = sdf.format(testDate1, rDate); + + logln(UnicodeString(" zh locale with skeleton: YYYYMMM Best Pattern:") + bPattern); + logln(UnicodeString(" Formatted date:") + rDate); + if ( expR!= rDate ) { + errln(UnicodeString("\nERROR: Test Chinese month hack Got: ") + rDate + + UnicodeString(" Expected: ") + expR ); + } + delete patGen; + } + // ======= Test various skeletons. logln("Testing DateTimePatternGenerator with various skeleton");