ICU-9256 For he@calendar=hebrew, offset the years within the current millenium down to 1-999
X-SVN-Rev: 32236
This commit is contained in:
parent
2f41905b0b
commit
00b9ba863a
@ -204,6 +204,12 @@ static const int32_t gFieldRangeBias[] = {
|
||||
-1, // 'U' - UDAT_YEAR_NAME_FIELD
|
||||
};
|
||||
|
||||
// When calendar uses hebr numbering (i.e. he@calendar=hebrew),
|
||||
// offset the years within the current millenium down to 1-999
|
||||
static const int32_t HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000;
|
||||
static const int32_t HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000;
|
||||
|
||||
|
||||
static UMTX LOCK;
|
||||
|
||||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleDateFormat)
|
||||
@ -1223,6 +1229,8 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
|
||||
}
|
||||
|
||||
currentNumberFormat = getNumberFormatByIndex(patternCharIndex);
|
||||
UnicodeString hebr("hebr", 4, US_INV);
|
||||
|
||||
switch (patternCharIndex) {
|
||||
|
||||
// for any "G" symbol, write out the appropriate era string
|
||||
@ -1262,6 +1270,9 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
|
||||
//AD 12345 12345 45 12345 12345 12345
|
||||
case UDAT_YEAR_FIELD:
|
||||
case UDAT_YEAR_WOY_FIELD:
|
||||
if (fDateOverride.compare(hebr)==0 && value>HEBREW_CAL_CUR_MILLENIUM_START_YEAR && value<HEBREW_CAL_CUR_MILLENIUM_END_YEAR) {
|
||||
value-=HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
|
||||
}
|
||||
if(count == 2)
|
||||
zeroPaddingNumber(currentNumberFormat, appendTo, value, 2, 2);
|
||||
else
|
||||
@ -2343,6 +2354,7 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
|
||||
patternCharIndex = (UDateFormatField)(patternCharPtr - DateFormatSymbols::getPatternUChars());
|
||||
currentNumberFormat = getNumberFormatByIndex(patternCharIndex);
|
||||
UCalendarDateFields field = fgPatternIndexToCalendarField[patternCharIndex];
|
||||
UnicodeString hebr("hebr", 4, US_INV);
|
||||
|
||||
if (numericLeapMonthFormatter != NULL) {
|
||||
numericLeapMonthFormatter->setFormats((const Format **)¤tNumberFormat, 1);
|
||||
@ -2509,7 +2521,9 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
|
||||
// we made adjustments to place the 2-digit year in the proper
|
||||
// century, for parsed strings from "00" to "99". Any other string
|
||||
// is treated literally: "2250", "-1", "1", "002".
|
||||
if ((pos.getIndex() - start) == 2 && !isChineseCalendar
|
||||
if (fDateOverride.compare(hebr)==0 && value < 1000) {
|
||||
value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
|
||||
} else if ((pos.getIndex() - start) == 2 && !isChineseCalendar
|
||||
&& u_isdigit(text.charAt(start))
|
||||
&& u_isdigit(text.charAt(start+1)))
|
||||
{
|
||||
@ -2544,7 +2558,9 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
|
||||
|
||||
case UDAT_YEAR_WOY_FIELD:
|
||||
// Comment is the same as for UDAT_Year_FIELDs - look above
|
||||
if ((pos.getIndex() - start) == 2
|
||||
if (fDateOverride.compare(hebr)==0 && value < 1000) {
|
||||
value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR;
|
||||
} else if ((pos.getIndex() - start) == 2
|
||||
&& u_isdigit(text.charAt(start))
|
||||
&& u_isdigit(text.charAt(start+1))
|
||||
&& fHaveDefaultCentury )
|
||||
|
@ -86,9 +86,10 @@ void DateFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &nam
|
||||
TESTCASE(46,TestParsePosition);
|
||||
TESTCASE(47,TestMonthPatterns);
|
||||
TESTCASE(48,TestContext);
|
||||
TESTCASE(49,TestNonGregoFmtParse);
|
||||
/*
|
||||
TESTCASE(49,TestRelativeError);
|
||||
TESTCASE(50,TestRelativeOther);
|
||||
TESTCASE(50,TestRelativeError);
|
||||
TESTCASE(51,TestRelativeOther);
|
||||
*/
|
||||
default: name = ""; break;
|
||||
}
|
||||
@ -3896,6 +3897,86 @@ void DateFormatTest::TestContext()
|
||||
}
|
||||
}
|
||||
|
||||
// test item for a particular locale + calendar and date format
|
||||
typedef struct {
|
||||
int32_t year;
|
||||
int32_t month;
|
||||
int32_t day;
|
||||
int32_t hour;
|
||||
int32_t minute;
|
||||
UnicodeString formattedDate;
|
||||
} CalAndFmtTestItem;
|
||||
|
||||
// test item giving locale + calendar, date format, and CalAndFmtTestItems
|
||||
typedef struct {
|
||||
const char * locale; // with calendar
|
||||
DateFormat::EStyle style;
|
||||
const CalAndFmtTestItem *caftItems;
|
||||
} TestNonGregoItem;
|
||||
|
||||
void DateFormatTest::TestNonGregoFmtParse()
|
||||
{
|
||||
// test items for he@calendar=hebrew, long date format
|
||||
const CalAndFmtTestItem cafti_he_hebrew_long[] = {
|
||||
{ 4999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05D3\\u05F3\\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") },
|
||||
{ 5100, 0, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05E7\\u05F3") },
|
||||
{ 5774, 5, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05D0\\u05D3\\u05E8 \\u05D0\\u05F3 \\u05EA\\u05E9\\u05E2\\u05F4\\u05D3") },
|
||||
{ 5999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") },
|
||||
{ 6100, 0, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05D5\\u05F3\\u05E7\\u05F3") },
|
||||
{ 0, 0, 0, 0, 0, UnicodeString("") } // terminator
|
||||
};
|
||||
// overal test items
|
||||
const TestNonGregoItem items[] = {
|
||||
{ "he@calendar=hebrew", DateFormat::kLong, cafti_he_hebrew_long },
|
||||
{ NULL, DateFormat::kNone, NULL } // terminator
|
||||
};
|
||||
const TestNonGregoItem * itemPtr;
|
||||
for (itemPtr = items; itemPtr->locale != NULL; itemPtr++) {
|
||||
Locale locale = Locale::createFromName(itemPtr->locale);
|
||||
DateFormat * dfmt = DateFormat::createDateInstance(itemPtr->style, locale);
|
||||
if (dfmt == NULL) {
|
||||
dataerrln("DateFormat::createDateInstance fails for locale %s", itemPtr->locale);
|
||||
} else {
|
||||
Calendar * cal = (dfmt->getCalendar())->clone();
|
||||
if (cal == NULL) {
|
||||
dataerrln("(DateFormat::getCalendar)->clone() fails for locale %s", itemPtr->locale);
|
||||
} else {
|
||||
const CalAndFmtTestItem * caftItemPtr;
|
||||
for (caftItemPtr = itemPtr->caftItems; caftItemPtr->year != 0; caftItemPtr++) {
|
||||
cal->clear();
|
||||
cal->set(UCAL_YEAR, caftItemPtr->year);
|
||||
cal->set(UCAL_MONTH, caftItemPtr->month);
|
||||
cal->set(UCAL_DATE, caftItemPtr->day);
|
||||
cal->set(UCAL_HOUR_OF_DAY, caftItemPtr->hour);
|
||||
cal->set(UCAL_MINUTE, caftItemPtr->minute);
|
||||
UnicodeString result;
|
||||
FieldPosition fpos(0);
|
||||
dfmt->format(*cal, result, fpos);
|
||||
if ( result.compare(caftItemPtr->formattedDate) != 0 ) {
|
||||
errln( UnicodeString("FAIL: date format for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
|
||||
", expected \"" + caftItemPtr->formattedDate + "\", got \"" + result + "\"");
|
||||
} else {
|
||||
// formatted OK, try parse
|
||||
ParsePosition ppos(0);
|
||||
dfmt->parse(result, *cal, ppos);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
int32_t year = cal->get(UCAL_YEAR, status);
|
||||
int32_t month = cal->get(UCAL_MONTH, status);
|
||||
int32_t day = cal->get(UCAL_DATE, status);
|
||||
if ( U_FAILURE(status) || ppos.getIndex() < result.length() || year != caftItemPtr->year || month != caftItemPtr->month || day != caftItemPtr->day ) {
|
||||
errln( UnicodeString("FAIL: date parse for locale ") + UnicodeString(itemPtr->locale) + ", style " + itemPtr->style +
|
||||
", string \"" + result + "\", expected " + caftItemPtr->year +"-"+caftItemPtr->month+"-"+caftItemPtr->day + ", got pos " +
|
||||
ppos.getIndex() + " " + year +"-"+month+"-"+day + " status " + UnicodeString(u_errorName(status)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
delete cal;
|
||||
}
|
||||
delete dfmt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
||||
//eof
|
||||
|
@ -179,6 +179,8 @@ public: // package
|
||||
|
||||
void TestContext(void);
|
||||
|
||||
void TestNonGregoFmtParse(void);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Test host-specific formatting.
|
||||
|
Loading…
Reference in New Issue
Block a user