ICU-6104 fixed the inconsistent behavior of DateTimePatternGen between ICU4C and ICU4J.
X-SVN-Rev: 23156
This commit is contained in:
parent
7490278152
commit
307a3f8307
@ -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 ; i<UDATPG_FIELD_COUNT; ++i ) {
|
||||
if ((appendItemFormats[i] != other.appendItemFormats[i]) ||
|
||||
(appendItemNames[i] != other.appendItemNames[i]) ) {
|
||||
@ -264,10 +269,17 @@ DateTimePatternGenerator::~DateTimePatternGenerator() {
|
||||
|
||||
void
|
||||
DateTimePatternGenerator::initData(const Locale& locale) {
|
||||
const char *baseLangName = locale.getBaseName();
|
||||
chineseMonthHack = FALSE;
|
||||
for (int32_t i=0; i<3; i++) {
|
||||
if ( uprv_memcmp(baseLangName, CJKLangName[i], 2 ) == 0 ) {
|
||||
chineseMonthHack = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
fStatus = U_ZERO_ERROR;
|
||||
skipMatcher = NULL;
|
||||
fAvailableFormatKeyHash=NULL;
|
||||
|
||||
addCanonicalItems();
|
||||
addICUPatterns(locale, fStatus);
|
||||
if (U_FAILURE(fStatus)) {
|
||||
@ -564,7 +576,12 @@ DateTimePatternGenerator::getBestPattern(const UnicodeString& patternForm, UErro
|
||||
int32_t timeMask=(1<<UDATPG_FIELD_COUNT) - 1 - dateMask;
|
||||
|
||||
resultPattern.remove();
|
||||
dtMatcher->set(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;
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user