]> granicus.if.org Git - icu/commitdiff
ICU-9616 Add DangiCalendar & tests, port from J to C
authorPeter Edberg <pedberg@unicode.org>
Mon, 18 Feb 2013 23:36:57 +0000 (23:36 +0000)
committerPeter Edberg <pedberg@unicode.org>
Mon, 18 Feb 2013 23:36:57 +0000 (23:36 +0000)
X-SVN-Rev: 33267

12 files changed:
.gitattributes
icu4c/source/i18n/Makefile.in
icu4c/source/i18n/calendar.cpp
icu4c/source/i18n/chnsecal.cpp
icu4c/source/i18n/chnsecal.h
icu4c/source/i18n/dangical.cpp [new file with mode: 0644]
icu4c/source/i18n/dangical.h [new file with mode: 0644]
icu4c/source/i18n/i18n.vcxproj
icu4c/source/i18n/i18n.vcxproj.filters
icu4c/source/test/intltest/callimts.cpp
icu4c/source/test/intltest/dtfmttst.cpp
icu4c/source/test/testdata/calendar.txt

index e484f7d3f6710199de08dcc490da7e5e886598a5..a3412d4c5ddd687c73b62a2459be3cc75f337090 100644 (file)
@@ -123,6 +123,8 @@ icu4c/source/data/zone/ms_SG.txt -text
 icu4c/source/data/zone/pool.res -text
 icu4c/source/extra/uconv/uconv.vcxproj -text
 icu4c/source/extra/uconv/uconv.vcxproj.filters -text
+icu4c/source/i18n/dangical.cpp -text
+icu4c/source/i18n/dangical.h -text
 icu4c/source/i18n/i18n.vcxproj -text
 icu4c/source/i18n/i18n.vcxproj.filters -text
 icu4c/source/i18n/region.cpp -text
index ffb82c0ef4f3ec7c28a8d52389c0d2f4fabbe99e..d19e770e50792b90fe9e6a563fcf7876ad62527c 100644 (file)
@@ -69,7 +69,7 @@ choicfmt.o datefmt.o smpdtfmt.o reldtfmt.o dtfmtsym.o udat.o dtptngen.o udatpg.o
 nfrs.o nfrule.o nfsubs.o rbnf.o numsys.o ucsdet.o \
 ucal.o calendar.o gregocal.o timezone.o simpletz.o olsontz.o \
 astro.o taiwncal.o buddhcal.o persncal.o islamcal.o japancal.o gregoimp.o hebrwcal.o \
-indiancal.o chnsecal.o cecal.o coptccal.o ethpccal.o \
+indiancal.o chnsecal.o cecal.o coptccal.o dangical.o ethpccal.o \
 coleitr.o coll.o tblcoll.o sortkey.o bocsu.o ucoleitr.o \
 ucol.o ucol_res.o ucol_bld.o ucol_sit.o ucol_tok.o ucol_wgt.o ucol_cnt.o ucol_elm.o \
 strmatch.o usearch.o search.o stsearch.o \
