ICU-10637 Format/parse using 'r', C part 2 (add tests, clean up islamic delta calculation)
X-SVN-Rev: 35355
This commit is contained in:
parent
7202567040
commit
5241507312
@ -106,7 +106,7 @@ U_CDECL_END
|
||||
*/
|
||||
|
||||
const char* fldName(UCalendarDateFields f) {
|
||||
return udbg_enumName(UDBG_UCalendarDateFields, (int32_t)f);
|
||||
return udbg_enumName(UDBG_UCalendarDateFields, (int32_t)f);
|
||||
}
|
||||
|
||||
#if UCAL_DEBUG_DUMP
|
||||
@ -740,7 +740,7 @@ fSkippedWallTime(UCAL_WALLTIME_LAST)
|
||||
clear();
|
||||
fZone = zone.clone();
|
||||
if (fZone == NULL) {
|
||||
success = U_MEMORY_ALLOCATION_ERROR;
|
||||
success = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
setWeekData(aLocale, NULL, success);
|
||||
}
|
||||
@ -1168,18 +1168,35 @@ Calendar::set(int32_t year, int32_t month, int32_t date, int32_t hour, int32_t m
|
||||
// per #10752 move the non-default implementation to subclasses
|
||||
// (default implementation will do no year adjustment)
|
||||
|
||||
static int32_t gregoYearFromIslamicStart(int32_t year) {
|
||||
// ad hoc conversion, improve under #10752
|
||||
// rough est for now, ok for grego 1846-2138,
|
||||
// otherwise occasionally wrong (for 3% of years)
|
||||
int cycle, offset, shift = 0;
|
||||
if (year >= 1397) {
|
||||
cycle = (year - 1397) / 67;
|
||||
offset = (year - 1397) % 67;
|
||||
shift = 2*cycle + ((offset >= 33)? 1: 0);
|
||||
} else {
|
||||
cycle = (year - 1396) / 67 - 1;
|
||||
offset = -(year - 1396) % 67;
|
||||
shift = 2*cycle + ((offset <= 33)? 1: 0);
|
||||
}
|
||||
return year + 579 - shift;
|
||||
}
|
||||
|
||||
int32_t Calendar::getRelatedYear(UErrorCode &status) const
|
||||
{
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
int32_t year = get(UCAL_EXTENDED_YEAR, status);
|
||||
int32_t year = get(UCAL_EXTENDED_YEAR, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return 0;
|
||||
}
|
||||
// modify for calendar type
|
||||
ECalType type = getCalendarType(getType());
|
||||
switch (type) {
|
||||
ECalType type = getCalendarType(getType());
|
||||
switch (type) {
|
||||
case CALTYPE_PERSIAN:
|
||||
year += 622; break;
|
||||
case CALTYPE_HEBREW:
|
||||
@ -1201,21 +1218,7 @@ int32_t Calendar::getRelatedYear(UErrorCode &status) const
|
||||
case CALTYPE_ISLAMIC_UMALQURA:
|
||||
case CALTYPE_ISLAMIC_TBLA:
|
||||
case CALTYPE_ISLAMIC_RGSA:
|
||||
// ad hoc conversion, improve under #10752
|
||||
{
|
||||
int cycle, offset, shift = 0;
|
||||
if (year >= 1397) {
|
||||
cycle = (year - 1397) / 67;
|
||||
offset = (year - 1397) % 67;
|
||||
shift = 2*cycle + ((offset >= 33)? 1: 0);
|
||||
} else {
|
||||
cycle = (year - 1396) / 67 - 1;
|
||||
offset = -(year - 1396) % 67;
|
||||
shift = 2*cycle + ((offset <= 33)? 1: 0);
|
||||
}
|
||||
year += 579 - shift;
|
||||
}
|
||||
break;
|
||||
year = gregoYearFromIslamicStart(year); break;
|
||||
default:
|
||||
// CALTYPE_GREGORIAN
|
||||
// CALTYPE_JAPANESE
|
||||
@ -1224,8 +1227,8 @@ int32_t Calendar::getRelatedYear(UErrorCode &status) const
|
||||
// CALTYPE_ISO8601
|
||||
// do nothing, EXTENDED_YEAR same as Gregorian
|
||||
break;
|
||||
}
|
||||
return year;
|
||||
}
|
||||
return year;
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -1233,11 +1236,27 @@ int32_t Calendar::getRelatedYear(UErrorCode &status) const
|
||||
// per #10752 move the non-default implementation to subclasses
|
||||
// (default implementation will do no year adjustment)
|
||||
|
||||
static int32_t firstIslamicStartYearFromGrego(int32_t year) {
|
||||
// ad hoc conversion, improve under #10752
|
||||
// rough est for now, ok for grego 1846-2138,
|
||||
// otherwise occasionally wrong (for 3% of years)
|
||||
int cycle, offset, shift = 0;
|
||||
if (year >= 1977) {
|
||||
cycle = (year - 1977) / 65;
|
||||
offset = (year - 1977) % 65;
|
||||
shift = 2*cycle + ((offset >= 32)? 1: 0);
|
||||
} else {
|
||||
cycle = (year - 1976) / 65 - 1;
|
||||
offset = -(year - 1976) % 65;
|
||||
shift = 2*cycle + ((offset <= 32)? 1: 0);
|
||||
}
|
||||
return year - 579 + shift;
|
||||
}
|
||||
void Calendar::setRelatedYear(int32_t year)
|
||||
{
|
||||
// modify for calendar type
|
||||
ECalType type = getCalendarType(getType());
|
||||
switch (type) {
|
||||
ECalType type = getCalendarType(getType());
|
||||
switch (type) {
|
||||
case CALTYPE_PERSIAN:
|
||||
year -= 622; break;
|
||||
case CALTYPE_HEBREW:
|
||||
@ -1259,9 +1278,7 @@ void Calendar::setRelatedYear(int32_t year)
|
||||
case CALTYPE_ISLAMIC_UMALQURA:
|
||||
case CALTYPE_ISLAMIC_TBLA:
|
||||
case CALTYPE_ISLAMIC_RGSA:
|
||||
// needs adjustment, will do under #10752
|
||||
year -= 578; // handles current year +/- a few
|
||||
break;
|
||||
year = firstIslamicStartYearFromGrego(year); break;
|
||||
default:
|
||||
// CALTYPE_GREGORIAN
|
||||
// CALTYPE_JAPANESE
|
||||
@ -1270,9 +1287,9 @@ void Calendar::setRelatedYear(int32_t year)
|
||||
// CALTYPE_ISO8601
|
||||
// do nothing, EXTENDED_YEAR same as Gregorian
|
||||
break;
|
||||
}
|
||||
// set extended year
|
||||
set(UCAL_EXTENDED_YEAR, year);
|
||||
}
|
||||
// set extended year
|
||||
set(UCAL_EXTENDED_YEAR, year);
|
||||
}
|
||||
|
||||
// -------------------------------------
|
||||
@ -2438,11 +2455,11 @@ Calendar::getDayOfWeekType(UCalendarDaysOfWeek dayOfWeek, UErrorCode &status) co
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
return UCAL_WEEKDAY;
|
||||
}
|
||||
if (fWeekendOnset == fWeekendCease) {
|
||||
if (dayOfWeek != fWeekendOnset)
|
||||
return UCAL_WEEKDAY;
|
||||
return (fWeekendOnsetMillis == 0) ? UCAL_WEEKEND : UCAL_WEEKEND_ONSET;
|
||||
}
|
||||
if (fWeekendOnset == fWeekendCease) {
|
||||
if (dayOfWeek != fWeekendOnset)
|
||||
return UCAL_WEEKDAY;
|
||||
return (fWeekendOnsetMillis == 0) ? UCAL_WEEKEND : UCAL_WEEKEND_ONSET;
|
||||
}
|
||||
if (fWeekendOnset < fWeekendCease) {
|
||||
if (dayOfWeek < fWeekendOnset || dayOfWeek > fWeekendCease) {
|
||||
return UCAL_WEEKDAY;
|
||||
|
@ -1630,26 +1630,28 @@ void DateFormatRegressionTest::TestT10619(void) {
|
||||
const TestDateFormatLeniencyItem * itemPtr;
|
||||
for (itemPtr = items; itemPtr->locale != NULL; itemPtr++ ) {
|
||||
|
||||
Locale locale = Locale::createFromName(itemPtr->locale);
|
||||
status = U_ZERO_ERROR;
|
||||
ParsePosition pos(0);
|
||||
SimpleDateFormat * sdmft = new SimpleDateFormat(itemPtr->pattern, locale, status);
|
||||
if (U_FAILURE(status)) {
|
||||
dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
|
||||
continue;
|
||||
}
|
||||
sdmft->setLenient(itemPtr->leniency);
|
||||
sdmft->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, itemPtr->leniency, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, itemPtr->leniency, status);
|
||||
/*UDate d = */sdmft->parse(itemPtr->parseString, pos);
|
||||
Locale locale = Locale::createFromName(itemPtr->locale);
|
||||
status = U_ZERO_ERROR;
|
||||
ParsePosition pos(0);
|
||||
SimpleDateFormat * sdmft = new SimpleDateFormat(itemPtr->pattern, locale, status);
|
||||
if (U_FAILURE(status)) {
|
||||
dataerrln("Unable to create SimpleDateFormat - %s", u_errorName(status));
|
||||
continue;
|
||||
}
|
||||
sdmft->setLenient(itemPtr->leniency);
|
||||
sdmft->setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, itemPtr->leniency, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, itemPtr->leniency, status);
|
||||
/*UDate d = */sdmft->parse(itemPtr->parseString, pos);
|
||||
|
||||
delete sdmft;
|
||||
if(pos.getErrorIndex() > -1)
|
||||
if(itemPtr->expectedResult.length() != 0) {
|
||||
errln("error: unexpected error - " + itemPtr->parseString + " - error index " + pos.getErrorIndex() + " - leniency " + itemPtr->leniency);
|
||||
continue;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
delete sdmft;
|
||||
if(pos.getErrorIndex() > -1) {
|
||||
if(itemPtr->expectedResult.length() != 0) {
|
||||
errln("error: unexpected error - " + itemPtr->parseString + " - error index " + pos.getErrorIndex() +
|
||||
" - leniency " + itemPtr->leniency);
|
||||
continue;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delete cal;
|
||||
|
@ -4052,6 +4052,7 @@ void DateFormatTest::TestContext()
|
||||
|
||||
// test item for a particular locale + calendar and date format
|
||||
typedef struct {
|
||||
int32_t era;
|
||||
int32_t year;
|
||||
int32_t month;
|
||||
int32_t day;
|
||||
@ -4064,6 +4065,7 @@ typedef struct {
|
||||
typedef struct {
|
||||
const char * locale; // with calendar
|
||||
DateFormat::EStyle style;
|
||||
UnicodeString pattern; // ignored unless style == DateFormat::kNone
|
||||
const CalAndFmtTestItem *caftItems;
|
||||
} TestNonGregoItem;
|
||||
|
||||
@ -4071,23 +4073,62 @@ 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
|
||||
{ 0, 4999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05D3\\u05F3\\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") },
|
||||
{ 0, 5100, 0, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05E7\\u05F3") },
|
||||
{ 0, 5774, 5, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05D0\\u05D3\\u05E8 \\u05D0\\u05F3 \\u05EA\\u05E9\\u05E2\\u05F4\\u05D3") },
|
||||
{ 0, 5999, 12, 29, 12, 0, CharsToUnicodeString("\\u05DB\\u05F4\\u05D8 \\u05D1\\u05D0\\u05DC\\u05D5\\u05DC \\u05EA\\u05EA\\u05E7\\u05E6\\u05F4\\u05D8") },
|
||||
{ 0, 6100, 0, 1, 12, 0, CharsToUnicodeString("\\u05D0\\u05F3 \\u05D1\\u05EA\\u05E9\\u05E8\\u05D9 \\u05D5\\u05F3\\u05E7\\u05F3") },
|
||||
{ 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator
|
||||
};
|
||||
const CalAndFmtTestItem cafti_zh_chinese_custU[] = {
|
||||
{ 78, 31, 0, 1, 12, 0, CharsToUnicodeString("2014\\u7532\\u5348\\u5E74\\u6B63\\u67081") },
|
||||
{ 77, 31, 0, 1, 12, 0, CharsToUnicodeString("1954\\u7532\\u5348\\u5E74\\u6B63\\u67081") },
|
||||
{ 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator
|
||||
};
|
||||
const CalAndFmtTestItem cafti_zh_chinese_custNoU[] = {
|
||||
{ 78, 31, 0, 1, 12, 0, CharsToUnicodeString("2014\\u5E74\\u6B63\\u67081") },
|
||||
{ 77, 31, 0, 1, 12, 0, CharsToUnicodeString("1954\\u5E74\\u6B63\\u67081") },
|
||||
{ 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator
|
||||
};
|
||||
const CalAndFmtTestItem cafti_ja_japanese_custGy[] = {
|
||||
{235, 26, 2, 5, 12, 0, CharsToUnicodeString("2014(\\u5E73\\u621026)\\u5E743\\u67085\\u65E5") },
|
||||
{234, 60, 2, 5, 12, 0, CharsToUnicodeString("1985(\\u662D\\u548C60)\\u5E743\\u67085\\u65E5") },
|
||||
{ 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator
|
||||
};
|
||||
const CalAndFmtTestItem cafti_ja_japanese_custNoGy[] = {
|
||||
{235, 26, 2, 5, 12, 0, CharsToUnicodeString("2014\\u5E743\\u67085\\u65E5") },
|
||||
{234, 60, 2, 5, 12, 0, CharsToUnicodeString("1985\\u5E743\\u67085\\u65E5") },
|
||||
{ 0, 0, 0, 0, 0, 0, UnicodeString("") } // terminator
|
||||
};
|
||||
const CalAndFmtTestItem cafti_en_islamic_cust[] = {
|
||||
{ 0, 1384, 0, 1, 12, 0, UnicodeString("1 Muh. 1384 AH, 1964") },
|
||||
{ 0, 1436, 0, 1, 12, 0, UnicodeString("1 Muh. 1436 AH, 2014") },
|
||||
{ 0, 1487, 0, 1, 12, 0, UnicodeString("1 Muh. 1487 AH, 2064") },
|
||||
{ 0, 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
|
||||
{ "he@calendar=hebrew", DateFormat::kLong, UnicodeString(""), cafti_he_hebrew_long },
|
||||
{ "zh@calendar=chinese", DateFormat::kNone, CharsToUnicodeString("rU\\u5E74MMMd"), cafti_zh_chinese_custU },
|
||||
{ "zh@calendar=chinese", DateFormat::kNone, CharsToUnicodeString("r\\u5E74MMMd"), cafti_zh_chinese_custNoU },
|
||||
{ "ja@calendar=japanese", DateFormat::kNone, CharsToUnicodeString("r(Gy)\\u5E74M\\u6708d\\u65E5"), cafti_ja_japanese_custGy },
|
||||
{ "ja@calendar=japanese", DateFormat::kNone, CharsToUnicodeString("r\\u5E74M\\u6708d\\u65E5"), cafti_ja_japanese_custNoGy },
|
||||
{ "en@calendar=islamic", DateFormat::kNone, UnicodeString("d MMM y G, r"), cafti_en_islamic_cust },
|
||||
{ NULL, DateFormat::kNone, UnicodeString(""), 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) {
|
||||
DateFormat * dfmt = NULL;
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
if (itemPtr->style != DateFormat::kNone) {
|
||||
dfmt = DateFormat::createDateInstance(itemPtr->style, locale);
|
||||
} else {
|
||||
dfmt = new SimpleDateFormat(itemPtr->pattern, locale, status);
|
||||
}
|
||||
if (U_FAILURE(status)) {
|
||||
dataerrln("new SimpleDateFormat fails for locale %s", itemPtr->locale);
|
||||
} else if (dfmt == NULL) {
|
||||
dataerrln("DateFormat::createDateInstance fails for locale %s", itemPtr->locale);
|
||||
} else {
|
||||
Calendar * cal = (dfmt->getCalendar())->clone();
|
||||
@ -4097,6 +4138,7 @@ void DateFormatTest::TestNonGregoFmtParse()
|
||||
const CalAndFmtTestItem * caftItemPtr;
|
||||
for (caftItemPtr = itemPtr->caftItems; caftItemPtr->year != 0; caftItemPtr++) {
|
||||
cal->clear();
|
||||
cal->set(UCAL_ERA, caftItemPtr->era);
|
||||
cal->set(UCAL_YEAR, caftItemPtr->year);
|
||||
cal->set(UCAL_MONTH, caftItemPtr->month);
|
||||
cal->set(UCAL_DATE, caftItemPtr->day);
|
||||
@ -4112,13 +4154,16 @@ void DateFormatTest::TestNonGregoFmtParse()
|
||||
// formatted OK, try parse
|
||||
ParsePosition ppos(0);
|
||||
dfmt->parse(result, *cal, ppos);
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
status = U_ZERO_ERROR;
|
||||
int32_t era = cal->get(UCAL_ERA, status);
|
||||
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 " +
|
||||
if ( U_FAILURE(status) || ppos.getIndex() < result.length() || era != caftItemPtr->era ||
|
||||
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->era +":"+caftItemPtr->year +"-"+caftItemPtr->month+"-"+caftItemPtr->day + ", got pos " +
|
||||
ppos.getIndex() + " " + year +"-"+month+"-"+day + " status " + UnicodeString(u_errorName(status)) );
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user