ICU-57149.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / caltest.cpp
index 01f1407a06fcb351788f035c5df1d5b44a38ae18..1d1c56938f12890d3a4800fb3731b8dddb311d8b 100644 (file)
@@ -1,9 +1,8 @@
 /************************************************************************
- * COPYRIGHT: 
- * Copyright (c) 1997-2014, International Business Machines Corporation
+ * COPYRIGHT:
+ * Copyright (c) 1997-2016, International Business Machines Corporation
  * and others. All Rights Reserved.
  ************************************************************************/
-
 #include "unicode/utypes.h"
 
 #if !UCONFIG_NO_FORMATTING
 #include "unicode/ustring.h"
 #include "cstring.h"
 #include "unicode/localpointer.h"
+#include "islamcal.h"
 
 #define mkcstr(U) u_austrcpy(calloc(8, u_strlen(U) + 1), U)
 
-#define TEST_CHECK_STATUS {if (U_FAILURE(status)) {errln("%s:%d: Test failure.  status=%s", \
-                                                              __FILE__, __LINE__, u_errorName(status)); return;}}
+#define TEST_CHECK_STATUS { \
+    if (U_FAILURE(status)) { \
+        if (status == U_MISSING_RESOURCE_ERROR) { \
+            dataerrln("%s:%d: Test failure.  status=%s", __FILE__, __LINE__, u_errorName(status)); \
+        } else { \
+            errln("%s:%d: Test failure.  status=%s", __FILE__, __LINE__, u_errorName(status)); \
+        } return;}}
+
+#define TEST_CHECK_STATUS_LOCALE(testlocale) { \
+    if (U_FAILURE(status)) { \
+        if (status == U_MISSING_RESOURCE_ERROR) { \
+            dataerrln("%s:%d: Test failure, locale %s.  status=%s", __FILE__, __LINE__, testlocale, u_errorName(status)); \
+        } else { \
+            errln("%s:%d: Test failure, locale %s.  status=%s", __FILE__, __LINE__, testlocale, u_errorName(status)); \
+        } return;}}
 
 #define TEST_ASSERT(expr) {if ((expr)==FALSE) {errln("%s:%d: Test failure \n", __FILE__, __LINE__);};}
 
@@ -42,19 +55,19 @@ UnicodeString CalendarTest::calToStr(const Calendar & cal)
     out += (UnicodeString("") + fieldName((UCalendarDateFields)i) + "=" +  cal.get((UCalendarDateFields)i, status) + UnicodeString(" "));
   }
   out += "[" + UnicodeString(cal.getType()) + "]";
-  
+
   if(cal.inDaylightTime(status)) {
     out += UnicodeString(" (in DST), zone=");
   }
   else {
     out += UnicodeString(", zone=");
   }
-  
+
   UnicodeString str2;
   out += cal.getTimeZone().getDisplayName(str2);
   d = cal.getTime(status);
   out += UnicodeString(" :","") + d;
-  
+
   return out;
 }
 
@@ -280,12 +293,47 @@ void CalendarTest::runIndexedTest( int32_t index, UBool exec, const char* &name,
           }
           break;
         case 31:
+          name = "TestIslamicUmAlQura";
+          if(exec) {
+            logln("TestIslamicUmAlQura---"); logln("");
+            TestIslamicUmAlQura();
+          }
+          break;
+        case 32:
+          name = "TestIslamicTabularDates";
+          if(exec) {
+            logln("TestIslamicTabularDates---"); logln("");
+            TestIslamicTabularDates();
+          }
+          break;
+        case 33:
+          name = "TestHebrewMonthValidation";
+          if(exec) {
+            logln("TestHebrewMonthValidation---"); logln("");
+            TestHebrewMonthValidation();
+          }
+          break;
+        case 34:
+          name = "TestWeekData";
+          if(exec) {
+            logln("TestWeekData---"); logln("");
+            TestWeekData();
+          }
+          break;
+        case 35:
           name = "TestAddAcrossZoneTransition";
           if(exec) {
             logln("TestAddAcrossZoneTransition---"); logln("");
             TestAddAcrossZoneTransition();
           }
           break;
+        case 36:
+          name = "TestChineseCalendarMapping";
+          if(exec) {
+            logln("TestChineseCalendarMapping---"); logln("");
+            TestChineseCalendarMapping();
+          }
+          break;
         default: name = ""; break;
     }
 }
@@ -341,16 +389,16 @@ CalendarTest::TestGenericAPI()
 
     SimpleTimeZone *zone = new SimpleTimeZone(tzoffset, tzid);
     Calendar *cal = Calendar::createInstance(zone->clone(), status);
-    if (failure(status, "Calendar::createInstance", TRUE)) return;
+    if (failure(status, "Calendar::createInstance #1", TRUE)) return;
 
     if (*zone != cal->getTimeZone()) errln("FAIL: Calendar::getTimeZone failed");
 
     Calendar *cal2 = Calendar::createInstance(cal->getTimeZone(), status);
-    if (failure(status, "Calendar::createInstance")) return;
+    if (failure(status, "Calendar::createInstance #2")) return;
     cal->setTime(when, status);
     cal2->setTime(when, status);
     if (failure(status, "Calendar::setTime")) return;
-    
+
     if (!(*cal == *cal2)) errln("FAIL: Calendar::operator== failed");
     if ((*cal != *cal2))  errln("FAIL: Calendar::operator!= failed");
     if (!cal->equals(*cal2, status) ||
@@ -491,17 +539,20 @@ CalendarTest::TestGenericAPI()
         for (i=0; i<count; ++i)
         {
             cal = Calendar::createInstance(loc[i], status);
-            if (failure(status, "Calendar::createInstance")) return;
+            if (U_FAILURE(status)) {
+                errcheckln(status, UnicodeString("FAIL: Calendar::createInstance #3, locale ") +  loc[i].getName() + " , error " + u_errorName(status));
+                return;
+            }
             delete cal;
         }
     }
 
     cal = Calendar::createInstance(TimeZone::createDefault(), Locale::getEnglish(), status);
-    if (failure(status, "Calendar::createInstance")) return;
+    if (failure(status, "Calendar::createInstance #4")) return;
     delete cal;
 
     cal = Calendar::createInstance(*zone, Locale::getEnglish(), status);
-    if (failure(status, "Calendar::createInstance")) return;
+    if (failure(status, "Calendar::createInstance #5")) return;
     delete cal;
 
     GregorianCalendar *gc = new GregorianCalendar(*zone, status);
@@ -543,7 +594,7 @@ CalendarTest::TestGenericAPI()
 
     /* Code coverage for Calendar class. */
     cal = Calendar::createInstance(status);
-    if (failure(status, "Calendar::createInstance")) {
+    if (failure(status, "Calendar::createInstance #6")) {
         return;
     }else {
         ((Calendar *)cal)->roll(UCAL_HOUR, (int32_t)100, status);
@@ -557,7 +608,7 @@ CalendarTest::TestGenericAPI()
 
     status = U_ZERO_ERROR;
     cal = Calendar::createInstance(Locale("he_IL@calendar=hebrew"), status);
-    if (failure(status, "Calendar::createInstance")) {
+    if (failure(status, "Calendar::createInstance #7")) {
         return;
     } else {
         cal->roll(Calendar::MONTH, (int32_t)100, status);
@@ -636,7 +687,7 @@ CalendarTest::TestRog()
     }
     delete gc;
 }
+
 // -------------------------------------
 
 /**
@@ -678,7 +729,7 @@ void CalendarTest::dowTest(UBool lenient)
 
 // -------------------------------------
 
-/** 
+/**
  * Confirm that cloned Calendar objects do not inadvertently share substructures.
  */
 void
@@ -698,7 +749,7 @@ CalendarTest::TestClonesUnique908()
     delete c;
     delete d;
 }
+
 // -------------------------------------
 
 /**
@@ -726,7 +777,7 @@ CalendarTest::TestGregorianChange768()
     if (!b) errln("FAIL");
     delete c;
 }
+
 // -------------------------------------
 
 /**
@@ -832,9 +883,9 @@ CalendarTest::TestDisambiguation765()
     //}
     delete c;
 }
+
 // -------------------------------------
+
 void
 CalendarTest::verify765(const UnicodeString& msg, Calendar* c, int32_t year, int32_t month, int32_t day)
 {
@@ -856,16 +907,16 @@ CalendarTest::verify765(const UnicodeString& msg, Calendar* c, int32_t year, int
         if (U_FAILURE(status)) { errln("Calendar::getTime failed"); return; }
     }
 }
+
 // -------------------------------------
+
 void
 CalendarTest::verify765(const UnicodeString& msg/*, IllegalArgumentException e*/, UErrorCode status)
 {
     if (status != U_ILLEGAL_ARGUMENT_ERROR) errln("FAIL: No IllegalArgumentException for " + msg);
     else logln("PASS: " + msg + "IllegalArgument as expected");
 }