index 656b92f4242d06541b2753550062dcca89efea08..bb5e788a296561062a06b56883d8f94cc3a3f636 100644 (file)
@@ -1,6 +1,6 @@
 /*
 *******************************************************************************
-* Copyright (C) 1997-2012, International Business Machines Corporation and    *
+* Copyright (C) 1997-2013, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
@@ -45,6 +45,7 @@
 #include "indiancal.h"
 #include "chnsecal.h"
 #include "coptccal.h"
+#include "dangical.h"
 #include "ethpccal.h"
 #include "unicode/calendar.h"
 #include "cpputils.h"
@@ -164,6 +165,7 @@ static const char * const gCalTypes[] = {
     "ethiopic",
     "ethiopic-amete-alem",
     "iso8601",
+    "dangi",
     NULL
 };
 
@@ -183,7 +185,8 @@ typedef enum ECalType {
     CALTYPE_COPTIC,
     CALTYPE_ETHIOPIC,
     CALTYPE_ETHIOPIC_AMETE_ALEM,
-    CALTYPE_ISO8601
+    CALTYPE_ISO8601,
+    CALTYPE_DANGI
 } ECalType;
 
 U_NAMESPACE_BEGIN
@@ -341,6 +344,9 @@ static Calendar *createStandardCalendar(ECalType calType, const Locale &loc, UEr
             cal->setFirstDayOfWeek(UCAL_MONDAY);
             cal->setMinimalDaysInFirstWeek(4);
             break;
+        case CALTYPE_DANGI:
+            cal = new DangiCalendar(loc, status);
+            break;
         default:
             status = U_UNSUPPORTED_ERROR;
     }
index 4c75119b018efdb4174d902fecbb46c3abfec5bd..129d18bbd874702725d47c40bfde2e77e15af574 100644 (file)
@@ -127,7 +127,7 @@ ChineseCalendar::ChineseCalendar(const Locale& aLocale, UErrorCode& success)
 }
 
 ChineseCalendar::ChineseCalendar(const Locale& aLocale, int32_t epochYear,
-                                TimeZone* zoneAstroCalc, UErrorCode &success)
+                                const TimeZone* zoneAstroCalc, UErrorCode &success)
 :   Calendar(TimeZone::createDefault(), aLocale, success),
     isLeapYear(FALSE),
     fEpochYear(epochYear),
index 4c67a0aee8fd118f9ee9557b283f1cd869558d4b..ce4f95c30b3b56dc5a02cd8149b13fc78390b31f 100644 (file)
@@ -94,7 +94,7 @@ U_NAMESPACE_BEGIN
  * @author Alan Liu
  * @internal
  */
