ICU-9226 Calendar add +year should always move forward in time; roll year should wrap for eras with real bounds, pin otherwise
X-SVN-Rev: 31966
This commit is contained in:
parent
1f3812e51e
commit
c63be1f302
@ -1600,6 +1600,45 @@ void Calendar::roll(UCalendarDateFields field, int32_t amount, UErrorCode& statu
|
||||
|
||||
case UCAL_YEAR:
|
||||
case UCAL_YEAR_WOY:
|
||||
{
|
||||
// * If era==0 and years go backwards in time, change sign of amount.
|
||||
// * Until we have new API per #9393, we temporarily hardcode knowledge of
|
||||
// which calendars have era 0 years that go backwards.
|
||||
UBool era0WithYearsThatGoBackwards = FALSE;
|
||||
int32_t era = get(UCAL_ERA, status);
|
||||
if (era == 0) {
|
||||
const char * calType = getType();
|
||||
if ( uprv_strcmp(calType,"gregorian")==0 || uprv_strcmp(calType,"roc")==0 || uprv_strcmp(calType,"coptic")==0 ) {
|
||||
amount = -amount;
|
||||
era0WithYearsThatGoBackwards = TRUE;
|
||||
}
|
||||
}
|
||||
int32_t newYear = internalGet(field) + amount;
|
||||
if (era > 0 || newYear >= 1) {
|
||||
int32_t maxYear = getActualMaximum(field, status);
|
||||
if (maxYear < 32768) {
|
||||
// this era has real bounds, roll should wrap years
|
||||
if (newYear < 1) {
|
||||
newYear = maxYear - ((-newYear) % maxYear);
|
||||
} else if (newYear > maxYear) {
|
||||
newYear = ((newYear - 1) % maxYear) + 1;
|
||||
}
|
||||
// else era is unbounded, just pin low year instead of wrapping
|
||||
} else if (newYear < 1) {
|
||||
newYear = 1;
|
||||
}
|
||||
// else we are in era 0 with newYear < 1;
|
||||
// calendars with years that go backwards must pin the year value at 0,
|
||||
// other calendars can have years < 0 in era 0
|
||||
} else if (era0WithYearsThatGoBackwards) {
|
||||
newYear = 1;
|
||||
}
|
||||
set(field, newYear);
|
||||
pinField(UCAL_MONTH,status);
|
||||
pinField(UCAL_DAY_OF_MONTH,status);
|
||||
return;
|
||||
}
|
||||
|
||||
case UCAL_EXTENDED_YEAR:
|
||||
// Rolling the year can involve pinning the DAY_OF_MONTH.
|
||||
set(field, internalGet(field) + amount);
|
||||
@ -1861,8 +1900,25 @@ void Calendar::add(UCalendarDateFields field, int32_t amount, UErrorCode& status
|
||||
return;
|
||||
|
||||
case UCAL_YEAR:
|
||||
case UCAL_EXTENDED_YEAR:
|
||||
case UCAL_YEAR_WOY:
|
||||
{
|
||||
// * If era=0 and years go backwards in time, change sign of amount.
|
||||
// * Until we have new API per #9393, we temporarily hardcode knowledge of
|
||||
// which calendars have era 0 years that go backwards.
|
||||
// * Note that for UCAL_YEAR (but not UCAL_YEAR_WOY) we could instead handle
|
||||
// this by applying the amount to the UCAL_EXTENDED_YEAR field; but since
|
||||
// we would still need to handle UCAL_YEAR_WOY as below, might as well
|
||||
// also handle UCAL_YEAR the same way.
|
||||
int32_t era = get(UCAL_ERA, status);
|
||||
if (era == 0) {
|
||||
const char * calType = getType();
|
||||
if ( uprv_strcmp(calType,"gregorian")==0 || uprv_strcmp(calType,"roc")==0 || uprv_strcmp(calType,"coptic")==0 ) {
|
||||
amount = -amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Fall through into normal handling
|
||||
case UCAL_EXTENDED_YEAR:
|
||||
case UCAL_MONTH:
|
||||
{
|
||||
UBool oldLenient = isLenient();
|
||||
|
@ -32,6 +32,7 @@
|
||||
|
||||
void TestGregorianChange(void);
|
||||
void TestFieldDifference(void);
|
||||
void TestAddRollEra0AndEraBounds(void);
|
||||
|
||||
void addCalTest(TestNode** root);
|
||||
|
||||
@ -50,6 +51,7 @@ void addCalTest(TestNode** root)
|
||||
addTest(root, &TestWeekend, "tsformat/ccaltst/TestWeekend");
|
||||
addTest(root, &TestFieldDifference, "tsformat/ccaltst/TestFieldDifference");
|
||||
addTest(root, &TestAmbiguousWallTime, "tsformat/ccaltst/TestAmbiguousWallTime");
|
||||
addTest(root, &TestAddRollEra0AndEraBounds, "tsformat/ccaltst/TestAddRollEra0AndEraBounds");
|
||||
}
|
||||
|
||||
/* "GMT" */
|
||||
@ -1655,46 +1657,46 @@ static void TestWeekend() {
|
||||
log_data_err("Unable to create UDateFormat - %s\n", u_errorName(fmtStatus));
|
||||
return;
|
||||
}
|
||||
for (count = sizeof(testDates)/sizeof(testDates[0]); count-- > 0; ++testDatesPtr) {
|
||||
for (count = sizeof(testDates)/sizeof(testDates[0]); count-- > 0; ++testDatesPtr) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UCalendar * cal = ucal_open(NULL, 0, testDatesPtr->locale, UCAL_GREGORIAN, &status);
|
||||
log_verbose("locale: %s\n", testDatesPtr->locale);
|
||||
if (U_SUCCESS(status)) {
|
||||
const TestWeekendDates * weekendDatesPtr = testDatesPtr->dates;
|
||||
for (subCount = testDatesPtr->numDates; subCount--; ++weekendDatesPtr) {
|
||||
UDate dateToTest;
|
||||
UBool isWeekend;
|
||||
char fmtDateBytes[kFormattedDateMax] = "<could not format test date>"; /* initialize for failure */
|
||||
UCalendar * cal = ucal_open(NULL, 0, testDatesPtr->locale, UCAL_GREGORIAN, &status);
|
||||
log_verbose("locale: %s\n", testDatesPtr->locale);
|
||||
if (U_SUCCESS(status)) {
|
||||
const TestWeekendDates * weekendDatesPtr = testDatesPtr->dates;
|
||||
for (subCount = testDatesPtr->numDates; subCount--; ++weekendDatesPtr) {
|
||||
UDate dateToTest;
|
||||
UBool isWeekend;
|
||||
char fmtDateBytes[kFormattedDateMax] = "<could not format test date>"; /* initialize for failure */
|
||||
|
||||
ucal_clear(cal);
|
||||
ucal_setDateTime(cal, weekendDatesPtr->year, weekendDatesPtr->month, weekendDatesPtr->day,
|
||||
weekendDatesPtr->hour, 0, 0, &status);
|
||||
dateToTest = ucal_getMillis(cal, &status) + weekendDatesPtr->millisecOffset;
|
||||
isWeekend = ucal_isWeekend(cal, dateToTest, &status);
|
||||
if (U_SUCCESS(fmtStatus)) {
|
||||
UChar fmtDate[kFormattedDateMax];
|
||||
(void)udat_format(fmt, dateToTest, fmtDate, kFormattedDateMax, NULL, &fmtStatus);
|
||||
if (U_SUCCESS(fmtStatus)) {
|
||||
u_austrncpy(fmtDateBytes, fmtDate, kFormattedDateMax);
|
||||
fmtDateBytes[kFormattedDateMax-1] = 0;
|
||||
} else {
|
||||
fmtStatus = U_ZERO_ERROR;
|
||||
}
|
||||
}
|
||||
if ( U_FAILURE(status) ) {
|
||||
log_err("FAIL: locale %s date %s isWeekend() status %s\n", testDatesPtr->locale, fmtDateBytes, u_errorName(status) );
|
||||
status = U_ZERO_ERROR;
|
||||
} else if ( (isWeekend!=0) != (weekendDatesPtr->isWeekend!=0) ) {
|
||||
log_err("FAIL: locale %s date %s isWeekend %d, expected the opposite\n", testDatesPtr->locale, fmtDateBytes, isWeekend );
|
||||
} else {
|
||||
log_verbose("OK: locale %s date %s isWeekend %d\n", testDatesPtr->locale, fmtDateBytes, isWeekend );
|
||||
}
|
||||
}
|
||||
ucal_close(cal);
|
||||
} else {
|
||||
log_data_err("FAIL: ucal_open for locale %s failed: %s - (Are you missing data?)\n", testDatesPtr->locale, u_errorName(status) );
|
||||
}
|
||||
}
|
||||
ucal_clear(cal);
|
||||
ucal_setDateTime(cal, weekendDatesPtr->year, weekendDatesPtr->month, weekendDatesPtr->day,
|
||||
weekendDatesPtr->hour, 0, 0, &status);
|
||||
dateToTest = ucal_getMillis(cal, &status) + weekendDatesPtr->millisecOffset;
|
||||
isWeekend = ucal_isWeekend(cal, dateToTest, &status);
|
||||
if (U_SUCCESS(fmtStatus)) {
|
||||
UChar fmtDate[kFormattedDateMax];
|
||||
(void)udat_format(fmt, dateToTest, fmtDate, kFormattedDateMax, NULL, &fmtStatus);
|
||||
if (U_SUCCESS(fmtStatus)) {
|
||||
u_austrncpy(fmtDateBytes, fmtDate, kFormattedDateMax);
|
||||
fmtDateBytes[kFormattedDateMax-1] = 0;
|
||||
} else {
|
||||
fmtStatus = U_ZERO_ERROR;
|
||||
}
|
||||
}
|
||||
if ( U_FAILURE(status) ) {
|
||||
log_err("FAIL: locale %s date %s isWeekend() status %s\n", testDatesPtr->locale, fmtDateBytes, u_errorName(status) );
|
||||
status = U_ZERO_ERROR;
|
||||
} else if ( (isWeekend!=0) != (weekendDatesPtr->isWeekend!=0) ) {
|
||||
log_err("FAIL: locale %s date %s isWeekend %d, expected the opposite\n", testDatesPtr->locale, fmtDateBytes, isWeekend );
|
||||
} else {
|
||||
log_verbose("OK: locale %s date %s isWeekend %d\n", testDatesPtr->locale, fmtDateBytes, isWeekend );
|
||||
}
|
||||
}
|
||||
ucal_close(cal);
|
||||
} else {
|
||||
log_data_err("FAIL: ucal_open for locale %s failed: %s - (Are you missing data?)\n", testDatesPtr->locale, u_errorName(status) );
|
||||
}
|
||||
}
|
||||
if (U_SUCCESS(fmtStatus)) {
|
||||
udat_close(fmt);
|
||||
}
|
||||
@ -1712,12 +1714,12 @@ static void TestWeekend() {
|
||||
transition = ucal_getWeekendTransition(cal, daysOfWeekPtr->dayOfWeek, &status);
|
||||
}
|
||||
if ( U_FAILURE(status) ) {
|
||||
log_err("FAIL: locale %s DOW %d getDayOfWeekType() status %s\n", testDaysPtr->locale, daysOfWeekPtr->dayOfWeek, u_errorName(status) );
|
||||
status = U_ZERO_ERROR;
|
||||
log_err("FAIL: locale %s DOW %d getDayOfWeekType() status %s\n", testDaysPtr->locale, daysOfWeekPtr->dayOfWeek, u_errorName(status) );
|
||||
status = U_ZERO_ERROR;
|
||||
} else if ( dayType != daysOfWeekPtr->dayType || transition != daysOfWeekPtr->transition ) {
|
||||
log_err("FAIL: locale %s DOW %d type %d, expected %d\n", testDaysPtr->locale, daysOfWeekPtr->dayOfWeek, dayType, daysOfWeekPtr->dayType );
|
||||
log_err("FAIL: locale %s DOW %d type %d, expected %d\n", testDaysPtr->locale, daysOfWeekPtr->dayOfWeek, dayType, daysOfWeekPtr->dayType );
|
||||
} else {
|
||||
log_verbose("OK: locale %s DOW %d type %d\n", testDaysPtr->locale, daysOfWeekPtr->dayOfWeek, dayType );
|
||||
log_verbose("OK: locale %s DOW %d type %d\n", testDaysPtr->locale, daysOfWeekPtr->dayOfWeek, dayType );
|
||||
}
|
||||
}
|
||||
ucal_close(cal);
|
||||
@ -1937,4 +1939,221 @@ void TestAmbiguousWallTime() {
|
||||
ucal_close(ucal);
|
||||
}
|
||||
|
||||
/**
|
||||
* TestAddRollEra0AndEraBounds, for #9226
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
const char * locale;
|
||||
UBool era0YearsGoBackwards; /* until we have API to get this, per #9393 */
|
||||
} EraTestItem;
|
||||
|
||||
static const EraTestItem eraTestItems[] = {
|
||||
/* calendars with non-modern era 0 that goes backwards, max era == 1 */
|
||||
{ "en@calendar=gregorian", TRUE },
|
||||
{ "en@calendar=roc", TRUE },
|
||||
{ "en@calendar=coptic", TRUE },
|
||||
/* calendars with non-modern era 0 that goes forwards, max era > 1 */
|
||||
{ "en@calendar=japanese", FALSE },
|
||||
{ "en@calendar=chinese", FALSE },
|
||||
/* calendars with non-modern era 0 that goes forwards, max era == 1 */
|
||||
{ "en@calendar=ethiopic", FALSE },
|
||||
/* calendars with only one era = 0, forwards */
|
||||
{ "en@calendar=buddhist", FALSE },
|
||||
{ "en@calendar=hebrew", FALSE },
|
||||
{ "en@calendar=islamic", FALSE },
|
||||
{ "en@calendar=indian", FALSE },
|
||||
{ "en@calendar=persian", FALSE },
|
||||
{ "en@calendar=ethiopic-amete-alem", FALSE },
|
||||
{ NULL, FALSE }
|
||||
};
|
||||
|
||||
static const UChar zoneGMT[] = { 0x47,0x4D,0x54,0 };
|
||||
|
||||
void TestAddRollEra0AndEraBounds() {
|
||||
const EraTestItem * eraTestItemPtr;
|
||||
for (eraTestItemPtr = eraTestItems; eraTestItemPtr->locale != NULL; eraTestItemPtr++) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
UCalendar *ucalTest = ucal_open(zoneGMT, -1, eraTestItemPtr->locale, UCAL_DEFAULT, &status);
|
||||
if ( U_SUCCESS(status) ) {
|
||||
int32_t yrBefore, yrAfter, yrMax, eraAfter, eraMax, eraNow;
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
ucal_clear(ucalTest);
|
||||
ucal_set(ucalTest, UCAL_YEAR, 2);
|
||||
ucal_set(ucalTest, UCAL_ERA, 0);
|
||||
yrBefore = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
ucal_add(ucalTest, UCAL_YEAR, 1, &status);
|
||||
yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("FAIL: set era 0 year 2 then add 1 year and get year for %s, error %s\n",
|
||||
eraTestItemPtr->locale, u_errorName(status));
|
||||
} else if ( (eraTestItemPtr->era0YearsGoBackwards && yrAfter>yrBefore) ||
|
||||
(!eraTestItemPtr->era0YearsGoBackwards && yrAfter<yrBefore) ) {
|
||||
log_err("FAIL: era 0 add 1 year does not move forward in time for %s\n", eraTestItemPtr->locale);
|
||||
}
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
ucal_clear(ucalTest);
|
||||
ucal_set(ucalTest, UCAL_YEAR, 2);
|
||||
ucal_set(ucalTest, UCAL_ERA, 0);
|
||||
yrBefore = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
ucal_roll(ucalTest, UCAL_YEAR, 1, &status);
|
||||
yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("FAIL: set era 0 year 2 then roll 1 year and get year for %s, error %s\n",
|
||||
eraTestItemPtr->locale, u_errorName(status));
|
||||
} else if ( (eraTestItemPtr->era0YearsGoBackwards && yrAfter>yrBefore) ||
|
||||
(!eraTestItemPtr->era0YearsGoBackwards && yrAfter<yrBefore) ) {
|
||||
log_err("FAIL: era 0 roll 1 year does not move forward in time for %s\n", eraTestItemPtr->locale);
|
||||
}
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
ucal_clear(ucalTest);
|
||||
ucal_set(ucalTest, UCAL_YEAR, 1);
|
||||
ucal_set(ucalTest, UCAL_ERA, 0);
|
||||
if (eraTestItemPtr->era0YearsGoBackwards) {
|
||||
ucal_roll(ucalTest, UCAL_YEAR, 1, &status); /* roll forward in time to era 0 boundary */
|
||||
yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
eraAfter = ucal_get(ucalTest, UCAL_ERA, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("FAIL: set era 0 year 1 then roll 1 year and get year,era for %s, error %s\n",
|
||||
eraTestItemPtr->locale, u_errorName(status));
|
||||
/* all calendars with era0YearsGoBackwards have "unbounded" era0 year values, so we should pin at yr 1 */
|
||||
} else if (eraAfter != 0 || yrAfter != 1) {
|
||||
log_err("FAIL: era 0 roll 1 year from year 1 does not stay within era or pin to year 1 for %s (get era %d year %d)\n",
|
||||
eraTestItemPtr->locale, eraAfter, yrAfter);
|
||||
}
|
||||
} else {
|
||||
/* roll backward in time to where era 0 years go negative, except for the Chinese
|
||||
calendar, which uses negative eras instead of having years outside the range 1-60 */
|
||||
const char * calType = ucal_getType(ucalTest, &status);
|
||||
ucal_roll(ucalTest, UCAL_YEAR, -2, &status);
|
||||
yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
eraAfter = ucal_get(ucalTest, UCAL_ERA, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("FAIL: set era 0 year 1 then roll -2 years and get year,era for %s, error %s\n",
|
||||
eraTestItemPtr->locale, u_errorName(status));
|
||||
} else if ( uprv_strcmp(calType,"chinese")!=0 && (eraAfter != 0 || yrAfter != -1) ) {
|
||||
log_err("FAIL: era 0 roll -2 years from year 1 does not stay within era or produce year -1 for %s (get era %d year %d)\n",
|
||||
eraTestItemPtr->locale, eraAfter, yrAfter);
|
||||
}
|
||||
}
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
ucal_clear(ucalTest);
|
||||
ucal_set(ucalTest, UCAL_YEAR, 1);
|
||||
ucal_set(ucalTest, UCAL_ERA, 0);
|
||||
eraMax = ucal_getLimit(ucalTest, UCAL_ERA, UCAL_MAXIMUM, &status);
|
||||
if ( U_SUCCESS(status) && eraMax > 0 ) {
|
||||
/* try similar tests for era 1 (if calendar has it), in which years always go forward */
|
||||
status = U_ZERO_ERROR;
|
||||
ucal_clear(ucalTest);
|
||||
ucal_set(ucalTest, UCAL_YEAR, 2);
|
||||
ucal_set(ucalTest, UCAL_ERA, 1);
|
||||
yrBefore = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
ucal_add(ucalTest, UCAL_YEAR, 1, &status);
|
||||
yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("FAIL: set era 1 year 2 then add 1 year and get year for %s, error %s\n",
|
||||
eraTestItemPtr->locale, u_errorName(status));
|
||||
} else if ( yrAfter<yrBefore ) {
|
||||
log_err("FAIL: era 1 add 1 year does not move forward in time for %s\n", eraTestItemPtr->locale);
|
||||
}
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
ucal_clear(ucalTest);
|
||||
ucal_set(ucalTest, UCAL_YEAR, 2);
|
||||
ucal_set(ucalTest, UCAL_ERA, 1);
|
||||
yrBefore = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
ucal_roll(ucalTest, UCAL_YEAR, 1, &status);
|
||||
yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("FAIL: set era 1 year 2 then roll 1 year and get year for %s, error %s\n",
|
||||
eraTestItemPtr->locale, u_errorName(status));
|
||||
} else if ( yrAfter<yrBefore ) {
|
||||
log_err("FAIL: era 1 roll 1 year does not move forward in time for %s\n", eraTestItemPtr->locale);
|
||||
}
|
||||
|
||||
status = U_ZERO_ERROR;
|
||||
ucal_clear(ucalTest);
|
||||
ucal_set(ucalTest, UCAL_YEAR, 1);
|
||||
ucal_set(ucalTest, UCAL_ERA, 1);
|
||||
yrMax = ucal_getLimit(ucalTest, UCAL_YEAR, UCAL_ACTUAL_MAXIMUM, &status); /* max year value for era 1 */
|
||||
ucal_roll(ucalTest, UCAL_YEAR, -1, &status); /* roll down which should pin or wrap to end */
|
||||
yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
eraAfter = ucal_get(ucalTest, UCAL_ERA, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("FAIL: set era 1 year 1 then roll -1 year and get year,era for %s, error %s\n",
|
||||
eraTestItemPtr->locale, u_errorName(status));
|
||||
/* if yrMax is reasonable we should wrap to that, else we should pin at yr 1 */
|
||||
} else if (yrMax >= 32768) {
|
||||
if (eraAfter != 1 || yrAfter != 1) {
|
||||
log_err("FAIL: era 1 roll -1 year from year 1 does not stay within era or pin to year 1 for %s (get era %d year %d)\n",
|
||||
eraTestItemPtr->locale, eraAfter, yrAfter);
|
||||
}
|
||||
} else if (eraAfter != 1 || yrAfter != yrMax) {
|
||||
log_err("FAIL: era 1 roll -1 year from year 1 does not stay within era or wrap to year %d for %s (get era %d year %d)\n",
|
||||
yrMax, eraTestItemPtr->locale, eraAfter, yrAfter);
|
||||
} else {
|
||||
/* now roll up which should wrap to beginning */
|
||||
ucal_roll(ucalTest, UCAL_YEAR, 1, &status); /* now roll up which should wrap to beginning */
|
||||
yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
eraAfter = ucal_get(ucalTest, UCAL_ERA, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("FAIL: era 1 roll 1 year from end and get year,era for %s, error %s\n",
|
||||
eraTestItemPtr->locale, u_errorName(status));
|
||||
} else if (eraAfter != 1 || yrAfter != 1) {
|
||||
log_err("FAIL: era 1 roll 1 year from year %d does not stay within era or wrap to year 1 for %s (get era %d year %d)\n",
|
||||
yrMax, eraTestItemPtr->locale, eraAfter, yrAfter);
|
||||
}
|
||||
}
|
||||
|
||||
/* if current era > 1, try the same roll tests for current era */
|
||||
ucal_setMillis(ucalTest, ucal_getNow(), &status);
|
||||
eraNow = ucal_get(ucalTest, UCAL_ERA, &status);
|
||||
if ( U_SUCCESS(status) && eraNow > 1 ) {
|
||||
status = U_ZERO_ERROR;
|
||||
ucal_clear(ucalTest);
|
||||
ucal_set(ucalTest, UCAL_YEAR, 1);
|
||||
ucal_set(ucalTest, UCAL_ERA, eraNow);
|
||||
yrMax = ucal_getLimit(ucalTest, UCAL_YEAR, UCAL_ACTUAL_MAXIMUM, &status); /* max year value for this era */
|
||||
ucal_roll(ucalTest, UCAL_YEAR, -1, &status);
|
||||
yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
eraAfter = ucal_get(ucalTest, UCAL_ERA, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("FAIL: set era %d year 1 then roll -1 year and get year,era for %s, error %s\n",
|
||||
eraNow, eraTestItemPtr->locale, u_errorName(status));
|
||||
/* if yrMax is reasonable we should wrap to that, else we should pin at yr 1 */
|
||||
} else if (yrMax >= 32768) {
|
||||
if (eraAfter != eraNow || yrAfter != 1) {
|
||||
log_err("FAIL: era %d roll -1 year from year 1 does not stay within era or pin to year 1 for %s (get era %d year %d)\n",
|
||||
eraNow, eraTestItemPtr->locale, eraAfter, yrAfter);
|
||||
}
|
||||
} else if (eraAfter != eraNow || yrAfter != yrMax) {
|
||||
log_err("FAIL: era %d roll -1 year from year 1 does not stay within era or wrap to year %d for %s (get era %d year %d)\n",
|
||||
eraNow, yrMax, eraTestItemPtr->locale, eraAfter, yrAfter);
|
||||
} else {
|
||||
/* now roll up which should wrap to beginning */
|
||||
ucal_roll(ucalTest, UCAL_YEAR, 1, &status); /* now roll up which should wrap to beginning */
|
||||
yrAfter = ucal_get(ucalTest, UCAL_YEAR, &status);
|
||||
eraAfter = ucal_get(ucalTest, UCAL_ERA, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
log_err("FAIL: era %d roll 1 year from end and get year,era for %s, error %s\n",
|
||||
eraNow, eraTestItemPtr->locale, u_errorName(status));
|
||||
} else if (eraAfter != eraNow || yrAfter != 1) {
|
||||
log_err("FAIL: era %d roll 1 year from year %d does not stay within era or wrap to year 1 for %s (get era %d year %d)\n",
|
||||
eraNow, yrMax, eraTestItemPtr->locale, eraAfter, yrAfter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ucal_close(ucalTest);
|
||||
} else {
|
||||
log_data_err("FAIL: ucal_open fails for zone GMT, locale %s, UCAL_DEFAULT\n", eraTestItemPtr->locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
Loading…
Reference in New Issue
Block a user