+
 // -------------------------------------
 
 /**
@@ -877,9 +928,9 @@ CalendarTest::TestGMTvsLocal4064654()
     test4064654(1997, 1, 1, 12, 0, 0);
     test4064654(1997, 4, 16, 18, 30, 0);
 }
+
 // -------------------------------------
+
 void
 CalendarTest::test4064654(int32_t yr, int32_t mo, int32_t dt, int32_t hr, int32_t mn, int32_t sc)
 {
@@ -917,9 +968,9 @@ CalendarTest::test4064654(int32_t yr, int32_t mo, int32_t dt, int32_t hr, int32_
     delete gmtcal;
     delete cal;
 }
+
 // -------------------------------------
+
 /**
  * The operations of adding and setting should not exhibit pathological
  * dependence on the order of operations.  This test checks for this.
@@ -933,66 +984,66 @@ CalendarTest::TestAddSetOrder621()
     if (failure(status, "Calendar::createInstance", TRUE)) return;
 
     cal->setTime(d, status);
-    if (U_FAILURE(status)) { 
-        errln("Calendar::setTime failed"); 
+    if (U_FAILURE(status)) {
+        errln("Calendar::setTime failed");
         delete cal;
-        return; 
+        return;
     }
     cal->add(UCAL_DATE, - 5, status);
-    if (U_FAILURE(status)) { 
-        errln("Calendar::add failed"); 
+    if (U_FAILURE(status)) {
+        errln("Calendar::add failed");
         delete cal;
-        return; 
+        return;
     }
     cal->set(UCAL_HOUR_OF_DAY, 0);
     cal->set(UCAL_MINUTE, 0);
     cal->set(UCAL_SECOND, 0);
     UnicodeString s;
     dateToString(cal->getTime(status), s);
-    if (U_FAILURE(status)) { 
-        errln("Calendar::getTime failed"); 
+    if (U_FAILURE(status)) {
+        errln("Calendar::getTime failed");
         delete cal;
-        return; 
+        return;
     }
     delete cal;
 
     cal = Calendar::createInstance(status);
-    if (U_FAILURE(status)) { 
-        errln("Calendar::createInstance failed"); 
+    if (U_FAILURE(status)) {
+        errln("Calendar::createInstance failed");
         delete cal;
-        return; 
+        return;
     }
     cal->setTime(d, status);
-    if (U_FAILURE(status)) { 
-        errln("Calendar::setTime failed"); 
+    if (U_FAILURE(status)) {
+        errln("Calendar::setTime failed");
         delete cal;
-        return; 
+        return;
     }
     cal->set(UCAL_HOUR_OF_DAY, 0);
     cal->set(UCAL_MINUTE, 0);
     cal->set(UCAL_SECOND, 0);
     cal->add(UCAL_DATE, - 5, status);
-    if (U_FAILURE(status)) { 
-        errln("Calendar::add failed"); 
+    if (U_FAILURE(status)) {
+        errln("Calendar::add failed");
         delete cal;
-        return; 
+        return;
     }
     UnicodeString s2;
     dateToString(cal->getTime(status), s2);
-    if (U_FAILURE(status)) { 
-        errln("Calendar::getTime failed"); 
+    if (U_FAILURE(status)) {
+        errln("Calendar::getTime failed");
         delete cal;
-        return; 
+        return;
     }
-    if (s == s2) 
+    if (s == s2)
         logln("Pass: " + s + " == " + s2);
-    else 
+    else
         errln("FAIL: " + s + " != " + s2);
     delete cal;
 }
+
 // -------------------------------------
+
 /**
  * Confirm that adding to various fields works.
  */
@@ -1026,9 +1077,9 @@ CalendarTest::TestAdd520()
     check520(temp, y, m, d);
     delete temp;
 }
+
 // -------------------------------------
+
 /**
  * Execute adding and rolling in GregorianCalendar extensively,
  */
