@@ -129,6 +129,7 @@ void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name,
129129 TESTCASE_AUTO (TestWeekData);
130130 TESTCASE_AUTO (TestAddAcrossZoneTransition);
131131 TESTCASE_AUTO (TestChineseCalendarMapping);
132+ TESTCASE_AUTO (TestChineseCalendarLiu1901To2101);
132133 TESTCASE_AUTO (TestTimeZoneInLocale);
133134 TESTCASE_AUTO (TestBasicConversionISO8601);
134135 TESTCASE_AUTO (TestBasicConversionJapanese);
@@ -3841,6 +3842,7 @@ void CalendarTest::TestAddAcrossZoneTransition() {
38413842// Data in a separate file (Gregorian to Chinese lunar map)
38423843#define INCLUDED_FROM_CALTEST_CPP
38433844#include " caltestdata.h"
3845+ #include " liutestdata.h"
38443846
38453847void CalendarTest::TestChineseCalendarMapping () {
38463848 UErrorCode status = U_ZERO_ERROR ;
@@ -3911,6 +3913,79 @@ void CalendarTest::TestChineseCalendarMapping() {
39113913 }
39123914}
39133915
3916+ void CalendarTest::TestChineseCalendarLiu1901To2101 () {
3917+ UErrorCode status = U_ZERO_ERROR ;
3918+ LocalPointer<TimeZone> zone (TimeZone::createTimeZone (UnicodeString (" China" )));
3919+ Locale locEnCalGregory = Locale::createFromName (" en@calendar=gregorian" );
3920+ Locale locEnCalChinese = Locale::createFromName (" en@calendar=chinese" );
3921+ LocalPointer<Calendar> calGregory (Calendar::createInstance (zone->clone (), locEnCalGregory, status));
3922+ LocalPointer<Calendar> calChinese (Calendar::createInstance (zone.orphan (), locEnCalChinese, status));
3923+ if (U_FAILURE (status)) {
3924+ errln (" Fail: Calendar::createInstance fails in TestChineseCalendarLiu1901To2101: %s" , u_errorName (status));
3925+ return ;
3926+ }
3927+ const GregoToChineseLiu* mapPtr = gregoToChineseLiu;
3928+ calGregory->clear ();
3929+ calChinese->clear ();
3930+ for (; mapPtr->gyr != 0 ; mapPtr++) {
3931+ // Known historical Keplerian approximation boundary variations between 2-body model and DE405 ephemeris.
3932+ // Notice: 1987 (ICU-23274) is NOT in this exception list and is strictly asserted.
3933+ if ((mapPtr->gyr == 1917 && (mapPtr->gmo == 3 || mapPtr->gmo == 4 )) ||
3934+ (mapPtr->gyr == 1922 && (mapPtr->gmo == 6 || mapPtr->gmo == 7 )) ||
3935+ (mapPtr->gyr == 1954 && mapPtr->gmo == 2 && mapPtr->gda == 3 ) ||
3936+ (mapPtr->gyr == 1955 && mapPtr->gmo == 2 && mapPtr->gda == 22 ) ||
3937+ (mapPtr->gyr == 1999 && mapPtr->gmo == 1 && mapPtr->gda == 17 ) ||
3938+ (mapPtr->gyr == 2012 && mapPtr->gmo == 8 && mapPtr->gda == 17 ) ||
3939+ (mapPtr->gyr == 2027 && mapPtr->gmo == 2 && mapPtr->gda == 6 ) ||
3940+ (mapPtr->gyr == 2070 && mapPtr->gmo == 3 && mapPtr->gda == 12 ) ||
3941+ (mapPtr->gyr == 2018 && mapPtr->gmo == 11 && mapPtr->gda == 8 ) ||
3942+ (mapPtr->gyr == 2030 && mapPtr->gmo == 2 && mapPtr->gda == 3 ) ||
3943+ (mapPtr->gyr == 2097 && mapPtr->gmo == 8 && mapPtr->gda == 8 ) ||
3944+ (mapPtr->gyr == 2101 && mapPtr->gmo == 6 && mapPtr->gda == 27 )) {
3945+ continue ;
3946+ }
3947+
3948+ status = U_ZERO_ERROR ;
3949+ calGregory->set (mapPtr->gyr , mapPtr->gmo - 1 , mapPtr->gda , 8 , 0 );
3950+ UDate date = calGregory->getTime (status);
3951+ calChinese->setTime (date, status);
3952+ if (U_FAILURE (status)) {
3953+ errln (" Fail: for Gregorian %4d-%02d-%02d, setTime reports: %s" , mapPtr->gyr , mapPtr->gmo , mapPtr->gda , u_errorName (status));
3954+ continue ;
3955+ }
3956+ int32_t yr = calChinese->get (UCAL_EXTENDED_YEAR , status);
3957+ int32_t mo = calChinese->get (UCAL_MONTH , status) + 1 ;
3958+ int32_t lp = calChinese->get (UCAL_IS_LEAP_MONTH , status);
3959+ int32_t da = calChinese->get (UCAL_DATE , status);
3960+ const char * mcode = calChinese->getTemporalMonthCode (status);
3961+ if (yr != mapPtr->cyr || mo != mapPtr->cmo || lp != mapPtr->clp || da != 1 || uprv_strcmp (mcode, mapPtr->mcode ) != 0 ) {
3962+ errln (" Fail: Gregorian %4d-%02d-%02d should be Chinese %4d-%02d(%d)-01 (%s), but got %4d-%02d(%d)-%02d (%s)" ,
3963+ mapPtr->gyr , mapPtr->gmo , mapPtr->gda , mapPtr->cyr , mapPtr->cmo , mapPtr->clp , mapPtr->mcode , yr, mo, lp, da, mcode);
3964+ }
3965+
3966+ // Test convert back: Chinese to Gregorian
3967+ status = U_ZERO_ERROR ;
3968+ calChinese->clear ();
3969+ calChinese->set (UCAL_EXTENDED_YEAR , mapPtr->cyr );
3970+ calChinese->setTemporalMonthCode (mapPtr->mcode , status);
3971+ calChinese->set (UCAL_DATE , 1 );
3972+ calChinese->set (UCAL_HOUR_OF_DAY , 8 );
3973+ date = calChinese->getTime (status);
3974+ calGregory->setTime (date, status);
3975+ if (U_FAILURE (status)) {
3976+ errln (" Fail converting back Chinese %4d (%s)-01: %s" , mapPtr->cyr , mapPtr->mcode , u_errorName (status));
3977+ continue ;
3978+ }
3979+ int32_t gyr = calGregory->get (UCAL_YEAR , status);
3980+ int32_t gmo = calGregory->get (UCAL_MONTH , status) + 1 ;
3981+ int32_t gda = calGregory->get (UCAL_DATE , status);
3982+ if (gyr != mapPtr->gyr || gmo != mapPtr->gmo || gda != mapPtr->gda ) {
3983+ errln (" Fail convert back: Chinese %4d (%s)-01 should be Gregorian %4d-%02d-%02d, got %4d-%02d-%02d" ,
3984+ mapPtr->cyr , mapPtr->mcode , mapPtr->gyr , mapPtr->gmo , mapPtr->gda , gyr, gmo, gda);
3985+ }
3986+ }
3987+ }
3988+
39143989void CalendarTest::TestClearMonth () {
39153990 UErrorCode status = U_ZERO_ERROR ;
39163991 LocalPointer<Calendar> cal (Calendar::createInstance (Locale::getRoot (), status));
0 commit comments