-class ChineseCalendar : public Calendar {
+class U_I18N_API ChineseCalendar : public Calendar {
  public:
   //-------------------------------------------------------------------------
   // Constructors...
@@ -126,7 +126,7 @@ class ChineseCalendar : public Calendar {
    *                        if successful, will not be changed to an error value.
    * @internal
    */
-  ChineseCalendar(const Locale& aLocale, int32_t epochYear, TimeZone* zoneAstroCalc, UErrorCode &success);
+  ChineseCalendar(const Locale& aLocale, int32_t epochYear, const TimeZone* zoneAstroCalc, UErrorCode &success);
 
  public:
   /**
@@ -308,6 +308,3 @@ U_NAMESPACE_END
 
 #endif
 #endif
-
-
-
diff --git a/icu4c/source/i18n/dangical.cpp b/icu4c/source/i18n/dangical.cpp
new file mode 100644 (file)
index 0000000..5c86cff
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ ******************************************************************************
+ * Copyright (C) 2013, International Business Machines Corporation
+ * and others. All Rights Reserved.
+ ******************************************************************************
+ *
+ * File DANGICAL.CPP
+ *****************************************************************************
+ */
+
+#include "chnsecal.h"
+#include "dangical.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "umutex.h"
+#include "gregoimp.h" // Math
+#include "unicode/rbtz.h"
+#include "unicode/tzrule.h"
+#include "ucln_in.h"
+
+// --- The cache --
+static UMutex dangiLock = U_MUTEX_INITIALIZER;
+static icu::TimeZone *gDangiCalendarZoneAstroCalc = NULL;
+static UBool gDangiCalendarZoneAstroCalcInitialized = FALSE;
+
+/**
+ * The start year of the Korean traditional calendar (Dan-gi) is the inaugural
+ * year of Dan-gun (BC 2333).
+ */
+static const int32_t DANGI_EPOCH_YEAR = -2332; // Gregorian year
+
+U_CDECL_BEGIN
+static UBool calendar_dangi_cleanup(void) {
+    if (gDangiCalendarZoneAstroCalc) {
+        delete gDangiCalendarZoneAstroCalc;
+        gDangiCalendarZoneAstroCalc = NULL;
+    }
+    gDangiCalendarZoneAstroCalcInitialized = FALSE;
+    return TRUE;
+}
+U_CDECL_END
+
+U_NAMESPACE_BEGIN
+
+// Implementation of the DangiCalendar class
+
+//-------------------------------------------------------------------------
+// Constructors...
+//-------------------------------------------------------------------------
+
+DangiCalendar::DangiCalendar(const Locale& aLocale, UErrorCode& success)
+:   ChineseCalendar(aLocale, DANGI_EPOCH_YEAR, getDangiCalZoneAstroCalc(), success)
+{
+}
+
+DangiCalendar::DangiCalendar (const DangiCalendar& other) 
+: ChineseCalendar(other)
+{
+}
+
+DangiCalendar::~DangiCalendar()
+{
+}
+
+Calendar*
+DangiCalendar::clone() const
+{
+    return new DangiCalendar(*this);
+}
+
+const char *DangiCalendar::getType() const { 
+    return "dangi";
+}
+
+/**
+ * The time zone used for performing astronomical computations for
+ * Dangi calendar. In Korea various timezones have been used historically 
+ * (cf. http://www.math.snu.ac.kr/~kye/others/lunar.html): 
+ *  
+ *            - 1908/04/01: GMT+8 
+ * 1908/04/01 - 1911/12/31: GMT+8.5 
+ * 1912/01/01 - 1954/03/20: GMT+9 
+ * 1954/03/21 - 1961/08/09: GMT+8.5 
+ * 1961/08/10 -           : GMT+9 
+ *  
+ * Note that, in 1908-1911, the government did not apply the timezone change 
+ * but used GMT+8. In addition, 1954-1961's timezone change does not affect 
+ * the lunar date calculation. Therefore, the following simpler rule works: 
+ *   
+ * -1911: GMT+8 
+ * 1912-: GMT+9 
+ *  
+ * Unfortunately, our astronomer's approximation doesn't agree with the 
+ * references (http://www.math.snu.ac.kr/~kye/others/lunar.html and 
+ * http://astro.kasi.re.kr/Life/ConvertSolarLunarForm.aspx?MenuID=115) 
+ * in 1897/7/30. So the following ad hoc fix is used here: 
+ *  
+ *     -1896: GMT+8 
+ *      1897: GMT+7 
+ * 1898-1911: GMT+8 
+ * 1912-    : GMT+9 
+ */
+const TimeZone* DangiCalendar::getDangiCalZoneAstroCalc(void) const {
+    UBool initialized;
+    UMTX_CHECK(&dangiLock, gDangiCalendarZoneAstroCalcInitialized, initialized);
+    if (!initialized) {
+        umtx_lock(&dangiLock);
+        {
+            if (!gDangiCalendarZoneAstroCalcInitialized) {
+                const UDate millis1897[] = { (UDate)((1897 - 1970) * 365 * kOneDay) }; // some days of error is not a problem here
+                const UDate millis1898[] = { (UDate)((1898 - 1970) * 365 * kOneDay) }; // some days of error is not a problem here
+                const UDate millis1912[] = { (UDate)((1912 - 1970) * 365 * kOneDay) }; // this doesn't create an issue for 1911/12/20
+                InitialTimeZoneRule* initialTimeZone = new InitialTimeZoneRule(UnicodeString("GMT+8"), 8*kOneHour, 0);
+                TimeZoneRule* rule1897 = new TimeArrayTimeZoneRule(UnicodeString("Korean 1897"), 7*kOneHour, 0, millis1897, 1, DateTimeRule::STANDARD_TIME);
+                TimeZoneRule* rule1898to1911 = new TimeArrayTimeZoneRule(UnicodeString("Korean 1898-1911"), 8*kOneHour, 0, millis1898, 1, DateTimeRule::STANDARD_TIME);
+                TimeZoneRule* ruleFrom1912 = new TimeArrayTimeZoneRule(UnicodeString("Korean 1912-"), 9*kOneHour, 0, millis1912, 1, DateTimeRule::STANDARD_TIME);
+                UErrorCode status = U_ZERO_ERROR;
+                RuleBasedTimeZone* dangiCalZoneAstroCalc = new RuleBasedTimeZone(UnicodeString("KOREA_ZONE"), initialTimeZone); // adopts initialTimeZone
+                dangiCalZoneAstroCalc->addTransitionRule(rule1897, status); // adopts rule1897
+                dangiCalZoneAstroCalc->addTransitionRule(rule1898to1911, status);
+                dangiCalZoneAstroCalc->addTransitionRule(ruleFrom1912, status);
+                dangiCalZoneAstroCalc->complete(status);
+                if (U_SUCCESS(status)) {
+                    gDangiCalendarZoneAstroCalc = dangiCalZoneAstroCalc;
+                } else {
+                    delete dangiCalZoneAstroCalc;
+                    gDangiCalendarZoneAstroCalc = NULL;
+                }
+                gDangiCalendarZoneAstroCalcInitialized = TRUE;
+                ucln_i18n_registerCleanup(UCLN_I18N_CHINESE_CALENDAR, calendar_dangi_cleanup);
+            }
+        }
+        umtx_unlock(&dangiLock);
+    }
+    return gDangiCalendarZoneAstroCalc;
+}
+
+UOBJECT_DEFINE_RTTI_IMPLEMENTATION(DangiCalendar)
+
+U_NAMESPACE_END
+
+#endif
+
diff --git a/icu4c/source/i18n/dangical.h b/icu4c/source/i18n/dangical.h
new file mode 100644 (file)
index 0000000..76dd3d4
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+ *****************************************************************************
+ * Copyright (C) 2013, International Business Machines Corporation
+ * and others. All Rights Reserved.
+ *****************************************************************************
+ *
+ * File DANGICAL.H
+ *****************************************************************************
+ */
+
+#ifndef DANGICAL_H
+#define DANGICAL_H
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/calendar.h"
+#include "unicode/timezone.h"
+#include "chnsecal.h"
+
+U_NAMESPACE_BEGIN
+
+/**
+ * <p><code>DangiCalendar</code> is a concrete subclass of {@link Calendar}
+ * that implements a traditional Korean lunisolar calendar.</p>
+ *
+ * <p>DangiCalendar usually should be instantiated using 
+ * {@link com.ibm.icu.util.Calendar#getInstance(ULocale)} passing in a <code>ULocale</code>
+ * with the tag <code>"@calendar=dangi"</code>.</p>
+ *
+ * @internal
+ */
+class DangiCalendar : public ChineseCalendar {
+ public:
+  //-------------------------------------------------------------------------
+  // Constructors...
+  //-------------------------------------------------------------------------
+
+  /**
+   * Constructs a DangiCalendar based on the current time in the default time zone
+   * with the given locale.
+   *
+   * @param aLocale  The given locale.
+   * @param success  Indicates the status of DangiCalendar object construction.
+   *                 Returns U_ZERO_ERROR if constructed successfully.
+   * @internal
+   */
+  DangiCalendar(const Locale& aLocale, UErrorCode &success);
+
+  /**
+   * Copy Constructor
+   * @internal
+   */
+  DangiCalendar(const DangiCalendar& other);
+
+  /**
+   * Destructor.
+   * @internal
+   */
+  virtual ~DangiCalendar();
+
+  /**
+   * Clone.
+   * @internal
+   */
+  virtual Calendar* clone() const;
+
+  //----------------------------------------------------------------------
+  // Internal methods & astronomical calculations
+  //----------------------------------------------------------------------
+
+ private:
+
+  const TimeZone* getDangiCalZoneAstroCalc(void) const;
+
+  // UObject stuff
+ public: 
+  /**
+   * @return   The class ID for this object. All objects of a given class have the
+   *           same class ID. Objects of other classes have different class IDs.
+   * @internal
+   */
+  virtual UClassID getDynamicClassID(void) const;
+
+  /**
+   * Return the class ID for this class. This is useful only for comparing to a return
+   * value from getDynamicClassID(). For example:
+   *
+   *      Base* polymorphic_pointer = createPolymorphicObject();
+   *      if (polymorphic_pointer->getDynamicClassID() ==
+   *          Derived::getStaticClassID()) ...
+   *
+   * @return   The class ID for all objects of this class.
+   * @internal
+   */
+  U_I18N_API static UClassID U_EXPORT2 getStaticClassID(void);
+
+  /**
+   * return the calendar type, "dangi".
+   *
+   * @return calendar type
+   * @internal
+   */
+  const char * getType() const;
+
+
+ private:
+  DangiCalendar(); // default constructor not implemented
+};
+
+U_NAMESPACE_END
+
+#endif
+#endif
+
+
+
index d583f7bbb260ca6f22ebb994f434b54453f812a4..9e22d552919bdc46dbc373f0fa40b2c7ae55442b 100644 (file)
     <ClCompile Include="currfmt.cpp" />\r
     <ClCompile Include="currpinf.cpp" />\r
     <ClCompile Include="currunit.cpp" />\r
+    <ClCompile Include="dangical.cpp" />\r
     <ClCompile Include="datefmt.cpp" />\r
     <ClCompile Include="dcfmtsym.cpp" />\r
     <ClCompile Include="decContext.c" />\r
 </Command>\r
       <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">..\..\include\unicode\%(Filename)%(Extension);%(Outputs)</Outputs>\r
     </CustomBuild>\r
+    <ClInclude Include="dangical.h" />\r
     <CustomBuild Include="unicode\datefmt.h">\r
       <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">copy "%(FullPath)" ..\..\include\unicode\r
 </Command>\r
index 55688468fe47e7871995750498ba573f3b764670..6138b543eed1404effee14fa5f1f35bb931ed50f 100644 (file)
     <ClCompile Include="currunit.cpp">\r
       <Filter>formatting</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="dangical.cpp">\r
+      <Filter>formatting</Filter>\r
+    </ClCompile>\r
     <ClCompile Include="datefmt.cpp">\r
       <Filter>formatting</Filter>\r
     </ClCompile>\r
     <ClInclude Include="currfmt.h">\r
       <Filter>formatting</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="dangical.h">\r
+      <Filter>formatting</Filter>\r
+    </ClInclude>\r
     <ClInclude Include="decContext.h">\r
       <Filter>formatting</Filter>\r
     </ClInclude>\r
index 6a2dd9e782414fad84b3d18fde237dbf1f846b78..a7d9bf5a7799c0595a014f213ef9407778367ea2 100644 (file)
@@ -1,6 +1,6 @@
 /***********************************************************************
  * COPYRIGHT: 
- * Copyright (c) 1997-2011, International Business Machines Corporation
+ * Copyright (c) 1997-2013, International Business Machines Corporation
  * and others. All Rights Reserved.
  ***********************************************************************/
 
@@ -159,6 +159,7 @@ CalendarLimitTest::TestLimits(void) {
         {"islamic",         FALSE,      DEFAULT_START, 800000}, // Approx. 2250 years from now, after which some rounding errors occur in Islamic calendar
         {"hebrew",          TRUE,       DEFAULT_START, DEFAULT_END},
         {"chinese",         TRUE,       DEFAULT_START, DEFAULT_END},
+        {"dangi",           TRUE,       DEFAULT_START, DEFAULT_END},
         {"indian",          FALSE,      DEFAULT_START, DEFAULT_END},
         {"coptic",          FALSE,      DEFAULT_START, DEFAULT_END},
         {"ethiopic",        FALSE,      DEFAULT_START, DEFAULT_END},
index ebb82df86c4a393b728f5a1548ea8c63775fc96c..06e7fa97767c6654d0b3f6511a5a9c0a18f66630 100644 (file)
@@ -3908,6 +3908,14 @@ void DateFormatTest::TestMonthPatterns()
                                                             CharsToUnicodeString("2 s\\u00ECyu\\u00E8bis ren-chen"),
                                                             CharsToUnicodeString("2 w\\u01D4yu\\u00E8 ren-chen") } },
         { "fr@calendar=chinese",      DateFormat::kShort, { UnicodeString("2/4/29"),        UnicodeString("2/4bis/29"),             UnicodeString("2/5/29") } },
+        { "en@calendar=dangi",        DateFormat::kLong,  { UnicodeString("Month3bis 2, 29"), UnicodeString("Month4 2, 29"),      UnicodeString("Month5 1, 29") } },
+        { "en@calendar=dangi",        DateFormat::kShort, { UnicodeString("3bis/2/29"),        UnicodeString("4/2/29"),             UnicodeString("5/1/29") } },
+        { "ko@calendar=dangi",        DateFormat::kLong,  { CharsToUnicodeString("\\uC784\\uC9C4\\uB144 3bis\\uC6D4 2\\uC77C"),
+                                                            CharsToUnicodeString("\\uC784\\uC9C4\\uB144 4\\uC6D4 2\\uC77C"),
+                                                            CharsToUnicodeString("\\uC784\\uC9C4\\uB144 5\\uC6D4 1\\uC77C") } },
+        { "ko@calendar=dangi",        DateFormat::kShort, { CharsToUnicodeString("29. 3bis. 2."),
+                                                            CharsToUnicodeString("29. 4. 2."),
+                                                            CharsToUnicodeString("29. 5. 1.") } },
         // terminator
         { NULL,                       0,                  { UnicodeString(""), UnicodeString(""), UnicodeString("") } }
     };
index d0653a3bdec2cc3e7e4354c588d3735eed54d32c..ec72728e173f979ede51081bb383984f675a3b9f 100644 (file)
@@ -1,4 +1,4 @@
-// Copyright (c) 2008-2012 International Business Machines
+// Copyright (c) 2008-2013 International Business Machines
 // Corporation and others. All Rights Reserved.
 calendar:table(nofallback) {
     Info {
@@ -115,6 +115,58 @@ calendar:table(nofallback) {
                     "EXTENDED_YEAR=4627,MONTH=5,DATE=1,IS_LEAP_MONTH=0", // ch
                     "YEAR=1990,MONTH=6,DATE=22",   // greg
                },
+               // dangi calendar
+               // (0-based months)
+               {
+                    "en_US@calendar=dangi",
+                    "EXTENDED_YEAR=4297,MONTH=6,DATE=29,IS_LEAP_MONTH=0", // dangi
+                    "YEAR=1964,MONTH=8,DATE=5",   // greg
+               },
+               {
+                    "en_US@calendar=dangi",
+                     "EXTENDED_YEAR=4297,MONTH=7,DATE=1,IS_LEAP_MONTH=0", // dangi
+                    "YEAR=1964,MONTH=8,DATE=6",   // greg
+               },
+               {
+                    "en_US@calendar=dangi",
+                     "EXTENDED_YEAR=4294,MONTH=10,DATE=18,IS_LEAP_MONTH=0", // dangi
+                    "YEAR=1961,MONTH=11,DATE=25",   // greg
+               },
+               {
+                    "en_US@calendar=dangi",
+                     "EXTENDED_YEAR=4323,MONTH=4,DATE=30,IS_LEAP_MONTH=0", // dangi
+                    "YEAR=1990,MONTH=5,DATE=22",   // greg
+               },
+               {
+                    "en_US@calendar=dangi",
+                     "EXTENDED_YEAR=4323,MONTH=4,DATE=1,IS_LEAP_MONTH=1", // dangi
+                    "YEAR=1990,MONTH=5,DATE=23",   // greg
+               },
+               {
+                    "en_US@calendar=dangi",
+                     "EXTENDED_YEAR=4323,MONTH=4,DATE=29,IS_LEAP_MONTH=1", // dangi
+                    "YEAR=1990,MONTH=6,DATE=21",   // greg
+               },
+               {
+                    "en_US@calendar=dangi",
+                     "EXTENDED_YEAR=4323,MONTH=5,DATE=1,IS_LEAP_MONTH=0", // dangi
+                    "YEAR=1990,MONTH=6,DATE=22",   // greg
+               },
+               {
+                    "en_US@calendar=dangi",
+                     "EXTENDED_YEAR=4213,MONTH=9,DATE=1,IS_LEAP_MONTH=0", // dangi
+                    "YEAR=1880,MONTH=10,DATE=3",   // greg
+               },
+               {
+                    "en_US@calendar=dangi",
+                     "EXTENDED_YEAR=4215,MONTH=10,DATE=1,IS_LEAP_MONTH=0", // dangi
+                    "YEAR=1882,MONTH=11,DATE=10",   // greg
+               },
+               {
+                    "en_US@calendar=dangi",
+                     "EXTENDED_YEAR=4230,MONTH=6,DATE=1,IS_LEAP_MONTH=0", // dangi
+                    "YEAR=1897,MONTH=6,DATE=29",   // greg
+               },
             }
         }
         TestCalendarOperations {
@@ -343,6 +395,42 @@ calendar:table(nofallback) {
                     "MONTH=-10", // month - 10
                     "EXTENDED_YEAR=4638,MONTH=5,DATE=29,IS_LEAP_MONTH=0",  // ch  
                },
+               //dangi add tests
+               { // normal
+                    "en_US@calendar=dangi",         
+                    "EXTENDED_YEAR=4338,MONTH=2,DATE=15,IS_LEAP_MONTH=0",  // dangi  
+                    "add",
+                    "MONTH=3", // month + 3
+                    "EXTENDED_YEAR=4338,MONTH=5,DATE=15,IS_LEAP_MONTH=0",  // dangi  
+               },
+               { // across year
+                    "en_US@calendar=dangi",         
+                    "EXTENDED_YEAR=4335,MONTH=11,DATE=15,IS_LEAP_MONTH=0",  // dangi  
+                    "add",
+                    "MONTH=1", // month + 1
+                    "EXTENDED_YEAR=4336,MONTH=0,DATE=15,IS_LEAP_MONTH=0",  // dangi  
+               },
+               { // 4 = leap
+                    "en_US@calendar=dangi",         
+                    "EXTENDED_YEAR=4334,MONTH=2,DATE=15,IS_LEAP_MONTH=0",  // dangi  
+                    "add",
+                    "MONTH=3", // month + 3
+                    "EXTENDED_YEAR=4334,MONTH=4,DATE=15,IS_LEAP_MONTH=0",  // dangi  
+               },
+               { // 4 = leap
+                    "en_US@calendar=dangi",         
+                    "EXTENDED_YEAR=4334,MONTH=2,DATE=15,IS_LEAP_MONTH=0",  // dangi  
+                    "add",
+                    "MONTH=2", // month + 2
+                    "EXTENDED_YEAR=4334,MONTH=3,DATE=15,IS_LEAP_MONTH=1",  // dangi  
+               },
+               { // dom should pin
+                    "en_US@calendar=dangi",         
+                    "EXTENDED_YEAR=4334,MONTH=2,DATE=30,IS_LEAP_MONTH=0",  // dangi  
+                    "add",
+                    "MONTH=2", // month + 2
+                    "EXTENDED_YEAR=4334,MONTH=3,DATE=29,IS_LEAP_MONTH=1",  // dangi  
+               },
                {
                     "en_US@calendar=hebrew",         
                     "MILLIS=-180799750799999",