@@ -1077,10 +1128,10 @@ CalendarTest::TestAddRollExtensive()
         for (i = 0; i < limit; i++) {
             logln(calToStr(*temp) + UnicodeString("  " ) + fieldName(e) + UnicodeString("++") );
             temp->roll(e, 1, status);
-            if (U_FAILURE(status)) { 
+            if (U_FAILURE(status)) {
               logln("caltest.cpp:%d e=%d, i=%d - roll(+) err %s\n",  __LINE__, (int) e, (int) i, u_errorName(status));
               logln(calToStr(*temp));
-              limit = i; status = U_ZERO_ERROR; 
+              limit = i; status = U_ZERO_ERROR;
             }
         }
         for (i = 0; i < limit; i++) {
@@ -1096,12 +1147,12 @@ CalendarTest::TestAddRollExtensive()
 
     delete temp;
 }
+
 // -------------------------------------
-void 
-CalendarTest::check520(Calendar* c, 
-                        int32_t y, int32_t m, int32_t d, 
-                        int32_t hr, int32_t min, int32_t sec, 
+void
+CalendarTest::check520(Calendar* c,
+                        int32_t y, int32_t m, int32_t d,
+                        int32_t hr, int32_t min, int32_t sec,
                         int32_t ms, UCalendarDateFields field)
 
 {
@@ -1113,7 +1164,7 @@ CalendarTest::check520(Calendar* c,
         c->get(UCAL_MINUTE, status) != min ||
         c->get(UCAL_SECOND, status) != sec ||
         c->get(UCAL_MILLISECOND, status) != ms) {
-        errln(UnicodeString("U_FAILURE for field ") + (int32_t)field + 
+        errln(UnicodeString("U_FAILURE for field ") + (int32_t)field +
                 ": Expected y/m/d h:m:s:ms of " +
                 y + "/" + (m + 1) + "/" + d + " " +
               hr + ":" + min + ":" + sec + ":" + ms +
@@ -1121,22 +1172,22 @@ CalendarTest::check520(Calendar* c,
               "/" + (c->get(UCAL_MONTH, status) + 1) +
               "/" + c->get(UCAL_DATE, status) +
               " " + c->get(UCAL_HOUR, status) + ":" +
-              c->get(UCAL_MINUTE, status) + ":" + 
+              c->get(UCAL_MINUTE, status) + ":" +
               c->get(UCAL_SECOND, status) + ":" +
               c->get(UCAL_MILLISECOND, status)
               );
 
         if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
     }
-    else 
+    else
         logln(UnicodeString("Confirmed: ") + y + "/" +
                 (m + 1) + "/" + d + " " +
                 hr + ":" + min + ":" + sec + ":" + ms);
 }
+
 // -------------------------------------
-void 
-CalendarTest::check520(Calendar* c, 
+void
+CalendarTest::check520(Calendar* c,
                         int32_t y, int32_t m, int32_t d)
 
 {
@@ -1153,13 +1204,13 @@ CalendarTest::check520(Calendar* c,
 
         if (U_FAILURE(status)) { errln("Calendar::get failed"); return; }
     }
-    else 
+    else
         logln(UnicodeString("Confirmed: ") + y + "/" +
                 (m + 1) + "/" + d);
 }
 
 // -------------------------------------
+
 /**
  * Test that setting of fields works.  In particular, make sure that all instances
  * of GregorianCalendar don't share a static instance of the fields array.
@@ -1186,7 +1237,7 @@ CalendarTest::TestFieldSet4781()
         delete g;
         delete g2;
 }
+
 // -------------------------------------
 
 /* We don't support serialization on C++
@@ -1224,11 +1275,11 @@ CalendarTest::TestSerialize337()
     }
     if (!ok) errln("Serialization of Calendar object failed.");
 }
+
 UnicodeString& CalendarTest::PREFIX = "abc";
+
 UnicodeString& CalendarTest::POSTFIX = "def";
+
 UnicodeString& CalendarTest::FILENAME = "tmp337.bin";
  */
 
@@ -1237,7 +1288,7 @@ UnicodeString& CalendarTest::FILENAME = "tmp337.bin";
 /**
  * Verify that the seconds of a Calendar can be zeroed out through the
  * expected sequence of operations.
- */ 
+ */
 void
 CalendarTest::TestSecondsZero121()
 {
@@ -1259,9 +1310,9 @@ CalendarTest::TestSecondsZero121()
     }
     delete cal;
 }
+
 // -------------------------------------
+
 /**
  * Verify that a specific sequence of adding and setting works as expected;
  * it should not vary depending on when and whether the get method is
@@ -1312,9 +1363,9 @@ CalendarTest::TestAddSetGet0610()
         delete calendar;
     }
 }
+
 // -------------------------------------
+
 UnicodeString
 CalendarTest::value(Calendar* calendar)
 {
@@ -1324,10 +1375,10 @@ CalendarTest::value(Calendar* calendar)
         "/" + (int32_t)calendar->get(UCAL_DATE, status) +
         (U_FAILURE(status) ? " FAIL: Calendar::get failed" : "");
 }
+
+
 // -------------------------------------
+
 /**
  * Verify that various fields on a known date are set correctly.
  */
@@ -1352,7 +1403,7 @@ CalendarTest::TestFields060()
     }
     delete calendar;
 }
+
 int32_t CalendarTest::EXPECTED_FIELDS[] = {
     UCAL_YEAR, 1997,
     UCAL_MONTH, UCAL_OCTOBER,
@@ -1361,12 +1412,12 @@ int32_t CalendarTest::EXPECTED_FIELDS[] = {
     UCAL_DAY_OF_WEEK_IN_MONTH, 4,
     UCAL_DAY_OF_YEAR, 295
 };
+
 const int32_t CalendarTest::EXPECTED_FIELDS_length = (int32_t)(sizeof(CalendarTest::EXPECTED_FIELDS) /
     sizeof(CalendarTest::EXPECTED_FIELDS[0]));
 
 // -------------------------------------
+
 /**
  * Verify that various fields on a known date are set correctly.  In this
  * case, the start of the epoch (January 1 1970).
@@ -1416,13 +1467,13 @@ CalendarTest::TestEpochStartFields()
     delete z;
     delete gc;
 }
+
 int32_t CalendarTest::EPOCH_FIELDS[] = {
     1, 1970, 0, 1, 1, 1, 1, 5, 1, 0, 0, 0, 0, 0, 0, - 28800000, 0
 };
+
 // -------------------------------------
+
 /**
  * Test that the days of the week progress properly when add is called repeatedly
  * for increments of 24 days.
@@ -1436,7 +1487,7 @@ CalendarTest::TestDOWProgression()
     marchByDelta(cal, 24);
     delete cal;
 }
+
 // -------------------------------------
 
 void
@@ -1515,7 +1566,7 @@ void CalendarTest::yearAddTest(Calendar& cal, UErrorCode& status) {
     int32_t woy = cal.get(UCAL_WEEK_OF_YEAR, status);
     int32_t dow = cal.get(UCAL_DOW_LOCAL, status);
     UDate t = cal.getTime(status);
-    
+
     if(U_FAILURE(status)){
         errln(UnicodeString("Failed to create Calendar for locale. Error: ") + UnicodeString(u_errorName(status)));
         return;
@@ -1606,7 +1657,7 @@ void CalendarTest::loop_addroll(Calendar *cal, /*SimpleDateFormat *sdf,*/ int ti
 // -------------------------------------
 
 void
-CalendarTest::doYEAR_WOYLoop(Calendar *cal, SimpleDateFormat *sdf, 
+CalendarTest::doYEAR_WOYLoop(Calendar *cal, SimpleDateFormat *sdf,
                                     int32_t times, UErrorCode& errorCode) {
 
     UnicodeString us;
@@ -1660,7 +1711,7 @@ CalendarTest::doYEAR_WOYLoop(Calendar *cal, SimpleDateFormat *sdf,
     delete (tstres);
 }
 // -------------------------------------
-  
+
 void
 CalendarTest::marchByDelta(Calendar* cal, int32_t delta)
 {
@@ -1734,7 +1785,7 @@ void CalendarTest::TestWOY(void) {
          Sun Jan 09 2000, WOY 2
          Mon Jan 10 2000, WOY 3
     */
+
     UnicodeString str;
     UErrorCode status = U_ZERO_ERROR;
     int32_t i;
@@ -1964,7 +2015,7 @@ void CalendarTest::TestYWOY()
 {
    UnicodeString str;
    UErrorCode status = U_ZERO_ERROR;
-   
+
    GregorianCalendar cal(status);
    if (failure(status, "construct GregorianCalendar", TRUE)) return;
 
@@ -1976,7 +2027,7 @@ void CalendarTest::TestYWOY()
    cal.set(UCAL_YEAR_WOY,2004);
    cal.set(UCAL_WEEK_OF_YEAR,1);
    cal.set(UCAL_DAY_OF_WEEK, UCAL_MONDAY);
-   
+
    logln(calToStr(cal));
    if(cal.get(UCAL_YEAR, status) != 2003) {
      errln("year not 2003");
@@ -1987,7 +2038,7 @@ void CalendarTest::TestYWOY()
    cal.set(UCAL_YEAR_WOY,2004);
    cal.set(UCAL_WEEK_OF_YEAR,1);
    cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY);
-   
+
    logln(calToStr(cal));
    if(cal.get(UCAL_YEAR, status) != 2004) {
      errln("year not 2004");
@@ -1999,7 +2050,7 @@ void CalendarTest::TestYWOY()
    cal.set(UCAL_WEEK_OF_YEAR,1);
    cal.set(UCAL_DAY_OF_WEEK, UCAL_THURSDAY);
    cal.set(UCAL_DOW_LOCAL, 1);
-   
+
    logln(calToStr(cal));
    if(cal.get(UCAL_YEAR, status) != 2003) {
      errln("year not 2003");
@@ -2033,7 +2084,7 @@ void CalendarTest::TestJD()
   } else {
     logln("Wanted JD of %d at time=0, [epoch 1970], got %d\n", kEpochStartAsJulianDay, jd);
   }
-  
+
   cal.setTime(Calendar::getNow(), status);
   cal.clear();
   cal.set(UCAL_JULIAN_DAY, kEpochStartAsJulianDay);
@@ -2072,7 +2123,7 @@ void CalendarTest::TestDebug()
                           }
                           name = "(null)";
                   }
-          logln("udbg_enumArrayValue(%d,%d) = %s, returned %d", t, i, 
+          logln("udbg_enumArrayValue(%d,%d) = %s, returned %d", t, i,
                       name, udbg_enumArrayValue((UDebugEnumType)t,i));
             logln("udbg_enumString = " + udbg_enumString((UDebugEnumType)t,i));
         }
@@ -2125,7 +2176,7 @@ int32_t CalendarTest::testLocaleCount()
 
 static UDate doMinDateOfCalendar(Calendar* adopt, UBool &isGregorian, UErrorCode& status) {
   if(U_FAILURE(status)) return 0.0;
-  
+
   adopt->clear();
   adopt->set(UCAL_EXTENDED_YEAR, adopt->getActualMinimum(UCAL_EXTENDED_YEAR, status));
   UDate ret = adopt->getTime(status);
@@ -2153,7 +2204,7 @@ void CalendarTest::Test6703()
     cal = Calendar::createInstance(loc1, status);
     if (failure(status, "Calendar::createInstance", TRUE)) return;
     delete cal;
-  
+
     status = U_ZERO_ERROR;
     Locale loc2("en");
     cal = Calendar::createInstance(loc2, status);
@@ -2171,46 +2222,46 @@ void CalendarTest::Test6703()
 
 void CalendarTest::Test3785()
 {
-    UErrorCode status = U_ZERO_ERROR; 
+    UErrorCode status = U_ZERO_ERROR;
     UnicodeString uzone = UNICODE_STRING_SIMPLE("Europe/Paris");
-    UnicodeString exp1 = UNICODE_STRING_SIMPLE("Mon 30 Jumada II 1433 AH, 01:47:03");
-    UnicodeString exp2 = UNICODE_STRING_SIMPLE("Mon 1 Rajab 1433 AH, 01:47:04");
+    UnicodeString exp1 = UNICODE_STRING_SIMPLE("Mon 30 Jumada II 1433 AH, 01:47:09");
+    UnicodeString exp2 = UNICODE_STRING_SIMPLE("Mon 1 Rajab 1433 AH, 01:47:10");
 
-    LocalUDateFormatPointer df(udat_open(UDAT_NONE, UDAT_NONE, "en@calendar=islamic", uzone.getTerminatedBuffer(), 
+    LocalUDateFormatPointer df(udat_open(UDAT_NONE, UDAT_NONE, "en@calendar=islamic", uzone.getTerminatedBuffer(),
                                          uzone.length(), NULL, 0, &status));
     if (df.isNull() || U_FAILURE(status)) return;
 
-    UChar upattern[64];   
-    u_uastrcpy(upattern, "EEE d MMMM y G, HH:mm:ss"); 
+    UChar upattern[64];
+    u_uastrcpy(upattern, "EEE d MMMM y G, HH:mm:ss");
     udat_applyPattern(df.getAlias(), FALSE, upattern, u_strlen(upattern));
 
-    UChar ubuffer[1024]; 
-    UDate ud0 = 1337557623000.0;
+    UChar ubuffer[1024];
+    UDate ud0 = 1337557629000.0;
 
-    status = U_ZERO_ERROR; 
-    udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status); 
+    status = U_ZERO_ERROR;
+    udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status);
     if (U_FAILURE(status)) {
         errln("Error formatting date 1\n");
-        return; 
+        return;
     }
     //printf("formatted: '%s'\n", mkcstr(ubuffer));
 
     UnicodeString act1(ubuffer);
     if ( act1 != exp1 ) {
-        errln("Unexpected result from date 1 format\n"); 
+        errln(UnicodeString("Unexpected result from date 1 format, act1: ") + act1);
     }
     ud0 += 1000.0; // add one second
 
-    status = U_ZERO_ERROR; 
-    udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status); 
+    status = U_ZERO_ERROR;
+    udat_format(df.getAlias(), ud0, ubuffer, 1024, NULL, &status);
     if (U_FAILURE(status)) {
         errln("Error formatting date 2\n");
-        return; 
+        return;
     }
     //printf("formatted: '%s'\n", mkcstr(ubuffer));
     UnicodeString act2(ubuffer);
     if ( act2 != exp2 ) {
-        errln("Unexpected result from date 2 format\n");
+        errln(UnicodeString("Unexpected result from date 2 format, act2: ") + act2);
     }
 
     return;
@@ -2222,7 +2273,7 @@ void CalendarTest::Test1624() {
     HebrewCalendar hc(loc,status);
 
     for (int32_t year = 5600; year < 5800; year++ ) {
-    
+
         for (int32_t month = HebrewCalendar::TISHRI; month <= HebrewCalendar::ELUL; month++) {
             // skip the adar 1 month if year is not a leap year
             if (HebrewCalendar::isLeapYear(year) == FALSE && month == HebrewCalendar::ADAR_1) {
@@ -2739,6 +2790,673 @@ void CalendarTest::TestCloneLocale(void) {
   TEST_CHECK_STATUS;
 }
 
+void CalendarTest::setAndTestCalendar(Calendar* cal, int32_t initMonth, int32_t initDay, int32_t initYear, UErrorCode& status) {
+        cal->clear();
+        cal->setLenient(FALSE);
+        cal->set(initYear, initMonth, initDay);
+        int32_t day = cal->get(UCAL_DAY_OF_MONTH, status);
+        int32_t month = cal->get(UCAL_MONTH, status);
+        int32_t year = cal->get(UCAL_YEAR, status);
+        if(U_FAILURE(status))
+            return;
+
+        if(initDay != day || initMonth != month || initYear != year)
+        {
+            errln(" year init values:\tmonth %i\tday %i\tyear %i", initMonth, initDay, initYear);
+            errln("values post set():\tmonth %i\tday %i\tyear %i",month, day, year);
+        }
+}
+
+void CalendarTest::setAndTestWholeYear(Calendar* cal, int32_t startYear, UErrorCode& status) {
+        for(int32_t startMonth = 0; startMonth < 12; startMonth++) {
+            for(int32_t startDay = 1; startDay < 31; startDay++ ) {
+                    setAndTestCalendar(cal, startMonth, startDay, startYear, status);
+                    if(U_FAILURE(status) && startDay == 30) {
+                        status = U_ZERO_ERROR;
+                        continue;
+                    }
+                    TEST_CHECK_STATUS;
+            }
+        }
+}
+
+// =====================================================================
+
+typedef struct {
+    int16_t  gYear;
+    int8_t   gMon;
+    int8_t   gDay;
+    int16_t  uYear;
+    int8_t   uMon;
+    int8_t   uDay;
+} GregoUmmAlQuraMap;
+
+// data from
+// Official Umm-al-Qura calendar of SA:
+// home, http://www.ummulqura.org.sa/default.aspx
+// converter, http://www.ummulqura.org.sa/Index.aspx
+static const GregoUmmAlQuraMap guMappings[] = {
+//  gregorian,    ummAlQura
+//  year mo da,   year mo da
+//  (using 1-based months here)
+  { 1882,11,12,   1300, 1, 1 },
+  { 1892, 7,25,   1310, 1, 1 },
+  { 1896, 6,12,   1314, 1, 1 },
+  { 1898, 5,22,   1316, 1, 1 },
+  { 1900, 4,30,   1318, 1, 1 },
+  { 1901, 4,20,   1319, 1, 1 },
+  { 1902, 4,10,   1320, 1, 1 },
+  { 1903, 3,30,   1321, 1, 1 },
+  { 1904, 3,19,   1322, 1, 1 },
+  { 1905, 3, 8,   1323, 1, 1 },
+  { 1906, 2,25,   1324, 1, 1 },
+  { 1907, 2,14,   1325, 1, 1 },
+  { 1908, 2, 4,   1326, 1, 1 },
+  { 1909, 1,23,   1327, 1, 1 },
+  { 1910, 1,13,   1328, 1, 1 },
+  { 1911, 1, 2,   1329, 1, 1 },
+  { 1911,12,22,   1330, 1, 1 },
+  { 1912,12,10,   1331, 1, 1 },
+  { 1913,11,30,   1332, 1, 1 },
+  { 1914,11,19,   1333, 1, 1 },
+  { 1915,11, 9,   1334, 1, 1 },
+  { 1916,10,28,   1335, 1, 1 },
+  { 1917,10,18,   1336, 1, 1 },
+  { 1918,10, 7,   1337, 1, 1 },
+  { 1919, 9,26,   1338, 1, 1 },
+  { 1920, 9,14,   1339, 1, 1 },
+  { 1921, 9, 4,   1340, 1, 1 },
+  { 1922, 8,24,   1341, 1, 1 },
+  { 1923, 8,14,   1342, 1, 1 },
+  { 1924, 8, 2,   1343, 1, 1 },
+  { 1925, 7,22,   1344, 1, 1 },
+  { 1926, 7,11,   1345, 1, 1 },
+  { 1927, 6,30,   1346, 1, 1 },
+  { 1928, 6,19,   1347, 1, 1 },
+  { 1929, 6, 9,   1348, 1, 1 },
+  { 1930, 5,29,   1349, 1, 1 },
+  { 1931, 5,19,   1350, 1, 1 },
+  { 1932, 5, 7,   1351, 1, 1 },
+  { 1933, 4,26,   1352, 1, 1 },
+  { 1934, 4,15,   1353, 1, 1 },
+  { 1935, 4, 5,   1354, 1, 1 },
+  { 1936, 3,24,   1355, 1, 1 },
+  { 1937, 3,14,   1356, 1, 1 },
+  { 1938, 3, 4,   1357, 1, 1 },
+  { 1939, 2,21,   1358, 1, 1 },
+  { 1940, 2,10,   1359, 1, 1 },
+  { 1941, 1,29,   1360, 1, 1 },
+  { 1942, 1,18,   1361, 1, 1 },
+  { 1943, 1, 8,   1362, 1, 1 },
+  { 1943,12,28,   1363, 1, 1 },
+  { 1944,12,17,   1364, 1, 1 },
+  { 1945,12, 6,   1365, 1, 1 },
+  { 1946,11,25,   1366, 1, 1 },
+  { 1947,11,14,   1367, 1, 1 },
+  { 1948,11, 3,   1368, 1, 1 },
+  { 1949,10,23,   1369, 1, 1 },
+  { 1950,10,13,   1370, 1, 1 },
+  { 1951,10, 3,   1371, 1, 1 },
+  { 1952, 9,21,   1372, 1, 1 },
+  { 1953, 9,10,   1373, 1, 1 },
+  { 1954, 8,30,   1374, 1, 1 },
+  { 1955, 8,19,   1375, 1, 1 },
+  { 1956, 8, 8,   1376, 1, 1 },
+  { 1957, 7,29,   1377, 1, 1 },
+  { 1958, 7,18,   1378, 1, 1 },
+  { 1959, 7, 8,   1379, 1, 1 },
+  { 1960, 6,26,   1380, 1, 1 },
+  { 1961, 6,15,   1381, 1, 1 },
+  { 1962, 6, 4,   1382, 1, 1 },
+  { 1963, 5,24,   1383, 1, 1 },
+  { 1964, 5,13,   1384, 1, 1 },
+  { 1965, 5, 3,   1385, 1, 1 },
+  { 1966, 4,22,   1386, 1, 1 },
+  { 1967, 4,11,   1387, 1, 1 },
+  { 1968, 3,30,   1388, 1, 1 },
+  { 1969, 3,19,   1389, 1, 1 },
+  { 1970, 3, 9,   1390, 1, 1 },
+  { 1971, 2,27,   1391, 1, 1 },
+  { 1972, 2,16,   1392, 1, 1 },
+  { 1973, 2, 5,   1393, 1, 1 },
+  { 1974, 1,25,   1394, 1, 1 },
+  { 1975, 1,14,   1395, 1, 1 },
+  { 1976, 1, 3,   1396, 1, 1 },
+  { 1976,12,22,   1397, 1, 1 },
+  { 1977,12,12,   1398, 1, 1 },
+  { 1978,12, 1,   1399, 1, 1 },
+  { 1979,11,21,   1400, 1, 1 },
+  { 1980,11, 9,   1401, 1, 1 },
+  { 1981,10,29,   1402, 1, 1 },
+  { 1982,10,18,   1403, 1, 1 },
+  { 1983,10, 8,   1404, 1, 1 },
+  { 1984, 9,26,   1405, 1, 1 },
+  { 1985, 9,16,   1406, 1, 1 },
+  { 1986, 9, 6,   1407, 1, 1 },
+  { 1987, 8,26,   1408, 1, 1 },
+  { 1988, 8,14,   1409, 1, 1 },
+  { 1989, 8, 3,   1410, 1, 1 },
+  { 1990, 7,23,   1411, 1, 1 },
+  { 1991, 7,13,   1412, 1, 1 },
+  { 1992, 7, 2,   1413, 1, 1 },
+  { 1993, 6,21,   1414, 1, 1 },
+  { 1994, 6,11,   1415, 1, 1 },
+  { 1995, 5,31,   1416, 1, 1 },
+  { 1996, 5,19,   1417, 1, 1 },
+  { 1997, 5, 8,   1418, 1, 1 },
+  { 1998, 4,28,   1419, 1, 1 },
+  { 1999, 4,17,   1420, 1, 1 },
+  { 1999, 5,16,   1420, 2, 1 },
+  { 1999, 6,15,   1420, 3, 1 },
+  { 1999, 7,14,   1420, 4, 1 },
+  { 1999, 8,12,   1420, 5, 1 },
+  { 1999, 9,11,   1420, 6, 1 },
+  { 1999,10,10,   1420, 7, 1 },
+  { 1999,11, 9,   1420, 8, 1 },
+  { 1999,12, 9,   1420, 9, 1 },
+  { 2000, 1, 8,   1420,10, 1 },
+  { 2000, 2, 7,   1420,11, 1 },
+  { 2000, 3, 7,   1420,12, 1 },
+  { 2000, 4, 6,   1421, 1, 1 },
+  { 2000, 5, 5,   1421, 2, 1 },
+  { 2000, 6, 3,   1421, 3, 1 },
+  { 2000, 7, 3,   1421, 4, 1 },
+  { 2000, 8, 1,   1421, 5, 1 },
+  { 2000, 8,30,   1421, 6, 1 },
+  { 2000, 9,28,   1421, 7, 1 },
+  { 2000,10,28,   1421, 8, 1 },
+  { 2000,11,27,   1421, 9, 1 },
+  { 2000,12,27,   1421,10, 1 },
+  { 2001, 1,26,   1421,11, 1 },
+  { 2001, 2,24,   1421,12, 1 },
+  { 2001, 3,26,   1422, 1, 1 },
+  { 2001, 4,25,   1422, 2, 1 },
+  { 2001, 5,24,   1422, 3, 1 },
+  { 2001, 6,22,   1422, 4, 1 },
+  { 2001, 7,22,   1422, 5, 1 },
+  { 2001, 8,20,   1422, 6, 1 },
+  { 2001, 9,18,   1422, 7, 1 },
+  { 2001,10,17,   1422, 8, 1 },
+  { 2001,11,16,   1422, 9, 1 },
+  { 2001,12,16,   1422,10, 1 },
+  { 2002, 1,15,   1422,11, 1 },
+  { 2002, 2,13,   1422,12, 1 },
+  { 2002, 3,15,   1423, 1, 1 },
+  { 2002, 4,14,   1423, 2, 1 },
+  { 2002, 5,13,   1423, 3, 1 },
+  { 2002, 6,12,   1423, 4, 1 },
+  { 2002, 7,11,   1423, 5, 1 },
+  { 2002, 8,10,   1423, 6, 1 },
+  { 2002, 9, 8,   1423, 7, 1 },
+  { 2002,10, 7,   1423, 8, 1 },
+  { 2002,11, 6,   1423, 9, 1 },
+  { 2002,12, 5,   1423,10, 1 },
+  { 2003, 1, 4,   1423,11, 1 },
+  { 2003, 2, 2,   1423,12, 1 },
+  { 2003, 3, 4,   1424, 1, 1 },
+  { 2003, 4, 3,   1424, 2, 1 },
+  { 2003, 5, 2,   1424, 3, 1 },
+  { 2003, 6, 1,   1424, 4, 1 },
+  { 2003, 7, 1,   1424, 5, 1 },
+  { 2003, 7,30,   1424, 6, 1 },
+  { 2003, 8,29,   1424, 7, 1 },
+  { 2003, 9,27,   1424, 8, 1 },
+  { 2003,10,26,   1424, 9, 1 },
+  { 2003,11,25,   1424,10, 1 },
+  { 2003,12,24,   1424,11, 1 },
+  { 2004, 1,23,   1424,12, 1 },
+  { 2004, 2,21,   1425, 1, 1 },
+  { 2004, 3,22,   1425, 2, 1 },
+  { 2004, 4,20,   1425, 3, 1 },
+  { 2004, 5,20,   1425, 4, 1 },
+  { 2004, 6,19,   1425, 5, 1 },
+  { 2004, 7,18,   1425, 6, 1 },
+  { 2004, 8,17,   1425, 7, 1 },
+  { 2004, 9,15,   1425, 8, 1 },
+  { 2004,10,15,   1425, 9, 1 },
+  { 2004,11,14,   1425,10, 1 },
+  { 2004,12,13,   1425,11, 1 },
+  { 2005, 1,12,   1425,12, 1 },
+  { 2005, 2,10,   1426, 1, 1 },
+  { 2005, 3,11,   1426, 2, 1 },
+  { 2005, 4,10,   1426, 3, 1 },
+  { 2005, 5, 9,   1426, 4, 1 },
+  { 2005, 6, 8,   1426, 5, 1 },
+  { 2005, 7, 7,   1426, 6, 1 },
+  { 2005, 8, 6,   1426, 7, 1 },
+  { 2005, 9, 5,   1426, 8, 1 },
+  { 2005,10, 4,   1426, 9, 1 },
+  { 2005,11, 3,   1426,10, 1 },
+  { 2005,12, 3,   1426,11, 1 },
+  { 2006, 1, 1,   1426,12, 1 },
+  { 2006, 1,31,   1427, 1, 1 },
+  { 2006, 3, 1,   1427, 2, 1 },
+  { 2006, 3,30,   1427, 3, 1 },
+  { 2006, 4,29,   1427, 4, 1 },
+  { 2006, 5,28,   1427, 5, 1 },
+  { 2006, 6,27,   1427, 6, 1 },
+  { 2006, 7,26,   1427, 7, 1 },
+  { 2006, 8,25,   1427, 8, 1 },
+  { 2006, 9,24,   1427, 9, 1 },
+  { 2006,10,23,   1427,10, 1 },
+  { 2006,11,22,   1427,11, 1 },
+  { 2006,12,22,   1427,12, 1 },
+  { 2007, 1,20,   1428, 1, 1 },
+  { 2007, 2,19,   1428, 2, 1 },
+  { 2007, 3,20,   1428, 3, 1 },
+  { 2007, 4,18,   1428, 4, 1 },
+  { 2007, 5,18,   1428, 5, 1 },
+  { 2007, 6,16,   1428, 6, 1 },
+  { 2007, 7,15,   1428, 7, 1 },
+  { 2007, 8,14,   1428, 8, 1 },
+  { 2007, 9,13,   1428, 9, 1 },
+  { 2007,10,13,   1428,10, 1 },
+  { 2007,11,11,   1428,11, 1 },
+  { 2007,12,11,   1428,12, 1 },
+  { 2008, 1,10,   1429, 1, 1 },
+  { 2008, 2, 8,   1429, 2, 1 },
+  { 2008, 3, 9,   1429, 3, 1 },
+  { 2008, 4, 7,   1429, 4, 1 },
+  { 2008, 5, 6,   1429, 5, 1 },
+  { 2008, 6, 5,   1429, 6, 1 },
+  { 2008, 7, 4,   1429, 7, 1 },
+  { 2008, 8, 2,   1429, 8, 1 },
+  { 2008, 9, 1,   1429, 9, 1 },
+  { 2008,10, 1,   1429,10, 1 },
+  { 2008,10,30,   1429,11, 1 },
+  { 2008,11,29,   1429,12, 1 },
+  { 2008,12,29,   1430, 1, 1 },
+  { 2009, 1,27,   1430, 2, 1 },
+  { 2009, 2,26,   1430, 3, 1 },
+  { 2009, 3,28,   1430, 4, 1 },
+  { 2009, 4,26,   1430, 5, 1 },
+  { 2009, 5,25,   1430, 6, 1 },
+  { 2009, 6,24,   1430, 7, 1 },
+  { 2009, 7,23,   1430, 8, 1 },
+  { 2009, 8,22,   1430, 9, 1 },
+  { 2009, 9,20,   1430,10, 1 },
+  { 2009,10,20,   1430,11, 1 },
+  { 2009,11,18,   1430,12, 1 },
+  { 2009,12,18,   1431, 1, 1 },
+  { 2010, 1,16,   1431, 2, 1 },
+  { 2010, 2,15,   1431, 3, 1 },
+  { 2010, 3,17,   1431, 4, 1 },
+  { 2010, 4,15,   1431, 5, 1 },
+  { 2010, 5,15,   1431, 6, 1 },
+  { 2010, 6,13,   1431, 7, 1 },
+  { 2010, 7,13,   1431, 8, 1 },
+  { 2010, 8,11,   1431, 9, 1 },
+  { 2010, 9,10,   1431,10, 1 },
+  { 2010,10, 9,   1431,11, 1 },
+  { 2010,11, 7,   1431,12, 1 },
+  { 2010,12, 7,   1432, 1, 1 },
+  { 2011, 1, 5,   1432, 2, 1 },
+  { 2011, 2, 4,   1432, 3, 1 },
+  { 2011, 3, 6,   1432, 4, 1 },
+  { 2011, 4, 5,   1432, 5, 1 },
+  { 2011, 5, 4,   1432, 6, 1 },
+  { 2011, 6, 3,   1432, 7, 1 },
+  { 2011, 7, 2,   1432, 8, 1 },
+  { 2011, 8, 1,   1432, 9, 1 },
+  { 2011, 8,30,   1432,10, 1 },
+  { 2011, 9,29,   1432,11, 1 },
+  { 2011,10,28,   1432,12, 1 },
+  { 2011,11,26,   1433, 1, 1 },
+  { 2011,12,26,   1433, 2, 1 },
+  { 2012, 1,24,   1433, 3, 1 },
+  { 2012, 2,23,   1433, 4, 1 },
+  { 2012, 3,24,   1433, 5, 1 },
+  { 2012, 4,22,   1433, 6, 1 },
+  { 2012, 5,22,   1433, 7, 1 },
+  { 2012, 6,21,   1433, 8, 1 },
+  { 2012, 7,20,   1433, 9, 1 },
+  { 2012, 8,19,   1433,10, 1 },
+  { 2012, 9,17,   1433,11, 1 },
+  { 2012,10,17,   1433,12, 1 },
+  { 2012,11,15,   1434, 1, 1 },
+  { 2012,12,14,   1434, 2, 1 },
+  { 2013, 1,13,   1434, 3, 1 },
+  { 2013, 2,11,   1434, 4, 1 },
+  { 2013, 3,13,   1434, 5, 1 },
+  { 2013, 4,11,   1434, 6, 1 },
+  { 2013, 5,11,   1434, 7, 1 },
+  { 2013, 6,10,   1434, 8, 1 },
+  { 2013, 7, 9,   1434, 9, 1 },
+  { 2013, 8, 8,   1434,10, 1 },
+  { 2013, 9, 7,   1434,11, 1 },
+  { 2013,10, 6,   1434,12, 1 },
+  { 2013,11, 4,   1435, 1, 1 },
+  { 2013,12, 4,   1435, 2, 1 },
+  { 2014, 1, 2,   1435, 3, 1 },
+  { 2014, 2, 1,   1435, 4, 1 },
+  { 2014, 3, 2,   1435, 5, 1 },
+  { 2014, 4, 1,   1435, 6, 1 },
+  { 2014, 4,30,   1435, 7, 1 },
+  { 2014, 5,30,   1435, 8, 1 },
+  { 2014, 6,28,   1435, 9, 1 },
+  { 2014, 7,28,   1435,10, 1 },
+  { 2014, 8,27,   1435,11, 1 },
+  { 2014, 9,25,   1435,12, 1 },
+  { 2014,10,25,   1436, 1, 1 },
+  { 2014,11,23,   1436, 2, 1 },
+  { 2014,12,23,   1436, 3, 1 },
+  { 2015, 1,21,   1436, 4, 1 },
+  { 2015, 2,20,   1436, 5, 1 },
+  { 2015, 3,21,   1436, 6, 1 },
+  { 2015, 4,20,   1436, 7, 1 },
+  { 2015, 5,19,   1436, 8, 1 },
+  { 2015, 6,18,   1436, 9, 1 },
+  { 2015, 7,17,   1436,10, 1 },
+  { 2015, 8,16,   1436,11, 1 },
+  { 2015, 9,14,   1436,12, 1 },
+  { 2015,10,14,   1437, 1, 1 },
+  { 2015,11,13,   1437, 2, 1 },
+  { 2015,12,12,   1437, 3, 1 },
+  { 2016, 1,11,   1437, 4, 1 },
+  { 2016, 2,10,   1437, 5, 1 },
+  { 2016, 3,10,   1437, 6, 1 },
+  { 2016, 4, 8,   1437, 7, 1 },
+  { 2016, 5, 8,   1437, 8, 1 },
+  { 2016, 6, 6,   1437, 9, 1 },
+  { 2016, 7, 6,   1437,10, 1 },
+  { 2016, 8, 4,   1437,11, 1 },
+  { 2016, 9, 2,   1437,12, 1 },
+  { 2016,10, 2,   1438, 1, 1 },
+  { 2016,11, 1,   1438, 2, 1 },
+  { 2016,11,30,   1438, 3, 1 },
+  { 2016,12,30,   1438, 4, 1 },
+  { 2017, 1,29,   1438, 5, 1 },
+  { 2017, 2,28,   1438, 6, 1 },
+  { 2017, 3,29,   1438, 7, 1 },
+  { 2017, 4,27,   1438, 8, 1 },
+  { 2017, 5,27,   1438, 9, 1 },
+  { 2017, 6,25,   1438,10, 1 },
+  { 2017, 7,24,   1438,11, 1 },
+  { 2017, 8,23,   1438,12, 1 },
+  { 2017, 9,21,   1439, 1, 1 },
+  { 2017,10,21,   1439, 2, 1 },
+  { 2017,11,19,   1439, 3, 1 },
+  { 2017,12,19,   1439, 4, 1 },
+  { 2018, 1,18,   1439, 5, 1 },
+  { 2018, 2,17,   1439, 6, 1 },
+  { 2018, 3,18,   1439, 7, 1 },
+  { 2018, 4,17,   1439, 8, 1 },
+  { 2018, 5,16,   1439, 9, 1 },
+  { 2018, 6,15,   1439,10, 1 },
+  { 2018, 7,14,   1439,11, 1 },
+  { 2018, 8,12,   1439,12, 1 },
+  { 2018, 9,11,   1440, 1, 1 },
+  { 2019, 8,31,   1441, 1, 1 },
+  { 2020, 8,20,   1442, 1, 1 },
+  { 2021, 8, 9,   1443, 1, 1 },
+  { 2022, 7,30,   1444, 1, 1 },
+  { 2023, 7,19,   1445, 1, 1 },
+  { 2024, 7, 7,   1446, 1, 1 },
+  { 2025, 6,26,   1447, 1, 1 },
+  { 2026, 6,16,   1448, 1, 1 },
+  { 2027, 6, 6,   1449, 1, 1 },
+  { 2028, 5,25,   1450, 1, 1 },
+  { 2029, 5,14,   1451, 1, 1 },
+  { 2030, 5, 4,   1452, 1, 1 },
+  { 2031, 4,23,   1453, 1, 1 },
+  { 2032, 4,11,   1454, 1, 1 },
+  { 2033, 4, 1,   1455, 1, 1 },
+  { 2034, 3,22,   1456, 1, 1 },
+  { 2035, 3,11,   1457, 1, 1 },
+  { 2036, 2,29,   1458, 1, 1 },
+  { 2037, 2,17,   1459, 1, 1 },
+  { 2038, 2, 6,   1460, 1, 1 },
+  { 2039, 1,26,   1461, 1, 1 },
+  { 2040, 1,15,   1462, 1, 1 },
+  { 2041, 1, 4,   1463, 1, 1 },
+  { 2041,12,25,   1464, 1, 1 },
+  { 2042,12,14,   1465, 1, 1 },
+  { 2043,12, 3,   1466, 1, 1 },
+  { 2044,11,21,   1467, 1, 1 },
+  { 2045,11,11,   1468, 1, 1 },
+  { 2046,10,31,   1469, 1, 1 },
+  { 2047,10,21,   1470, 1, 1 },
+  { 2048,10, 9,   1471, 1, 1 },
+  { 2049, 9,29,   1472, 1, 1 },
+  { 2050, 9,18,   1473, 1, 1 },
+  { 2051, 9, 7,   1474, 1, 1 },
+  { 2052, 8,26,   1475, 1, 1 },
+  { 2053, 8,15,   1476, 1, 1 },
+  { 2054, 8, 5,   1477, 1, 1 },
+  { 2055, 7,26,   1478, 1, 1 },
+  { 2056, 7,14,   1479, 1, 1 },
+  { 2057, 7, 3,   1480, 1, 1 },
+  { 2058, 6,22,   1481, 1, 1 },
+  { 2059, 6,11,   1482, 1, 1 },
+  { 2061, 5,21,   1484, 1, 1 },
+  { 2063, 4,30,   1486, 1, 1 },
+  { 2065, 4, 7,   1488, 1, 1 },
+  { 2067, 3,17,   1490, 1, 1 },
+  { 2069, 2,23,   1492, 1, 1 },
+  { 2071, 2, 2,   1494, 1, 1 },
+  { 2073, 1,10,   1496, 1, 1 },
+  { 2074,12,20,   1498, 1, 1 },
+  { 2076,11,28,   1500, 1, 1 },
+  {    0, 0, 0,      0, 0, 0 }, // terminator
+};
+
+static const UChar zoneSA[] = {0x41,0x73,0x69,0x61,0x2F,0x52,0x69,0x79,0x61,0x64,0x68,0}; // "Asia/Riyadh"
+
+void CalendarTest::TestIslamicUmAlQura() {
+
+    UErrorCode status = U_ZERO_ERROR;
+    Locale umalquraLoc("ar_SA@calendar=islamic-umalqura");
+    Locale gregoLoc("ar_SA@calendar=gregorian");
+    TimeZone* tzSA = TimeZone::createTimeZone(UnicodeString(TRUE, zoneSA, -1));
+    Calendar* tstCal = Calendar::createInstance(*((const TimeZone *)tzSA), umalquraLoc, status);
+    Calendar* gregCal = Calendar::createInstance(*((const TimeZone *)tzSA), gregoLoc, status);
+
+    IslamicCalendar* iCal = (IslamicCalendar*)tstCal;
+    if(strcmp(iCal->getType(), "islamic-umalqura") != 0) {
+        errln("wrong type of calendar created - %s", iCal->getType());
+    }
+
+    int32_t firstYear = 1318;
+    int32_t lastYear = 1368;    // just enough to be pretty sure
+    //int32_t lastYear = 1480;    // the whole shootin' match
+
+    tstCal->clear();
+    tstCal->setLenient(FALSE);
+
+    int32_t day=0, month=0, year=0, initDay = 27, initMonth = IslamicCalendar::RAJAB, initYear = 1434;
+
+    for( int32_t startYear = firstYear; startYear <= lastYear; startYear++) {
+        setAndTestWholeYear(tstCal, startYear, status);
+        status = U_ZERO_ERROR;
+    }
+
+    initMonth = IslamicCalendar::RABI_2;
+    initDay = 5;
+    int32_t loopCnt = 25;
+    tstCal->clear();
+    setAndTestCalendar( tstCal, initMonth, initDay, initYear, status);
+    TEST_CHECK_STATUS;
+
+    for(int x=1; x<=loopCnt; x++) {
+        day = tstCal->get(UCAL_DAY_OF_MONTH,status);
+        month = tstCal->get(UCAL_MONTH,status);
+        year = tstCal->get(UCAL_YEAR,status);
+        TEST_CHECK_STATUS;
+        tstCal->roll(UCAL_DAY_OF_MONTH, (UBool)TRUE, status);
+        TEST_CHECK_STATUS;
+    }
+
+    if(day != (initDay + loopCnt - 1) || month != IslamicCalendar::RABI_2 || year != 1434)
+      errln("invalid values for RABI_2 date after roll of %d", loopCnt);
+
+    status = U_ZERO_ERROR;
+    tstCal->clear();
+    initMonth = 2;
+    initDay = 30;
+    setAndTestCalendar( tstCal, initMonth, initDay, initYear, status);
+    if(U_SUCCESS(status)) {
+        errln("error NOT detected status %i",status);
+        errln("      init values:\tmonth %i\tday %i\tyear %i", initMonth, initDay, initYear);
+        int32_t day = tstCal->get(UCAL_DAY_OF_MONTH, status);
+        int32_t month = tstCal->get(UCAL_MONTH, status);
+        int32_t year = tstCal->get(UCAL_YEAR, status);
+        errln("values post set():\tmonth %i\tday %i\tyear %i",month, day, year);
+    }
+
+    status = U_ZERO_ERROR;
+    tstCal->clear();
+    initMonth = 3;
+    initDay = 30;
+    setAndTestCalendar( tstCal, initMonth, initDay, initYear, status);
+    TEST_CHECK_STATUS;
+
+    SimpleDateFormat* formatter = new SimpleDateFormat("yyyy-MM-dd", Locale::getUS(), status);
+    UDate date = formatter->parse("1975-05-06", status);
+    Calendar* is_cal = Calendar::createInstance(umalquraLoc, status);
+    is_cal->setTime(date, status);
+    int32_t is_day = is_cal->get(UCAL_DAY_OF_MONTH,status);
+    int32_t is_month = is_cal->get(UCAL_MONTH,status);
+    int32_t is_year = is_cal->get(UCAL_YEAR,status);
+    TEST_CHECK_STATUS;
+    if(is_day != 24 || is_month != IslamicCalendar::RABI_2 || is_year != 1395)
+        errln("unexpected conversion date month %i not %i or day %i not 24 or year %i not 1395", is_month, IslamicCalendar::RABI_2, is_day, is_year);
+
+    UDate date2 = is_cal->getTime(status);
+    TEST_CHECK_STATUS;
+    if(date2 != date) {
+        errln("before(%f) and after(%f) dates don't match up!",date, date2);
+    }
+
+    // check against data
+    const GregoUmmAlQuraMap* guMapPtr;
+    gregCal->clear();
+    tstCal->clear();
+    for (guMapPtr = guMappings; guMapPtr->gYear != 0; guMapPtr++) {
+        status = U_ZERO_ERROR;
+        gregCal->set(guMapPtr->gYear, guMapPtr->gMon - 1, guMapPtr->gDay, 12, 0);
+        date = gregCal->getTime(status);
+        tstCal->setTime(date, status);
+        int32_t uYear = tstCal->get(UCAL_YEAR, status);
+        int32_t uMon = tstCal->get(UCAL_MONTH, status) + 1;
+        int32_t uDay = tstCal->get(UCAL_DATE, status);
+        if(U_FAILURE(status)) {
+            errln("For gregorian %4d-%02d-%02d, get status %s",
+                    guMapPtr->gYear, guMapPtr->gMon, guMapPtr->gDay, u_errorName(status) );
+        } else if (uYear != guMapPtr->uYear || uMon != guMapPtr->uMon || uDay != guMapPtr->uDay) {
+            errln("For gregorian %4d-%02d-%02d, expect umalqura %4d-%02d-%02d, get %4d-%02d-%02d",
+                    guMapPtr->gYear, guMapPtr->gMon, guMapPtr->gDay,
+                    guMapPtr->uYear, guMapPtr->uMon, guMapPtr->uDay, uYear, uMon, uDay );
+        }
+    }
+
+    delete is_cal;
+    delete formatter;
+    delete gregCal;
+    delete tstCal;
+    delete tzSA;
+}
+
+void CalendarTest::TestIslamicTabularDates() {
+    UErrorCode status = U_ZERO_ERROR;
+    Locale islamicLoc("ar_SA@calendar=islamic-civil");
+    Locale tblaLoc("ar_SA@calendar=islamic-tbla");
+    SimpleDateFormat* formatter = new SimpleDateFormat("yyyy-MM-dd", Locale::getUS(), status);
+    UDate date = formatter->parse("1975-05-06", status);
+
+    Calendar* tstCal = Calendar::createInstance(islamicLoc, status);
+    tstCal->setTime(date, status);
+    int32_t is_day = tstCal->get(UCAL_DAY_OF_MONTH,status);
+    int32_t is_month = tstCal->get(UCAL_MONTH,status);
+    int32_t is_year = tstCal->get(UCAL_YEAR,status);
+    TEST_CHECK_STATUS;
+    delete tstCal;
+
+    tstCal = Calendar::createInstance(tblaLoc, status);
+    tstCal->setTime(date, status);
+    int32_t tbla_day = tstCal->get(UCAL_DAY_OF_MONTH,status);
+    int32_t tbla_month = tstCal->get(UCAL_MONTH,status);
+    int32_t tbla_year = tstCal->get(UCAL_YEAR,status);
+    TEST_CHECK_STATUS;
+
+    if(tbla_month != is_month || tbla_year != is_year)
+        errln("unexpected difference between islamic and tbla month %d : %d and/or year %d : %d",tbla_month,is_month,tbla_year,is_year);
+
+    if(tbla_day - is_day != 1)
+        errln("unexpected day difference between islamic and tbla: %d : %d ",tbla_day,is_day);
+    delete tstCal;
+    delete formatter;
+}
+
+void CalendarTest::TestHebrewMonthValidation() {
+    UErrorCode status = U_ZERO_ERROR;
+    LocalPointer<Calendar>  cal(Calendar::createInstance(Locale::createFromName("he_IL@calendar=hebrew"), status));
+    if (failure(status, "Calendar::createInstance, locale:he_IL@calendar=hebrew", TRUE)) return;
+    Calendar *pCal = cal.getAlias();
+
+    UDate d;
+    pCal->setLenient(FALSE);
+
+    // 5776 is a leap year and has month Adar I
+    pCal->set(5776, HebrewCalendar::ADAR_1, 1);
+    d = pCal->getTime(status);
+    if (U_FAILURE(status)) {
+        errln("Fail: 5776 Adar I 1 is a valid date.");
+    }
+    status = U_ZERO_ERROR;
+
+    // 5777 is NOT a lear year and does not have month Adar I
+    pCal->set(5777, HebrewCalendar::ADAR_1, 1);
+    d = pCal->getTime(status);
+    (void)d;
+    if (status == U_ILLEGAL_ARGUMENT_ERROR) {
+        logln("Info: U_ILLEGAL_ARGUMENT_ERROR, because 5777 Adar I 1 is not a valid date.");
+    } else {
+        errln("Fail: U_ILLEGAL_ARGUMENT_ERROR should be set for input date 5777 Adar I 1.");
+    }
+}
+
+void CalendarTest::TestWeekData() {
+    // Each line contains two locales using the same set of week rule data.
+    const char* LOCALE_PAIRS[] = {
+        "en",       "en_US",
+        "de",       "de_DE",
+        "de_DE",    "en_DE",
+        "en_GB",    "und_GB",
+        "ar_EG",    "en_EG",
+        "ar_SA",    "fr_SA",
+        0
+    };
+
+    UErrorCode status;
+
+    for (int32_t i = 0; LOCALE_PAIRS[i] != 0; i += 2) {
+        status = U_ZERO_ERROR;
+        LocalPointer<Calendar>  cal1(Calendar::createInstance(LOCALE_PAIRS[i], status));
+        LocalPointer<Calendar>  cal2(Calendar::createInstance(LOCALE_PAIRS[i + 1], status));
+        TEST_CHECK_STATUS_LOCALE(LOCALE_PAIRS[i]);
+
+        // First day of week
+        UCalendarDaysOfWeek dow1 = cal1->getFirstDayOfWeek(status);
+        UCalendarDaysOfWeek dow2 = cal2->getFirstDayOfWeek(status);
+        TEST_CHECK_STATUS;
+        TEST_ASSERT(dow1 == dow2);
+
+        // Minimum days in first week
+        uint8_t minDays1 = cal1->getMinimalDaysInFirstWeek();
+        uint8_t minDays2 = cal2->getMinimalDaysInFirstWeek();
+        TEST_ASSERT(minDays1 == minDays2);
+
+        // Weekdays and Weekends
+        for (int32_t d = UCAL_SUNDAY; d <= UCAL_SATURDAY; d++) {
+            status = U_ZERO_ERROR;
+            UCalendarWeekdayType wdt1 = cal1->getDayOfWeekType((UCalendarDaysOfWeek)d, status);
+            UCalendarWeekdayType wdt2 = cal2->getDayOfWeekType((UCalendarDaysOfWeek)d, status);
+            TEST_CHECK_STATUS;
+            TEST_ASSERT(wdt1 == wdt2);
+        }
+    }
+}
+
 typedef struct {
     const char* zone;
     const CalFields base;
@@ -2751,7 +3469,7 @@ static const TestAddAcrossZoneTransitionData AAZTDATA[] =
 {
     // Time zone                Base wall time                      day(s)  Skipped time options
     //                          Expected wall time
-    
+
     // Add 1 day, from the date before DST transition
     {"America/Los_Angeles",     CalFields(2014,3,8,1,59,59,999),    1,      UCAL_WALLTIME_FIRST,
                                 CalFields(2014,3,9,1,59,59,999)},
@@ -2908,7 +3626,7 @@ void CalendarTest::TestAddAcrossZoneTransition() {
             char buf[32];
             const char *optDisp = AAZTDATA[i].skippedWTOpt == UCAL_WALLTIME_FIRST ? "FIRST" :
                     AAZTDATA[i].skippedWTOpt == UCAL_WALLTIME_LAST ? "LAST" : "NEXT_VALID";
-            errln(UnicodeString("Error: base:") + AAZTDATA[i].base.toString(buf, sizeof(buf)) + ", tz:" + AAZTDATA[i].zone
+            dataerrln(UnicodeString("Error: base:") + AAZTDATA[i].base.toString(buf, sizeof(buf)) + ", tz:" + AAZTDATA[i].zone
                         + ", delta:" + AAZTDATA[i].deltaDays + " day(s), opt:" + optDisp
                         + ", result:" + res.toString(buf, sizeof(buf))
                         + " - expected:" + AAZTDATA[i].expected.toString(buf, sizeof(buf)));
@@ -2916,6 +3634,81 @@ void CalendarTest::TestAddAcrossZoneTransition() {
     }
 }
 
+// Data in a separate file (Gregorian to Chinese lunar map)
+#define INCLUDED_FROM_CALTEST_CPP
+#include "caltestdata.h"
+
+void CalendarTest::TestChineseCalendarMapping() {
+    UErrorCode status = U_ZERO_ERROR;
+    LocalPointer<TimeZone> zone(TimeZone::createTimeZone(UnicodeString("China")));
+    Locale locEnCalGregory = Locale::createFromName("en@calendar=gregorian");
+    Locale locEnCalChinese = Locale::createFromName("en@calendar=chinese");
+    LocalPointer<Calendar>  calGregory(Calendar::createInstance(zone->clone(), locEnCalGregory, status));
+    LocalPointer<Calendar>  calChinese(Calendar::createInstance(zone.orphan(), locEnCalChinese, status));
+    if ( U_FAILURE(status) ) {
+        errln("Fail: Calendar::createInstance fails for en with calendar=gregorian or calendar=chinese: %s", u_errorName(status));
+    } else {
+        const GregoToLunar * mapPtr = gregoToLunar; // in "caltestdata.h" included above
+        calGregory->clear();
+        calChinese->clear();
+        for (; mapPtr->gyr != 0; mapPtr++) {
+            status = U_ZERO_ERROR;
+            calGregory->set(mapPtr->gyr, mapPtr->gmo - 1, mapPtr->gda, 8, 0);
+            UDate date = calGregory->getTime(status);
+            calChinese->setTime(date, status);
+            if ( U_FAILURE(status) ) {
+                errln("Fail: for Gregorian %4d-%02d-%02d, calGregory->getTime or calChinese->setTime reports: %s",
+                        mapPtr->gyr, mapPtr->gmo, mapPtr->gda, u_errorName(status));
+                continue;
+            }
+            int32_t era = calChinese->get(UCAL_ERA, status);
+            int32_t yr  = calChinese->get(UCAL_YEAR, status);
+            int32_t mo  = calChinese->get(UCAL_MONTH, status) + 1;
+            int32_t lp  = calChinese->get(UCAL_IS_LEAP_MONTH, status);
+            int32_t da  = calChinese->get(UCAL_DATE, status);
+            if ( U_FAILURE(status) ) {
+                errln("Fail: for Gregorian %4d-%02d-%02d, calChinese->get (for era, yr, mo, leapmo, da) reports: %s",
+                        mapPtr->gyr, mapPtr->gmo, mapPtr->gda, u_errorName(status));
+                continue;
+            }
+            int32_t cmo = mapPtr->cmo & (~L);
+            int32_t clp = (mapPtr->cmo & L) != 0;
+            if (yr != mapPtr->cyr || mo != cmo || lp != clp || da != mapPtr->cda) {
+                errln("Fail: for Gregorian %4d-%02d-%02d, expected Chinese %2d-%02d(%d)-%02d, got %2d-%02d(%d)-%02d",
+                        mapPtr->gyr, mapPtr->gmo, mapPtr->gda, mapPtr->cyr, cmo, clp, mapPtr->cda, yr, mo, lp, da);
+                continue;
+            }
+            // If Grego->Chinese worked, try reverse mapping
+            calChinese->set(UCAL_ERA, era);
+            calChinese->set(UCAL_YEAR, mapPtr->cyr);
+            calChinese->set(UCAL_MONTH, cmo - 1);
+            calChinese->set(UCAL_IS_LEAP_MONTH, clp);
+            calChinese->set(UCAL_DATE, mapPtr->cda);
+            calChinese->set(UCAL_HOUR_OF_DAY, 8);
+            date = calChinese->getTime(status);
+            calGregory->setTime(date, status);
+            if ( U_FAILURE(status) ) {
+                errln("Fail: for Chinese %2d-%02d(%d)-%02d, calChinese->getTime or calGregory->setTime reports: %s",
+                        mapPtr->cyr, cmo, clp, mapPtr->cda, u_errorName(status));
+                continue;
+            }
+            yr  = calGregory->get(UCAL_YEAR, status);
+            mo  = calGregory->get(UCAL_MONTH, status) + 1;
+            da  = calGregory->get(UCAL_DATE, status);
+            if ( U_FAILURE(status) ) {
+                errln("Fail: for Chinese %2d-%02d(%d)-%02d, calGregory->get (for yr, mo, da) reports: %s",
+                        mapPtr->cyr, cmo, clp, mapPtr->cda, u_errorName(status));
+                continue;
+            }
+            if (yr != mapPtr->gyr || mo != mapPtr->gmo || da != mapPtr->gda) {
+                errln("Fail: for Chinese %2d-%02d(%d)-%02d, Gregorian %4d-%02d-%02d, got %4d-%02d-%02d",
+                        mapPtr->cyr, cmo, clp, mapPtr->cda, mapPtr->gyr, mapPtr->gmo, mapPtr->gda, yr, mo, da);
+                continue;
+            }
+        }
+    }
+}
+
 #endif /* #if !UCONFIG_NO_FORMATTING */
 
 //eof