]> granicus.if.org Git - icu/commitdiff
ICU-12973 CLDR Japanese Era data and tentative Japanese new era support (#111)
authorYoshito Umaoka <yumaoka@users.noreply.github.com>
Wed, 12 Sep 2018 21:13:30 +0000 (17:13 -0400)
committerShane Carr <shane@unicode.org>
Thu, 27 Sep 2018 21:27:39 +0000 (14:27 -0700)
* Updated era data format in supplementalData.

* Include tentative era names in data. Implemented Japanese era loaded from CLDR data in ICU4J.

* ICU4C implementation, ICU4C refactoring. WIP.

* VS project updates and some bug fixes

Also added API comments.

* Review feedback and bug fixes

- NULL to nullptr
- use of LocalUResourceBundlePointer
- TYPO "name" to "named"
- env var checking stricmp() == 0

* API comment correction based on feedback

* Duplicate the comment in ucal.h to calendar.h

* Fixed spelling errors in API comment

52 files changed:
icu4c/source/data/locales/ar.txt
icu4c/source/data/locales/ast.txt
icu4c/source/data/locales/br.txt
icu4c/source/data/locales/bs_Cyrl.txt
icu4c/source/data/locales/cs.txt
icu4c/source/data/locales/de.txt
icu4c/source/data/locales/he.txt
icu4c/source/data/locales/hi.txt
icu4c/source/data/locales/hr.txt
icu4c/source/data/locales/id.txt
icu4c/source/data/locales/ja.txt
icu4c/source/data/locales/ko.txt
icu4c/source/data/locales/lo.txt
icu4c/source/data/locales/lt.txt
icu4c/source/data/locales/nb.txt
icu4c/source/data/locales/nl.txt
icu4c/source/data/locales/root.txt
icu4c/source/data/locales/ru.txt
icu4c/source/data/locales/sr.txt
icu4c/source/data/locales/sr_Latn.txt
icu4c/source/data/locales/sv.txt
icu4c/source/data/locales/th.txt
icu4c/source/data/locales/yue.txt
icu4c/source/data/locales/yue_Hans.txt
icu4c/source/data/locales/zh.txt
icu4c/source/data/locales/zh_Hant.txt
icu4c/source/data/misc/supplementalData.txt
icu4c/source/i18n/Makefile.in
icu4c/source/i18n/erarules.cpp [new file with mode: 0644]
icu4c/source/i18n/erarules.h [new file with mode: 0644]
icu4c/source/i18n/i18n.vcxproj
icu4c/source/i18n/i18n.vcxproj.filters
icu4c/source/i18n/i18n_uwp.vcxproj
icu4c/source/i18n/japancal.cpp
icu4c/source/i18n/japancal.h
icu4c/source/i18n/ucln_in.h
icu4c/source/i18n/unicode/calendar.h
icu4c/source/i18n/unicode/ucal.h
icu4c/source/test/intltest/Makefile.in
icu4c/source/test/intltest/erarulestest.cpp [new file with mode: 0644]
icu4c/source/test/intltest/erarulestest.h [new file with mode: 0644]
icu4c/source/test/intltest/intltest.vcxproj
icu4c/source/test/intltest/intltest.vcxproj.filters
icu4c/source/test/intltest/itformat.cpp
icu4c/source/test/testdata/structLocale.txt
icu4j/main/classes/core/src/com/ibm/icu/impl/CalType.java [new file with mode: 0644]
icu4j/main/classes/core/src/com/ibm/icu/impl/EraRules.java [new file with mode: 0644]
icu4j/main/classes/core/src/com/ibm/icu/util/Calendar.java
icu4j/main/classes/core/src/com/ibm/icu/util/JapaneseCalendar.java
icu4j/main/shared/data/icudata.jar
icu4j/main/shared/data/icutzdata.jar
icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/EraRulesTest.java [new file with mode: 0644]

index 8fb84fa6141d151b128c966eb93e54bd6f45e1ee..7c809887c3b561d748d85df3a010e5f45bc2378d 100644 (file)
@@ -1635,6 +1635,7 @@ ar{
                     "تيشو",
                     "شووا",
                     "هيسي",
+                    "Qqqq",
                 }
             }
         }
index c2f8950a09c41c96cf1ff3dc18ca6df944b7412b..ce9a6857812a70886ec61ee1af8a27d678f897d8 100644 (file)
@@ -2304,6 +2304,7 @@ ast{
                     "Taishō",
                     "e. Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
                 narrow{
                     "Taika",
@@ -2542,6 +2543,7 @@ ast{
                     "T",
                     "S",
                     "H",
+                    "Q",
                 }
                 wide{
                     "Taika (645–650)",
@@ -2780,6 +2782,7 @@ ast{
                     "Taishō",
                     "era Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
             }
             intervalFormats{
index 41100c2de9a4267a5420b433fc7bddfc1af36300..f060ea61b5122e2838dbaed0a009970a9bdcfaeb 100644 (file)
@@ -4105,6 +4105,7 @@ br{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
                 narrow{
                     "Taika (645–650)",
@@ -4343,6 +4344,7 @@ br{
                     "T",
                     "S",
                     "H",
+                    "Q",
                 }
                 wide{
                     "Taika (645–650)",
@@ -4581,6 +4583,7 @@ br{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
             }
             intervalFormats{
index dca25e65ad550c8f055e85269a811a1efb595115..06765fbd71c6052a640ee4ebed7bbdbf229a4880 100644 (file)
@@ -1035,6 +1035,7 @@ bs_Cyrl{
                     "Таишо",
                     "Шова",
                     "Хаисеи",
+                    "Qqqq",
                 }
             }
         }
index 7299b8ef365b26a9f69ba8ea19a835fc4bd7972c..186a9ae66a40fccad63cb91122c5a11eaba37f8c 100644 (file)
@@ -3697,6 +3697,7 @@ cs{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
                 narrow{
                     "Taika (645–650)",
@@ -3935,6 +3936,7 @@ cs{
                     "T",
                     "S",
                     "H",
+                    "Q",
                 }
                 wide{
                     "Taika (645–650)",
@@ -4173,6 +4175,7 @@ cs{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
             }
             intervalFormats{
index 20d7fdeaa2018d0e92dd8217868aee2a3dce0f09..dafc31df0738a8f7eae23849034f645887c179b3 100644 (file)
@@ -1601,6 +1601,7 @@ de{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
             }
         }
index 28259660cf4462d9892dbe12a5ca1ebd1a908688..88a9233eb4b5d997d100772097620462ebb4e75d 100644 (file)
@@ -1837,6 +1837,7 @@ he{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
             }
         }
index 19d1409f67ee41c06cf210baec1bbfdd45accafb..7a34f79dbac658ce57278ad71b44a5493e14b0b3 100644 (file)
@@ -1239,6 +1239,7 @@ hi{
                     "ताईशो",
                     "शोवा",
                     "हेईसेई",
+                    "Qqqq",
                 }
             }
         }
index c10b26711ec105b3310e44f3c1e14f8daa3c0003..abace48515701aa5b2ddddb5a511a7b442607d35 100644 (file)
@@ -1577,6 +1577,7 @@ hr{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
             }
         }
index 59360effa8a2f1c4b46f91c765f77112131b0834..e969669bb04157908112e6d704da6b705f645461 100644 (file)
@@ -2217,6 +2217,7 @@ id{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
             }
         }
index 0a98cbd98b215e7704dc93ce2822c965dbcac567..cd2258f645b450d0ede155f44a2b410e6170d4c5 100644 (file)
@@ -2464,6 +2464,7 @@ ja{
                     "大正",
                     "昭和",
                     "平成",
+                    "QQ",
                 }
                 narrow{
                     "大化",
@@ -2702,6 +2703,7 @@ ja{
                     "T",
                     "S",
                     "H",
+                    "Q",
                 }
             }
         }
index 8096579bc2b93ee450a3731496aa607533b9cf23..57a36e88a9a85f036f69e4f1915a5fff668ff578 100644 (file)
@@ -1909,6 +1909,7 @@ ko{
                     "다이쇼",
                     "쇼와",
                     "헤이세이",
+                    "Qqqq",
                 }
             }
         }
index 6f40fbee80cb2bcca5ed588d750de4597e2c6326..5f06344c1c10f550471bde750921278df42c0de6 100644 (file)
@@ -1845,6 +1845,7 @@ lo{
                     "ໄຕໂຊ",
                     "ໂຊວາ",
                     "ຮີຊີ",
+                    "Qqqq",
                 }
             }
         }
index 457dc018e62f5b929ff6690b0b65bcef1c40704c..27e07acadc85e4d3d5a9715125fb072abbbf5cdb 100644 (file)
@@ -2466,6 +2466,7 @@ lt{
                     "Taišo",
                     "Šova",
                     "Heisei",
+                    "Qqqq",
                 }
             }
         }
index 661655e93cf3f8e38dd367dc2fc7beeaea1dac3b..a27810c98cec993d1c9a8ac3f19d4c494a17a742 100644 (file)
@@ -5483,6 +5483,7 @@ nb{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
                 narrow{
                     "Taika (645–650)",
@@ -5721,6 +5722,7 @@ nb{
                     "T",
                     "S",
                     "H",
+                    "Q",
                 }
                 wide{
                     "Taika (645–650)",
@@ -5959,6 +5961,7 @@ nb{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
             }
             intervalFormats{
index 90893ff3f3f8dd7c3681aec5b0075512df2cc206..cc582f203fb3c0ec17eaf52d2de9a6caa116d5f8 100644 (file)
@@ -4894,6 +4894,7 @@ nl{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
                 narrow{
                     "Taika (645–650)",
@@ -5132,6 +5133,7 @@ nl{
                     "T",
                     "S",
                     "H",
+                    "Q",
                 }
                 wide{
                     "Taika (645–650)",
@@ -5370,6 +5372,7 @@ nl{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
             }
         }
index 343bd4cdea19d98f3b1d40076ded7f31a002afd2..cb0f7e65b6f4c39dc3962e113817af4301d22bda 100644 (file)
@@ -1713,6 +1713,7 @@ root{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "QQ",
                 }
                 narrow{
                     "Taika (645–650)",
@@ -1951,6 +1952,7 @@ root{
                     "T",
                     "S",
                     "H",
+                    "Q",
                 }
                 wide:alias{"/LOCALE/calendar/japanese/eras/abbreviated"}
             }
index 931b225a8dca0a8a8928598c80f2889bca032eb2..7f3618e72e73408eba77a868637443de9a936a42 100644 (file)
@@ -1837,6 +1837,7 @@ ru{
                     "Эпоха Тайсьо",
                     "Сьова",
                     "Эпоха Хэйсэй",
+                    "Qqqq",
                 }
             }
         }
index a3dc6b1853cbcd3419052fbf8353793ea0c1b535..26d40e52a5892f1c797d6840a116d7631dfd04e4 100644 (file)
@@ -1256,6 +1256,7 @@ sr{
                     "Таишо",
                     "Шова",
                     "Хаисеи",
+                    "Qqqq",
                 }
             }
         }
index 57ceb03c99ef038571e9ddc594678de82a0cf0c1..1d8d305333b6c2c3713ea39ca75944c3550e82e1 100644 (file)
@@ -1257,6 +1257,7 @@ sr_Latn{
                     "Taišo",
                     "Šova",
                     "Haisei",
+                    "Qqqq",
                 }
             }
         }
index de38b740f23f69db57d9a28e8ace6f76302acb2c..d23eeda63db543bddaf0b1e5c2894246a747d29b 100644 (file)
@@ -1630,6 +1630,7 @@ sv{
                     "Taishō",
                     "Shōwa",
                     "Heisei",
+                    "Qqqq",
                 }
             }
         }
index 457973b4473e1c6880da89198242b0e5d0762270..c1a65f4483f8c87d93a1baf1a74420f77b76e5a9 100644 (file)
@@ -2332,6 +2332,7 @@ th{
                     "ทะอิโช",
                     "โชวะ",
                     "เฮเซ",
+                    "Qqqq",
                 }
             }
         }
index c06fa48292ffb14889406fbe2dfade7ac2dad791..4d7b9d4412e0b4927af85950b00be09934499067 100644 (file)
@@ -2394,6 +2394,7 @@ yue{
                     "大正",
                     "昭和",
                     "平成",
+                    "Qqqq",
                 }
             }
         }
index 07d8219d27f0423aa0d82ebb4eef3c70f66d8fa8..4c1f2718a416fadaef81e2aee78f0a26191d60c3 100644 (file)
@@ -2392,6 +2392,7 @@ yue_Hans{
                     "大正",
                     "昭和",
                     "平成",
+                    "Qqqq",
                 }
             }
         }
index 66cc28ba229eaf3a71b2d4cb095a9d9330d2840d..ce678deaa636c2348fc4bd86473525b6ac12b39a 100644 (file)
@@ -3403,6 +3403,7 @@ zh{
                     "大正",
                     "昭和",
                     "平成",
+                    "Qqqq",
                 }
                 narrow{
                     "大化(645–650)",
@@ -3641,6 +3642,7 @@ zh{
                     "T",
                     "S",
                     "H",
+                    "Q",
                 }
                 wide{
                     "大化 (645–650)",
@@ -3879,6 +3881,7 @@ zh{
                     "大正",
                     "昭和",
                     "平成",
+                    "Qqqq",
                 }
             }
         }
index 6780937575455a6021caa8ba683ccaa8154b3bde..ce44c806c9d95ef19d32a4b1df6069aef9ec72d6 100644 (file)
@@ -5737,6 +5737,7 @@ zh_Hant{
                     "大正",
                     "昭和",
                     "平成",
+                    "Qqqq",
                 }
                 narrow{
                     "大化",
@@ -5975,6 +5976,7 @@ zh_Hant{
                     "大正",
                     "昭和",
                     "平成",
+                    "Q",
                 }
                 wide{
                     "大化",
@@ -6213,6 +6215,7 @@ zh_Hant{
                     "大正",
                     "昭和",
                     "平成",
+                    "Qqqq",
                 }
             }
             intervalFormats{
index 086b8f8b36f5f438821ac65891b0672c578964e9..63a145dee7a35232bffaa4394c63d15492998ffa 100644 (file)
@@ -6,8 +6,9 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     start:intvector{
-                        -18457,
-                        643382272,
+                        -542,
+                        1,
+                        1,
                     }
                 }
             }
@@ -17,8 +18,9 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     start:intvector{
-                        -33843,
-                        1352598528,
+                        -2636,
+                        1,
+                        1,
                     }
                 }
             }
@@ -28,14 +30,16 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     end:intvector{
-                        -12383,
-                        368826367,
+                        284,
+                        8,
+                        28,
                     }
                 }
                 1{
                     start:intvector{
-                        -12383,
-                        368826368,
+                        284,
+                        8,
+                        29,
                     }
                 }
             }
@@ -45,8 +49,9 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     start:intvector{
-                        -31610,
-                        -93940736,
+                        -2332,
+                        1,
+                        1,
                     }
                 }
             }
@@ -56,14 +61,16 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     end:intvector{
-                        -14411,
-                        664902655,
+                        8,
+                        8,
+                        28,
                     }
                 }
                 1{
                     start:intvector{
-                        -14411,
-                        664902656,
+                        8,
+                        8,
+                        29,
                     }
                 }
             }
@@ -73,8 +80,9 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     end:intvector{
-                        -54823,
-                        -2125298689,
+                        -5492,
+                        8,
+                        29,
                     }
                 }
             }
@@ -83,14 +91,16 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     end:intvector{
-                        -14468,
-                        -477728769,
+                        0,
+                        12,
+                        31,
                     }
                 }
                 1{
                     start:intvector{
-                        -14468,
-                        -477728768,
+                        1,
+                        1,
+                        1,
                     }
                 }
             }
@@ -100,8 +110,9 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     start:intvector{
-                        -42096,
-                        1167292416,
+                        -3760,
+                        10,
+                        7,
                     }
                 }
             }
@@ -111,8 +122,9 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     start:intvector{
-                        -13895,
-                        -44389376,
+                        79,
+                        1,
+                        1,
                     }
                 }
             }
@@ -121,8 +133,9 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     start:intvector{
-                        -9901,
-                        -1497369600,
+                        622,
+                        7,
+                        15,
                     }
                 }
             }
@@ -132,8 +145,9 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     start:intvector{
-                        -9901,
-                        -1410969600,
+                        622,
+                        7,
+                        16,
                     }
                 }
             }
@@ -143,8 +157,9 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     start:intvector{
-                        -9901,
-                        -1497369600,
+                        622,
+                        7,
+                        15,
                     }
                 }
             }
@@ -154,8 +169,9 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     start:intvector{
-                        -9901,
-                        -1497369600,
+                        622,
+                        7,
+                        15,
                     }
                 }
             }
@@ -165,8 +181,9 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     start:intvector{
-                        -9901,
-                        -1497369600,
+                        622,
+                        7,
+                        15,
                     }
                 }
             }
@@ -176,1418 +193,1662 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     start:intvector{
-                        -9732,
-                        548124672,
+                        645,
+                        6,
+                        19,
                     }
                 }
                 1{
                     start:intvector{
-                        -9698,
-                        1572036608,
+                        650,
+                        2,
+                        15,
                     }
                 }
                 10{
                     start:intvector{
-                        -9114,
-                        1157535744,
+                        729,
+                        8,
+                        5,
                     }
                 }
                 100{
                     start:intvector{
-                        -5884,
-                        -819397632,
+                        1169,
+                        4,
+                        8,
                     }
                 }
                 101{
                     start:intvector{
-                        -5869,
-                        -1048707072,
+                        1171,
+                        4,
+                        21,
                     }
                 }
                 102{
                     start:intvector{
-                        -5837,
-                        504906752,
+                        1175,
+                        7,
+                        28,
                     }
                 }
                 103{
                     start:intvector{
-                        -5823,
-                        -156402688,
+                        1177,
+                        8,
+                        4,
                     }
                 }
                 104{
                     start:intvector{
-                        -5794,
-                        -294454272,
+                        1181,
+                        7,
+                        14,
                     }
                 }
                 105{
                     start:intvector{
-                        -5787,
-                        1324541952,
+                        1182,
+                        5,
+                        27,
                     }
                 }
                 106{
                     start:intvector{
-                        -5773,
-                        810999808,
+                        1184,
+                        4,
+                        16,
                     }
                 }
                 107{
                     start:intvector{
-                        -5764,
-                        -234673152,
+                        1185,
+                        8,
+                        14,
                     }
                 }
                 108{
                     start:intvector{
-                        -5729,
-                        702838784,
+                        1190,
+                        4,
+                        11,
                     }
                 }
                 109{
                     start:intvector{
-                        -5663,
-                        -1680770048,
+                        1199,
+                        4,
+                        27,
                     }
                 }
                 11{
                     start:intvector{
-                        -8970,
-                        -223922176,
+                        749,
+                        4,
+                        14,
                     }
                 }
                 110{
                     start:intvector{
-                        -5650,
-                        -664144896,
+                        1201,
+                        2,
+                        13,
                     }
                 }
                 111{
                     start:intvector{
-                        -5627,
-                        59374592,
+                        1204,
+                        2,
+                        20,
                     }
                 }
                 112{
                     start:intvector{
-                        -5611,
-                        200697856,
+                        1206,
+                        4,
+                        27,
                     }
                 }
                 113{
                     start:intvector{
-                        -5600,
-                        130457600,
+                        1207,
+                        10,
+                        25,
                     }
                 }
                 114{
                     start:intvector{
-                        -5576,
-                        -885324800,
+                        1211,
+                        3,
+                        9,
                     }
                 }
                 115{
                     start:intvector{
-                        -5556,
-                        -125470720,
+                        1213,
+                        12,
+                        6,
                     }
                 }
                 116{
                     start:intvector{
-                        -5516,
-                        1110004736,
+                        1219,
+                        4,
+                        12,
                     }
                 }
                 117{
                     start:intvector{
-                        -5494,
-                        1401524224,
+                        1222,
+                        4,
+                        13,
                     }
                 }
                 118{
                     start:intvector{
-                        -5475,
-                        2049945600,
+                        1224,
+                        11,
+                        20,
                     }
                 }
                 119{
                     start:intvector{
-                        -5472,
-                        -2083523584,
+                        1225,
+                        4,
+                        20,
                     }
                 }
                 12{
                     start:intvector{
-                        -8968,
-                        -1988256768,
+                        749,
+                        7,
+                        2,
                     }
                 }
                 120{
                     start:intvector{
-                        -5453,
-                        -398302208,
+                        1227,
+                        12,
+                        10,
                     }
                 }
                 121{
                     start:intvector{
-                        -5444,
-                        -86607872,
+                        1229,
+                        3,
+                        5,
                     }
                 }
                 122{
                     start:intvector{
-                        -5421,
-                        -1757255680,
+                        1232,
+                        4,
+                        2,
                     }
                 }
                 123{
                     start:intvector{
-                        -5413,
-                        837173248,
+                        1233,
+                        4,
+                        15,
                     }
                 }
                 124{
                     start:intvector{
-                        -5402,
-                        -1540834304,
+                        1234,
+                        11,
+                        5,
                     }
                 }
                 125{
                     start:intvector{
-                        -5395,
-                        164561920,
+                        1235,
+                        9,
+                        19,
                     }
                 }
                 126{
                     start:intvector{
-                        -5372,
-                        1690714112,
+                        1238,
+                        11,
+                        23,
                     }
                 }
                 127{
                     start:intvector{
-                        -5371,
-                        -332820480,
+                        1239,
+                        2,
+                        7,
                     }
                 }
                 128{
                     start:intvector{
-                        -5360,
-                        2077506560,
+                        1240,
+                        7,
+                        16,
                     }
                 }
                 129{
                     start:intvector{
-                        -5341,
-                        -1309839360,
+                        1243,
+                        2,
+                        26,
                     }
                 }
                 13{
                     start:intvector{
-                        -8908,
-                        1130272768,
+                        757,
+                        8,
+                        18,
                     }
                 }
                 130{
                     start:intvector{
-                        -5311,
-                        539309056,
+                        1247,
+                        2,
+                        28,
                     }
                 }
                 131{
                     start:intvector{
-                        -5296,
-                        828399616,
+                        1249,
+                        3,
+                        18,
                     }
                 }
                 132{
                     start:intvector{
-                        -5241,
-                        -1398568960,
+                        1256,
+                        10,
+                        5,
                     }
                 }
                 133{
                     start:intvector{
-                        -5238,
-                        -459470848,
+                        1257,
+                        3,
+                        14,
                     }
                 }
                 134{
                     start:intvector{
-                        -5223,
-                        -775180288,
+                        1259,
+                        3,
+                        26,
                     }
                 }
                 135{
                     start:intvector{
-                        -5215,
-                        -1957318656,
+                        1260,
+                        4,
+                        13,
                     }
                 }
                 136{
                     start:intvector{
-                        -5209,
-                        -683922432,
+                        1261,
+                        2,
+                        20,
                     }
                 }
                 137{
                     start:intvector{
-                        -5186,
-                        125997056,
+                        1264,
+                        2,
+                        28,
                     }
                 }
                 138{
                     start:intvector{
-                        -5105,
-                        -67721216,
+                        1275,
+                        4,
+                        25,
                     }
                 }
                 139{
                     start:intvector{
-                        -5084,
-                        -319634432,
+                        1278,
+                        2,
+                        29,
                     }
                 }
                 14{
                     start:intvector{
-                        -8854,
-                        -1899328512,
+                        765,
+                        1,
+                        7,
                     }
                 }
                 140{
                     start:intvector{
-                        -5009,
-                        -1811781632,
+                        1288,
+                        4,
+                        28,
                     }
                 }
                 141{
                     start:intvector{
-                        -4969,
-                        1324493824,
+                        1293,
+                        8,
+                        5,
                     }
                 }
                 142{
                     start:intvector{
-                        -4928,
-                        1400434688,
+                        1299,
+                        4,
+                        25,
                     }
                 }
                 143{
                     start:intvector{
-                        -4902,
-                        -1725282304,
+                        1302,
+                        11,
+                        21,
                     }
                 }
                 144{
                     start:intvector{
-                        -4897,
-                        -995318784,
+                        1303,
+                        8,
+                        5,
                     }
                 }
                 145{
                     start:intvector{
-                        -4872,
-                        1938266112,
+                        1306,
+                        12,
+                        14,
                     }
                 }
                 146{
                     start:intvector{
-                        -4859,
-                        -735276032,
+                        1308,
+                        10,
+                        9,
                     }
                 }
                 147{
                     start:intvector{
-                        -4840,
-                        -1901254656,
+                        1311,
+                        4,
+                        28,
                     }
                 }
                 148{
                     start:intvector{
-                        -4833,
-                        581741568,
+                        1312,
+                        3,
+                        20,
                     }
                 }
                 149{
                     start:intvector{
-                        -4798,
-                        -158681088,
+                        1317,
+                        2,
+                        3,
                     }
                 }
                 15{
                     start:intvector{
-                        -8835,
-                        -1337307136,
+                        767,
+                        8,
+                        16,
                     }
                 }
                 150{
                     start:intvector{
-                        -4781,
-                        1451442176,
+                        1319,
+                        4,
+                        28,
                     }
                 }
                 151{
                     start:intvector{
-                        -4768,
-                        -1049299968,
+                        1321,
+                        2,
+                        23,
                     }
                 }
                 152{
                     start:intvector{
-                        -4740,
-                        -1644384256,
+                        1324,
+                        12,
+                        9,
                     }
                 }
                 153{
                     start:intvector{
-                        -4730,
-                        -1134857216,
+                        1326,
+                        4,
+                        26,
                     }
                 }
                 154{
                     start:intvector{
-                        -4705,
-                        1280327680,
+                        1329,
+                        8,
+                        29,
                     }
                 }
                 155{
                     start:intvector{
-                        -4691,
-                        -1800181760,
+                        1331,
+                        8,
+                        9,
                     }
                 }
                 156{
                     start:intvector{
-                        -4673,
-                        -1003993088,
+                        1334,
+                        1,
+                        29,
                     }
                 }
                 157{
                     start:intvector{
-                        -4657,
-                        321897472,
+                        1336,
+                        2,
+                        29,
                     }
                 }
                 158{
                     start:intvector{
-                        -4627,
-                        -1494088704,
+                        1340,
+                        4,
+                        28,
                     }
                 }
                 159{
                     start:intvector{
-                        -4578,
-                        1003481088,
+                        1346,
+                        12,
+                        8,
                     }
                 }
                 16{
                     start:intvector{
-                        -8812,
-                        -1452754944,
+                        770,
+                        10,
+                        1,
                     }
                 }
                 160{
                     start:intvector{
-                        -4405,
-                        -775228416,
+                        1370,
+                        7,
+                        24,
                     }
                 }
                 161{
                     start:intvector{
-                        -4392,
-                        993964032,
+                        1372,
+                        4,
+                        1,
                     }
                 }
                 162{
                     start:intvector{
-                        -4369,
-                        1656116224,
+                        1375,
+                        5,
+                        27,
                     }
                 }
                 163{
                     start:intvector{
-                        -4341,
-                        1925031936,
+                        1379,
+                        3,
+                        22,
                     }
                 }
                 164{
                     start:intvector{
-                        -4327,
-                        1497889792,
+                        1381,
+                        2,
+                        10,
                     }
                 }
                 165{
                     start:intvector{
-                        -4304,
-                        -234125312,
+                        1384,
+                        4,
+                        28,
                     }
                 }
                 166{
                     start:intvector{
-                        -4305,
-                        -1209558016,
+                        1387,
+                        8,
+                        22,
                     }
                 }
                 167{
                     start:intvector{
-                        -4279,
-                        1403459584,
+                        1387,
+                        8,
+                        23,
                     }
                 }
                 168{
                     start:intvector{
-                        -4268,
-                        469219328,
+                        1389,
+                        2,
+                        9,
                     }
                 }
                 169{
                     start:intvector{
-                        -4260,
-                        1533480960,
+                        1390,
+                        3,
+                        26,
                     }
                 }
                 17{
                     start:intvector{
-                        -8737,
-                        -7302144,
+                        781,
+                        1,
+                        1,
                     }
                 }
                 170{
                     start:intvector{
-                        -4229,
-                        -948672512,
+                        1394,
+                        7,
+                        5,
                     }
                 }
                 171{
                     start:intvector{
-                        -3980,
-                        939438080,
+                        1428,
+                        4,
+                        27,
                     }
                 }
                 172{
                     start:intvector{
-                        -3970,
-                        844165120,
+                        1429,
+                        9,
+                        5,
                     }
                 }
                 173{
                     start:intvector{
-                        -3886,
-                        1478112256,
+                        1441,
+                        2,
+                        17,
                     }
                 }
                 174{
                     start:intvector{
-                        -3864,
-                        560031744,
+                        1444,
+                        2,
+                        5,
                     }
                 }
                 175{
                     start:intvector{
-                        -3824,
-                        1561339904,
+                        1449,
+                        7,
+                        28,
                     }
                 }
                 176{
                     start:intvector{
-                        -3802,
-                        1507259392,
+                        1452,
+                        7,
+                        25,
                     }
                 }
                 177{
                     start:intvector{
-                        -3780,
-                        1625978880,
+                        1455,
+                        7,
+                        25,
                     }
                 }
                 178{
                     start:intvector{
-                        -3764,
-                        1680902144,
+                        1457,
+                        9,
+                        28,
                     }
                 }
                 179{
                     start:intvector{
-                        -3740,
-                        553687040,
+                        1460,
+                        12,
+                        21,
                     }
                 }
                 18{
                     start:intvector{
-                        -8725,
-                        -138909696,
+                        782,
+                        8,
+                        19,
                     }
                 }
                 180{
                     start:intvector{
-                        -3702,
-                        1072929792,
+                        1466,
+                        2,
+                        28,
                     }
                 }
                 181{
                     start:intvector{
-                        -3695,
-                        -1491608576,
+                        1467,
+                        3,
+                        3,
                     }
                 }
                 182{
                     start:intvector{
-                        -3679,
-                        2080681984,
+                        1469,
+                        4,
+                        28,
                     }
                 }
                 183{
                     start:intvector{
-                        -3545,
-                        -1797502976,
+                        1487,
+                        7,
+                        29,
                     }
                 }
                 184{
                     start:intvector{
-                        -3530,
-                        -1076412416,
+                        1489,
+                        8,
+                        21,
                     }
                 }
                 185{
                     start:intvector{
-                        -3508,
-                        572474368,
+                        1492,
+                        7,
+                        19,
                     }
                 }
                 186{
                     start:intvector{
-                        -3445,
-                        1890334720,
+                        1501,
+                        2,
+                        29,
                     }
                 }
                 187{
                     start:intvector{
-                        -3423,
-                        2095454208,
+                        1504,
+                        2,
+                        30,
                     }
                 }
                 188{
                     start:intvector{
-                        -3295,
-                        -377726976,
+                        1521,
+                        8,
+                        23,
                     }
                 }
                 189{
                     start:intvector{
-                        -3243,
-                        1244540928,
+                        1528,
+                        8,
+                        20,
                     }
                 }
                 19{
                     start:intvector{
-                        -8550,
-                        1883980800,
+                        806,
+                        5,
+                        18,
                     }
                 }
                 190{
                     start:intvector{
-                        -3214,
-                        1020089344,
+                        1532,
+                        7,
+                        29,
                     }
                 }
                 191{
                     start:intvector{
-                        -3044,
-                        -228918272,
+                        1555,
+                        10,
+                        23,
                     }
                 }
                 192{
                     start:intvector{
-                        -3026,
-                        974237696,
+                        1558,
+                        2,
+                        28,
                     }
                 }
                 193{
                     start:intvector{
-                        -2937,
-                        2078948352,
+                        1570,
+                        4,
+                        23,
                     }
                 }
                 194{
                     start:intvector{
-                        -2913,
-                        1988533248,
+                        1573,
+                        7,
+                        28,
                     }
                 }
                 195{
                     start:intvector{
-                        -2771,
-                        -1948590080,
+                        1592,
+                        12,
+                        8,
                     }
                 }
                 196{
                     start:intvector{
-                        -2742,
-                        393925632,
+                        1596,
+                        10,
+                        27,
                     }
                 }
                 197{
                     start:intvector{
-                        -2605,
-                        -1940361216,
+                        1615,
+                        7,
+                        13,
                     }
                 }
                 198{
                     start:intvector{
-                        -2542,
-                        -17700864,
+                        1624,
+                        2,
+                        30,
                     }
                 }
                 199{
                     start:intvector{
-                        -2389,
-                        -939697152,
+                        1644,
+                        12,
+                        16,
                     }
                 }
                 2{
                     start:intvector{
-                        -9537,
-                        418301952,
+                        672,
+                        1,
+                        1,
                     }
                 }
                 20{
                     start:intvector{
-                        -8518,
-                        1389027328,
+                        810,
+                        9,
+                        19,
                     }
                 }
                 200{
                     start:intvector{
-                        -2365,
-                        154455040,
+                        1648,
+                        2,
+                        15,
                     }
                 }
                 201{
                     start:intvector{
-                        -2332,
-                        -981633024,
+                        1652,
+                        9,
+                        18,
                     }
                 }
                 202{
                     start:intvector{
-                        -2313,
-                        -1629211648,
+                        1655,
+                        4,
+                        13,
                     }
                 }
                 203{
                     start:intvector{
-                        -2289,
-                        -1287626752,
+                        1658,
+                        7,
+                        23,
                     }
                 }
                 204{
                     start:intvector{
-                        -2269,
-                        -182172672,
+                        1661,
+                        4,
+                        25,
                     }
                 }
                 205{
                     start:intvector{
-                        -2177,
-                        540603392,
+                        1673,
+                        9,
+                        21,
                     }
                 }
                 206{
                     start:intvector{
-                        -2118,
-                        289532928,
+                        1681,
+                        9,
+                        29,
                     }
                 }
                 207{
                     start:intvector{
-                        -2101,
-                        -1419878400,
+                        1684,
+                        2,
+                        21,
                     }
                 }
                 208{
                     start:intvector{
-                        -2067,
-                        -2037566464,
+                        1688,
+                        9,
+                        30,
                     }
                 }
                 209{
                     start:intvector{
-                        -1953,
-                        99929088,
+                        1704,
+                        3,
+                        13,
                     }
                 }
                 21{
                     start:intvector{
-                        -8420,
-                        40632320,
+                        824,
+                        1,
+                        5,
                     }
                 }
                 210{
                     start:intvector{
-                        -1901,
-                        1315229696,
+                        1711,
+                        4,
+                        25,
                     }
                 }
                 211{
                     start:intvector{
-                        -1863,
-                        970472448,
+                        1716,
+                        6,
+                        22,
                     }
                 }
                 212{
                     start:intvector{
-                        -1717,
-                        305247232,
+                        1736,
+                        4,
+                        28,
                     }
                 }
                 213{
                     start:intvector{
-                        -1682,
-                        -1731175424,
+                        1741,
+                        2,
+                        27,
                     }
                 }
                 214{
                     start:intvector{
-                        -1660,
-                        -2130855936,
+                        1744,
+                        2,
+                        21,
                     }
                 }
                 215{
                     start:intvector{
-                        -1628,
-                        -1070609408,
+                        1748,
+                        7,
+                        12,
                     }
                 }
                 216{
                     start:intvector{
-                        -1604,
-                        -297024512,
+                        1751,
+                        10,
+                        27,
                     }
                 }
                 217{
                     start:intvector{
-                        -1511,
-                        -2116183040,
+                        1764,
+                        6,
+                        2,
                     }
                 }
                 218{
                     start:intvector{
-                        -1449,
-                        -1514555392,
+                        1772,
+                        11,
+                        16,
                     }
                 }
                 219{
                     start:intvector{
-                        -1387,
-                        790039552,
+                        1781,
+                        4,
+                        2,
                     }
                 }
                 22{
                     start:intvector{
-                        -8347,
-                        1954419712,
+                        834,
+                        1,
+                        3,
                     }
                 }
                 220{
                     start:intvector{
-                        -1330,
-                        -1646063616,
+                        1789,
+                        1,
+                        25,
                     }
                 }
                 221{
                     start:intvector{
-                        -1242,
-                        -47985664,
+                        1801,
+                        2,
+                        5,
                     }
                 }
                 222{
                     start:intvector{
-                        -1219,
-                        589133824,
+                        1804,
+                        2,
+                        11,
                     }
                 }
                 223{
                     start:intvector{
-                        -1115,
-                        1810135040,
+                        1818,
+                        4,
+                        22,
                     }
                 }
                 224{
                     start:intvector{
-                        -1022,
-                        1114176512,
+                        1830,
+                        12,
+                        10,
                     }
                 }
                 225{
                     start:intvector{
-                        -920,
-                        -109054976,
+                        1844,
+                        12,
+                        2,
                     }
                 }
                 226{
                     start:intvector{
-                        -896,
-                        -977070080,
+                        1848,
+                        2,
+                        28,
                     }
                 }
                 227{
                     start:intvector{
-                        -846,
-                        1459132416,
+                        1854,
+                        11,
+                        27,
                     }
                 }
                 228{
                     start:intvector{
-                        -807,
-                        1398607872,
+                        1860,
+                        3,
+                        18,
                     }
                 }
                 229{
                     start:intvector{
-                        -800,
-                        537036800,
+                        1861,
+                        2,
+                        19,
                     }
                 }
                 23{
                     start:intvector{
-                        -8241,
-                        -1847080960,
+                        848,
+                        6,
+                        13,
                     }
                 }
                 230{
                     start:intvector{
-                        -778,
-                        742156288,
+                        1864,
+                        2,
+                        20,
                     }
                 }
                 231{
                     start:intvector{
-                        -770,
-                        1979217920,
+                        1865,
+                        4,
+                        7,
                     }
                 }
                 232{
                     start:intvector{
-                        -745,
-                        -1689931776,
+                        1868,
+                        9,
+                        8,
                     }
                 }
                 233{
                     start:intvector{
-                        -422,
-                        322598912,
+                        1912,
+                        7,
+                        30,
                     }
                 }
                 234{
                     start:intvector{
-                        -317,
-                        -393534464,
+                        1926,
+                        12,
+                        25,
                     }
                 }
                 235{
                     start:intvector{
-                        139,
-                        -1074621440,
+                        1989,
+                        1,
+                        8,
+                    }
+                }
+                236{
+                    named{"false"}
+                    start:intvector{
+                        2019,
+                        5,
+                        1,
                     }
                 }
                 24{
                     start:intvector{
-                        -8220,
-                        -1407794176,
+                        851,
+                        4,
+                        28,
                     }
                 }
                 25{
                     start:intvector{
-                        -8193,
-                        279856128,
+                        854,
+                        11,
+                        30,
                     }
                 }
                 26{
                     start:intvector{
-                        -8177,
-                        1889979392,
+                        857,
+                        2,
+                        21,
                     }
                 }
                 27{
                     start:intvector{
-                        -8161,
-                        821702656,
+                        859,
+                        4,
+                        15,
                     }
                 }
                 28{
                     start:intvector{
-                        -8029,
-                        2052419584,
+                        877,
+                        4,
+                        16,
                     }
                 }
                 29{
                     start:intvector{
-                        -7971,
-                        739516416,
+                        885,
+                        2,
+                        21,
                     }
                 }
                 3{
                     start:intvector{
-                        -9431,
-                        -13598720,
+                        686,
+                        7,
+                        20,
                     }
                 }
                 30{
                     start:intvector{
-                        -7941,
-                        -558069760,
+                        889,
+                        4,
+                        27,
                     }
                 }
                 31{
                     start:intvector{
-                        -7875,
-                        -115511296,
+                        898,
+                        4,
+                        26,
                     }
                 }
                 32{
                     start:intvector{
-                        -7851,
-                        -1588326400,
+                        901,
+                        7,
+                        15,
                     }
                 }
                 33{
                     start:intvector{
-                        -7691,
-                        1527873536,
+                        923,
+                        4,
+                        11,
                     }
                 }
                 34{
                     start:intvector{
-                        -7632,
-                        1881603072,
+                        931,
+                        4,
+                        26,
                     }
                 }
                 35{
                     start:intvector{
-                        -7580,
-                        1714503680,
+                        938,
+                        5,
+                        22,
                     }
                 }
                 36{
                     start:intvector{
-                        -7515,
-                        -348537856,
+                        947,
+                        4,
+                        22,
                     }
                 }
                 37{
                     start:intvector{
-                        -7437,
-                        801380352,
+                        957,
+                        10,
+                        27,
                     }
                 }
                 38{
                     start:intvector{
-                        -7413,
-                        2093365248,
+                        961,
+                        2,
+                        16,
                     }
                 }
                 39{
                     start:intvector{
-                        -7388,
-                        1855182848,
+                        964,
+                        7,
+                        10,
                     }
                 }
                 4{
                     start:intvector{
-                        -9323,
-                        -938866688,
+                        701,
+                        3,
+                        21,
                     }
                 }
                 40{
                     start:intvector{
-                        -7358,
-                        -2120803328,
+                        968,
+                        8,
+                        13,
                     }
                 }
                 41{
                     start:intvector{
-                        -7346,
-                        1524156416,
+                        970,
+                        3,
+                        25,
                     }
                 }
                 42{
                     start:intvector{
-                        -7319,
-                        -712527872,
+                        973,
+                        12,
+                        20,
                     }
                 }
                 43{
                     start:intvector{
-                        -7300,
-                        -1446506496,
+                        976,
+                        7,
+                        13,
                     }
                 }
                 44{
                     start:intvector{
-                        -7282,
-                        620649472,
+                        978,
+                        11,
+                        29,
                     }
                 }
                 45{
                     start:intvector{
-                        -7250,
-                        1248896000,
+                        983,
+                        4,
+                        15,
                     }
                 }
                 46{
                     start:intvector{
-                        -7235,
-                        1019586560,
+                        985,
+                        4,
+                        27,
                     }
                 }
                 47{
                     start:intvector{
-                        -7221,
-                        2061244416,
+                        987,
+                        4,
+                        5,
                     }
                 }
                 48{
                     start:intvector{
-                        -7204,
-                        -1289766912,
+                        989,
+                        8,
+                        8,
                     }
                 }
                 49{
                     start:intvector{
-                        -7195,
-                        -546072576,
+                        990,
+                        11,
+                        7,
                     }
                 }
                 5{
                     start:intvector{
-                        -9300,
-                        -708714496,
+                        704,
+                        5,
+                        10,
                     }
                 }
                 50{
                     start:intvector{
-                        -7163,
-                        1785141248,
+                        995,
+                        2,
+                        22,
                     }
                 }
                 51{
                     start:intvector{
-                        -7134,
-                        5489664,
+                        999,
+                        1,
+                        13,
                     }
                 }
                 52{
                     start:intvector{
-                        -7094,
-                        -1992169472,
+                        1004,
+                        7,
+                        20,
                     }
                 }
                 53{
                     start:intvector{
-                        -7032,
-                        2126825472,
+                        1012,
+                        12,
+                        25,
                     }
                 }
                 54{
                     start:intvector{
-                        -7000,
-                        1199872000,
+                        1017,
+                        4,
+                        23,
                     }
                 }
                 55{
                     start:intvector{
-                        -6972,
-                        259187712,
+                        1021,
+                        2,
+                        2,
                     }
                 }
                 56{
                     start:intvector{
-                        -6947,
-                        1489805312,
+                        1024,
+                        7,
+                        13,
                     }
                 }
                 57{
                     start:intvector{
-                        -6918,
-                        -92013568,
+                        1028,
+                        7,
+                        25,
                     }
                 }
                 58{
                     start:intvector{
-                        -6853,
-                        818879488,
+                        1037,
+                        4,
+                        21,
                     }
                 }
                 59{
                     start:intvector{
-                        -6827,
-                        1383329792,
+                        1040,
+                        11,
+                        10,
                     }
                 }
                 6{
                     start:intvector{
-                        -9273,
-                        -810431488,
+                        708,
+                        1,
+                        11,
                     }
                 }
                 60{
                     start:intvector{
-                        -6798,
-                        -25689088,
+                        1044,
+                        11,
+                        24,
                     }
                 }
                 61{
                     start:intvector{
-                        -6787,
-                        743037952,
+                        1046,
+                        4,
+                        14,
                     }
                 }
                 62{
                     start:intvector{
-                        -6738,
-                        -1115726848,
+                        1053,
+                        1,
+                        11,
                     }
                 }
                 63{
                     start:intvector{
-                        -6696,
-                        429014016,
+                        1058,
+                        8,
+                        29,
                     }
                 }
                 64{
                     start:intvector{
-                        -6646,
-                        -22318080,
+                        1065,
+                        8,
+                        2,
                     }
                 }
                 65{
                     start:intvector{
-                        -6618,
-                        653564928,
+                        1069,
+                        4,
+                        13,
                     }
                 }
                 66{
                     start:intvector{
-                        -6579,
-                        -1973926912,
+                        1074,
+                        8,
+                        23,
                     }
                 }
                 67{
                     start:intvector{
-                        -6555,
-                        1366625280,
+                        1077,
+                        11,
+                        17,
                     }
                 }
                 68{
                     start:intvector{
-                        -6531,
-                        325810176,
+                        1081,
+                        2,
+                        10,
                     }
                 }
                 69{
                     start:intvector{
-                        -6509,
-                        185329664,
+                        1084,
+                        2,
+                        7,
                     }
                 }
                 7{
                     start:intvector{
-                        -9217,
-                        -186200064,
+                        715,
+                        9,
+                        2,
                     }
                 }
                 70{
                     start:intvector{
-                        -6486,
-                        1193081856,
+                        1087,
+                        4,
+                        7,
                     }
                 }
                 71{
                     start:intvector{
-                        -6430,
-                        -922454016,
+                        1094,
+                        12,
+                        15,
                     }
                 }
                 72{
                     start:intvector{
-                        -6415,
-                        -2015763456,
+                        1096,
+                        12,
+                        17,
                     }
                 }
                 73{
                     start:intvector{
-                        -6408,
-                        1504032768,
+                        1097,
+                        11,
+                        21,
                     }
                 }
                 74{
                     start:intvector{
-                        -6395,
-                        1397457920,
+                        1099,
+                        8,
+                        28,
                     }
                 }
                 75{
                     start:intvector{
-                        -6362,
-                        236337152,
+                        1104,
+                        2,
+                        10,
                     }
                 }
                 76{
                     start:intvector{
-                        -6347,
-                        -313539584,
+                        1106,
+                        4,
+                        9,
                     }
                 }
                 77{
                     start:intvector{
-                        -6330,
-                        -147183616,
+                        1108,
+                        8,
+                        3,
                     }
                 }
                 78{
                     start:intvector{
-                        -6315,
-                        980874240,
+                        1110,
+                        7,
+                        13,
                     }
                 }
                 79{
                     start:intvector{
-                        -6293,
-                        1185993728,
+                        1113,
+                        7,
+                        13,
                     }
                 }
                 8{
                     start:intvector{
-                        -9200,
-                        819123200,
+                        717,
+                        11,
+                        17,
                     }
                 }
                 80{
                     start:intvector{
-                        -6259,
-                        -97861632,
+                        1118,
+                        4,
+                        3,
                     }
                 }
                 81{
                     start:intvector{
-                        -6244,
-                        -759171072,
+                        1120,
+                        4,
+                        10,
                     }
                 }
                 82{
                     start:intvector{
-                        -6214,
-                        312377344,
+                        1124,
+                        4,
+                        3,
                     }
                 }
                 83{
                     start:intvector{
-                        -6201,
-                        1415402496,
+                        1126,
+                        1,
+                        22,
                     }
                 }
                 84{
                     start:intvector{
-                        -6164,
-                        872812544,
+                        1131,
+                        1,
+                        29,
                     }
                 }
                 85{
                     start:intvector{
-                        -6153,
-                        2012172288,
+                        1132,
+                        8,
+                        11,
                     }
                 }
                 86{
                     start:intvector{
-                        -6133,
-                        1562426368,
+                        1135,
+                        4,
+                        27,
                     }
                 }
                 87{
                     start:intvector{
-                        -6088,
-                        -223669248,
+                        1141,
+                        7,
+                        10,
                     }
                 }
                 88{
                     start:intvector{
-                        -6082,
-                        -764673024,
+                        1142,
+                        4,
+                        28,
                     }
                 }
                 89{
                     start:intvector{
-                        -6068,
-                        943152128,
+                        1144,
+                        2,
+                        23,
                     }
                 }
                 9{
                     start:intvector{
-                        -9155,
-                        -621372416,
+                        724,
+                        2,
+                        4,
                     }
                 }
                 90{
                     start:intvector{
-                        -6058,
-                        -1805488128,
+                        1145,
+                        7,
+                        22,
                     }
                 }
                 91{
                     start:intvector{
-                        -6017,
-                        405420032,
+                        1151,
+                        1,
+                        26,
                     }
                 }
                 92{
                     start:intvector{
-                        -5990,
-                        -1399264256,
+                        1154,
+                        10,
+                        28,
                     }
                 }
                 93{
                     start:intvector{
-                        -5979,
-                        -1383104512,
+                        1156,
+                        4,
+                        27,
                     }
                 }
                 94{
                     start:intvector{
-                        -5957,
-                        -1869185024,
+                        1159,
+                        4,
+                        20,
                     }
                 }
                 95{
                     start:intvector{
-                        -5952,
-                        -448021504,
+                        1160,
+                        1,
+                        10,
                     }
                 }
                 96{
                     start:intvector{
-                        -5939,
-                        111570944,
+                        1161,
+                        9,
+                        4,
                     }
                 }
                 97{
                     start:intvector{
-                        -5928,
-                        -2093636608,
+                        1163,
+                        3,
+                        29,
                     }
                 }
                 98{
                     start:intvector{
-                        -5912,
-                        -1779513344,
+                        1165,
+                        6,
+                        5,
                     }
                 }
                 99{
                     start:intvector{
-                        -5903,
-                        -1727019008,
+                        1166,
+                        8,
+                        27,
                     }
                 }
             }
@@ -1597,8 +1858,9 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     start:intvector{
-                        -9905,
-                        -1165500416,
+                        622,
+                        1,
+                        1,
                     }
                 }
             }
@@ -1608,14 +1870,16 @@ supplementalData:table(nofallback){
             eras{
                 0{
                     end:intvector{
-                        -427,
-                        -727931905,
+                        1911,
+                        12,
+                        31,
                     }
                 }
                 1{
                     start:intvector{
-                        -427,
-                        -727931904,
+                        1912,
+                        1,
+                        1,
                     }
                 }
             }
index 6d9496ce2374891acb32fe0a8502c3dc77ddc380..98b36b4c9177fd2b7651ef266eeb8e1dda2a044e 100644 (file)
@@ -111,6 +111,7 @@ double-conversion-fast-dtoa.o double-conversion-strtod.o \
 numparse_stringsegment.o numparse_parsednumber.o numparse_impl.o \
 numparse_symbols.o numparse_decimal.o numparse_scientific.o numparse_currency.o \
 numparse_affixes.o numparse_compositions.o numparse_validators.o \
+erarules.o
 
 
 ## Header files to install
diff --git a/icu4c/source/i18n/erarules.cpp b/icu4c/source/i18n/erarules.cpp
new file mode 100644 (file)
index 0000000..3ea3850
--- /dev/null
@@ -0,0 +1,313 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include <stdlib.h>
+#include "unicode/ucal.h"
+#include "unicode/ures.h"
+#include "unicode/ustring.h"
+#include "cmemory.h"
+#include "cstring.h"
+#include "erarules.h"
+#include "gregoimp.h"
+#include "uassert.h"
+
+U_NAMESPACE_BEGIN
+
+static const int32_t MAX_ENCODED_START_YEAR = 32767;
+static const int32_t MIN_ENCODED_START_YEAR = -32768;
+static const int32_t MIN_ENCODED_START = -2147483391;   // encodeDate(MIN_ENCODED_START_YEAR, 1, 1, ...);
+
+static const int32_t YEAR_MASK = 0xFFFF0000;
+static const int32_t MONTH_MASK = 0x0000FF00;
+static const int32_t DAY_MASK = 0x000000FF;
+
+static const int32_t MAX_INT32 = 0x7FFFFFFF;
+static const int32_t MIN_INT32 = 0xFFFFFFFF;
+
+static const UChar VAL_FALSE[] = {0x66, 0x61, 0x6c, 0x73, 0x65};    // "false"
+static const UChar VAL_FALSE_LEN = 5;
+
+static UBool isSet(int startDate) {
+    return startDate != 0;
+}
+
+static UBool isValidRuleStartDate(int32_t year, int32_t month, int32_t day) {
+    return year >= MIN_ENCODED_START_YEAR && year <= MAX_ENCODED_START_YEAR
+            && month >= 1 && month <= 12 && day >=1 && day <= 31;
+}
+
+/**
+ * Encode year/month/date to a single integer.
+ * year is high 16 bits (-32768 to 32767), month is
+ * next 8 bits and day of month is last 8 bits.
+ *
+ * @param year  year
+ * @param month month (1-base)
+ * @param day   day of month
+ * @return  an encoded date.
+ */
+static int32_t encodeDate(int32_t year, int32_t month, int32_t day) {
+    return year << 16 | month << 8 | day;
+}
+
+static void decodeDate(int32_t encodedDate, int32_t (&fields)[3]) {
+    if (encodedDate == MIN_ENCODED_START) {
+        fields[0] = MIN_INT32;
+        fields[1] = 1;
+        fields[2] = 1;
+    } else {
+        fields[0] = (encodedDate & YEAR_MASK) >> 16;
+        fields[1] = (encodedDate & MONTH_MASK) >> 8;
+        fields[2] = encodedDate & DAY_MASK;
+    }
+}
+
+/**
+ * Compare an encoded date with another date specified by year/month/day.
+ * @param encoded   An encoded date
+ * @param year      Year of another date
+ * @param month     Month of another date
+ * @param day       Day of another date
+ * @return -1 when encoded date is earlier, 0 when two dates are same,
+ *          and 1 when encoded date is later.
+ */
+static int32_t compareEncodedDateWithYMD(int encoded, int year, int month, int day) {
+    if (year < MIN_ENCODED_START_YEAR) {
+        if (encoded == MIN_ENCODED_START) {
+            if (year > MIN_INT32 || month > 1 || day > 1) {
+                return -1;
+            }
+            return 0;
+        } else {
+            return 1;
+        }
+    } else if (year > MAX_ENCODED_START_YEAR) {
+        return -1;
+    } else {
+        int tmp = encodeDate(year, month, day);
+        if (encoded < tmp) {
+            return -1;
+        } else if (encoded == tmp) {
+            return 0;
+        } else {
+            return 1;
+        }
+    }
+}
+
+EraRules::EraRules(int32_t *startDates, int32_t numEras)
+    : startDates(startDates), numEras(numEras) {
+    initCurrentEra();
+}
+
+EraRules::~EraRules() {
+    uprv_free(startDates);
+}
+
+EraRules* EraRules::createInstance(const char *calType, UBool includeTentativeEra, UErrorCode& status) {
+    if(U_FAILURE(status)) {
+        return nullptr;
+    }
+    LocalUResourceBundlePointer rb(ures_openDirect(nullptr, "supplementalData", &status));
+    ures_getByKey(rb.getAlias(), "calendarData", rb.getAlias(), &status);
+    ures_getByKey(rb.getAlias(), calType, rb.getAlias(), &status);
+    ures_getByKey(rb.getAlias(), "eras", rb.getAlias(), &status);
+
+    if (U_FAILURE(status)) {
+        return nullptr;
+    }
+
+    int32_t numEras = ures_getSize(rb.getAlias());
+    int32_t firstTentativeIdx = MAX_INT32;
+
+    int32_t *startDates = (int32_t*)uprv_malloc(numEras * sizeof(int32_t));
+    if (startDates == nullptr) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+        return nullptr;
+    }
+    uprv_memset(startDates, 0, numEras * sizeof(int32_t));
+
+    while (ures_hasNext(rb.getAlias())) {
+        LocalUResourceBundlePointer eraRuleRes(ures_getNextResource(rb.getAlias(), nullptr, &status));
+        if (U_FAILURE(status)) {
+            goto error;
+        }
+        const char *eraIdxStr = ures_getKey(eraRuleRes.getAlias());
+        char *endp;
+        int32_t eraIdx = (int32_t)strtol(eraIdxStr, &endp, 10);
+        if ((size_t)(endp - eraIdxStr) != uprv_strlen(eraIdxStr)) {
+            status = U_INVALID_FORMAT_ERROR;
+            goto error;
+        }
+        if (eraIdx < 0 || eraIdx >= numEras) {
+            status = U_INVALID_FORMAT_ERROR;
+            goto error;
+        }
+        if (isSet(startDates[eraIdx])) {
+            // start date of the index was already set
+            status = U_INVALID_FORMAT_ERROR;
+            goto error;
+        }
+
+        UBool hasName = TRUE;
+        UBool hasEnd = TRUE;
+        int32_t len;
+        while (ures_hasNext(eraRuleRes.getAlias())) {
+            LocalUResourceBundlePointer res(ures_getNextResource(eraRuleRes.getAlias(), nullptr, &status));
+            if (U_FAILURE(status)) {
+                goto error;
+            }
+            const char *key = ures_getKey(res.getAlias());
+            if (uprv_strcmp(key, "start") == 0) {
+                const int32_t *fields = ures_getIntVector(res.getAlias(), &len, &status);
+                if (U_FAILURE(status)) {
+                    goto error;
+                }
+                if (len != 3 || !isValidRuleStartDate(fields[0], fields[1], fields[2])) {
+                    status = U_INVALID_FORMAT_ERROR;
+                    goto error;
+                }
+                startDates[eraIdx] = encodeDate(fields[0], fields[1], fields[2]);
+            } else if (uprv_strcmp(key, "named") == 0) {
+                const UChar *val = ures_getString(res.getAlias(), &len, &status);
+                if (u_strncmp(val, VAL_FALSE, VAL_FALSE_LEN) == 0) {
+                    hasName = FALSE;
+                }
+            } else if (uprv_strcmp(key, "end") == 0) {
+                hasEnd = TRUE;
+            }
+        }
+
+        if (isSet(startDates[eraIdx])) {
+            if (hasEnd) {
+                // This implementation assumes either start or end is available, not both.
+                // For now, just ignore the end rule.
+            }
+        } else {
+            if (hasEnd) {
+                if (eraIdx != 0) {
+                    // This implementation does not support end only rule for eras other than
+                    // the first one.
+                    status = U_INVALID_FORMAT_ERROR;
+                    goto error;
+                }
+                U_ASSERT(eraIdx == 0);
+                startDates[eraIdx] = MIN_ENCODED_START;
+            } else {
+                status = U_INVALID_FORMAT_ERROR;
+                goto error;
+            }
+        }
+
+        if (hasName) {
+            if (eraIdx >= firstTentativeIdx) {
+                status = U_INVALID_FORMAT_ERROR;
+                goto error;
+            }
+        } else {
+            if (eraIdx < firstTentativeIdx) {
+                firstTentativeIdx = eraIdx;
+            }
+        }
+    }
+
+    EraRules *result;
+    if (firstTentativeIdx < MAX_INT32 && !includeTentativeEra) {
+        result = new EraRules(startDates, firstTentativeIdx);
+    } else {
+        result = new EraRules(startDates, numEras);
+    }
+
+    if (result == nullptr) {
+        status = U_MEMORY_ALLOCATION_ERROR;
+    }
+    return result;
+
+error:
+    uprv_free(startDates);
+    return nullptr;
+}
+
+void EraRules::getStartDate(int32_t eraIdx, int32_t (&fields)[3], UErrorCode& status) const {
+    if(U_FAILURE(status)) {
+        return;
+    }
+    if (eraIdx < 0 || eraIdx >= numEras) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
+    decodeDate(startDates[eraIdx], fields);
+}
+
+int32_t EraRules::getStartYear(int32_t eraIdx, UErrorCode& status) const {
+    int year = MAX_INT32;   // bogus value
+    if(U_FAILURE(status)) {
+        return year;
+    }
+    if (eraIdx < 0 || eraIdx >= numEras) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return year;
+    }
+    int fields[3];
+    decodeDate(startDates[eraIdx], fields);
+    year = fields[0];
+
+    return year;
+}
+
+int32_t EraRules::getEraIndex(int32_t year, int32_t month, int32_t day, UErrorCode& status) const {
+    if(U_FAILURE(status)) {
+        return -1;
+    }
+
+    if (month < 1 || month > 12 || day < 1 || day > 31) {
+        status = U_ILLEGAL_ARGUMENT_ERROR;
+        return -1;
+    }
+    int32_t high = numEras; // last index + 1
+    int32_t low;
+
+    // Short circuit for recent years.  Most modern computations will
+    // occur in the last few eras.
+    if (compareEncodedDateWithYMD(startDates[getCurrentEraIndex()], year, month, day) <= 0) {
+        low = getCurrentEraIndex();
+    } else {
+        low = 0;
+    }
+
+    // Do binary search
+    while (low < high - 1) {
+        int i = (low + high) / 2;
+        if (compareEncodedDateWithYMD(startDates[i], year, month, day) <= 0) {
+            low = i;
+        } else {
+            high = i;
+        }
+    }
+    return low;
+}
+
+void EraRules::initCurrentEra() {
+    UDate now = ucal_getNow();
+    int year, month0, dom, dow, doy, mid;
+    Grego::timeToFields(now, year, month0, dom, dow, doy, mid);
+    int currentEncodedDate = encodeDate(year, month0 + 1 /* changes to 1-base */, dom);
+    int eraIdx = numEras - 1;
+    while (eraIdx > 0) {
+        if (currentEncodedDate >= startDates[eraIdx]) {
+            break;
+        }
+        eraIdx--;
+    }
+    // Note: current era could be before the first era.
+    // In this case, this implementation returns the first era index (0).
+    currentEra = eraIdx;}
+
+U_NAMESPACE_END
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
+
diff --git a/icu4c/source/i18n/erarules.h b/icu4c/source/i18n/erarules.h
new file mode 100644 (file)
index 0000000..83a8a82
--- /dev/null
@@ -0,0 +1,80 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#ifndef ERARULES_H_
+#define ERARULES_H_
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/uobject.h"
+
+U_NAMESPACE_BEGIN
+
+class U_I18N_API EraRules : public UMemory {
+public:
+    ~EraRules();
+
+    static EraRules* createInstance(const char *calType, UBool includeTentativeEra, UErrorCode& status);
+
+    /**
+     * Gets number of effective eras
+     * @return  number of effective eras
+     */
+    inline int32_t getNumberOfEras() const {
+        return numEras;
+    }
+
+    /**
+     * Gets start date of an era
+     * @param eraIdx    Era index
+     * @param fields    Receives date fields. The result includes values of year, month,
+     *                  day of month in this order. When an era has no start date, the result
+     *                  will be January 1st in year whose value is minimum integer.
+     * @param status    Receives status.
+     */
+    void getStartDate(int32_t eraIdx, int32_t (&fields)[3], UErrorCode& status) const;
+
+    /**
+     * Gets start year of an era
+     * @param eraIdx    Era index
+     * @param status    Receives status.
+     * @return The first year of an era. When a era has no start date, minimum int32
+     *          value is returned.
+     */
+    int32_t getStartYear(int32_t eraIdx, UErrorCode& status) const;
+
+    /**
+     * Returns era index for the specified year/month/day.
+     * @param year  Year
+     * @param month Month (1-base)
+     * @param day   Day of month
+     * @param status    Receives status
+     * @return  era index (or 0, when the specified date is before the first era)
+     */
+    int32_t getEraIndex(int32_t year, int32_t month, int32_t day, UErrorCode& status) const;
+
+    /**
+     * Gets the current era index. This is calculated only once for an instance of
+     * EraRules.
+     *
+     * @return era index of current era (or 0, when current date is before the first era)
+     */
+    inline int32_t getCurrentEraIndex() const {
+        return currentEra;
+    }
+
+private:
+    EraRules(int32_t *startDates, int32_t numEra);
+
+    void initCurrentEra();
+
+    int32_t *startDates;
+    int32_t numEras;
+    int32_t currentEra;
+};
+
+U_NAMESPACE_END
+#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* ERARULES_H_ */
index b0c57ce62ae3ab4b14d37f069933acba3569352c..18f48c6584ea3203f860fff7b6b7b48b16ff5440 100644 (file)
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClCompile Include="erarules.cpp" />
     <ClCompile Include="region.cpp" />
     <ClCompile Include="uregion.cpp" />
     <ClCompile Include="alphaindex.cpp" />
     <ClInclude Include="collationtailoring.h" />
     <ClInclude Include="collationweights.h" />
     <ClInclude Include="dayperiodrules.h" />
+    <ClInclude Include="erarules.h" />
     <ClInclude Include="numsys_impl.h" />
     <ClInclude Include="region_impl.h" />
     <ClInclude Include="selfmtimpl.h" />
index 752e4ece46a3970e4ddf62f9f97aa01b6f49b94a..db3470f83b20150c81cb39e9ed4c356ab3616bdb 100644 (file)
     <ClCompile Include="dayperiodrules.cpp">
       <Filter>formatting</Filter>
     </ClCompile>
+    <ClCompile Include="erarules.cpp">
+      <Filter>formatting</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="bocsu.cpp">
     <ClInclude Include="utf8collationiterator.h">
       <Filter>collation</Filter>
     </ClInclude>
+    <ClInclude Include="erarules.h">
+      <Filter>formatting</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ResourceCompile Include="i18n.rc">
       <Filter>misc</Filter>
     </ResourceCompile>
   </ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
index d4dbfe645304d9579e399fd200970f370beac591..e85c27766ab05b6175d95070334bb317ad8a44d3 100644 (file)
@@ -87,7 +87,7 @@
       <CompileAsWinRT>false</CompileAsWinRT>
       <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
     </ClCompile>
-    <ResourceCompile>      
+    <ResourceCompile>
       <Culture>0x0409</Culture>
       <AdditionalIncludeDirectories>../common;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ResourceCompile>
     </Link>
   </ItemDefinitionGroup>
   <ItemGroup>
+    <ClCompile Include="erarules.cpp" />
     <ClCompile Include="region.cpp" />
     <ClCompile Include="uregion.cpp" />
     <ClCompile Include="alphaindex.cpp" />
     <ClInclude Include="collationtailoring.h" />
     <ClInclude Include="collationweights.h" />
     <ClInclude Include="dayperiodrules.h" />
+    <ClInclude Include="erarules.h" />
     <ClInclude Include="numsys_impl.h" />
     <ClInclude Include="region_impl.h" />
     <ClInclude Include="selfmtimpl.h" />
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
   </ImportGroup>
-</Project>
+</Project>
\ No newline at end of file
index 17b4e0764ddc8d1978550616f2118a00ecd37e73..35e1834098d93cbed8caeba010eb3974a10cf357 100644 (file)
 #include "unicode/utypes.h"
 
 #if !UCONFIG_NO_FORMATTING
-
+#if U_PLATFORM_HAS_WINUWP_API == 0
+#include <stdlib.h> // getenv() is not available in UWP env
+#endif
 #include "cmemory.h"
+#include "erarules.h"
 #include "japancal.h"
 #include "unicode/gregocal.h"
 #include "umutex.h"
 #include "uassert.h"
-
-//#define U_DEBUG_JCAL
-
-#ifdef U_DEBUG_JCAL
-#include <stdio.h>
-#endif
+#include "ucln_in.h"
+#include "cstring.h"
+
+static icu::EraRules * gJapaneseEraRules = nullptr;
+static icu::UInitOnce gJapaneseEraRulesInitOnce = U_INITONCE_INITIALIZER;
+static int32_t gCurrentEra = 0;
+
+U_CDECL_BEGIN
+static UBool japanese_calendar_cleanup(void) {
+    if (gJapaneseEraRules) {
+        delete gJapaneseEraRules;
+        gJapaneseEraRules = nullptr;
+    }
+    gCurrentEra = 0;
+    gJapaneseEraRulesInitOnce.reset();
+    return TRUE;
+}
+U_CDECL_END
 
 U_NAMESPACE_BEGIN
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(JapaneseCalendar)
 
-//  Gregorian date of each emperor's ascension
-//  Years are AD, months are 1-based.
-static const struct { 
-    int16_t year;
-    int8_t  month;
-    int8_t  day;
-} kEraInfo[] =  {
-    //  Year  Month Day
-    {   645,    6, 19 },   // Taika   0
-    {   650,    2, 15 },   // Hakuchi 1
-    {   672,    1,  1 },   // Hakuho  2
-    {   686,    7, 20 },   // Shucho  3
-    {   701,    3, 21 },   // Taiho   4
-    {   704,    5, 10 },   // Keiun   5
-    {   708,    1, 11 },   // Wado    6
-    {   715,    9,  2 },   // Reiki   7
-    {   717,   11, 17 },   // Yoro    8
-    {   724,    2,  4 },   // Jinki   9
-    {   729,    8,  5 },   // Tempyo  10
-    {   749,    4, 14 },   // Tempyo-kampo 11
-    {   749,    7,  2 },   // Tempyo-shoho 12
-    {   757,    8, 18 },   // Tempyo-hoji  13
-    {   765,    1,  7 },   // Tempho-jingo 14
-    {   767,    8, 16 },   // Jingo-keiun  15
-    {   770,   10,  1 },   // Hoki         16
-    {   781,    1,  1 },   // Ten-o        17
-    {   782,    8, 19 },   // Enryaku      18
-    {   806,    5, 18 },   // Daido        19
-    {   810,    9, 19 },   // Konin        20
-    {   824,    1,  5 },   // Tencho
-    {   834,    1,  3 },   // Showa
-    {   848,    6, 13 },   // Kajo
-    {   851,    4, 28 },   // Ninju
-    {   854,   11, 30 },   // Saiko
-    {   857,    2, 21 },   // Tennan
-    {   859,    4, 15 },   // Jogan
-    {   877,    4, 16 },   // Genkei
-    {   885,    2, 21 },   // Ninna
-    {   889,    4, 27 },   // Kampyo       30
-    {   898,    4, 26 },   // Shotai
-    {   901,    7, 15 },   // Engi
-    {   923,    4, 11 },   // Encho
-    {   931,    4, 26 },   // Shohei
-    {   938,    5, 22 },   // Tengyo
-    {   947,    4, 22 },   // Tenryaku
-    {   957,   10, 27 },   // Tentoku
-    {   961,    2, 16 },   // Owa
-    {   964,    7, 10 },   // Koho
-    {   968,    8, 13 },   // Anna        40
-    {   970,    3, 25 },   // Tenroku
-    {   973,   12, 20 },   // Ten-en
-    {   976,    7, 13 },   // Jogen
-    {   978,   11, 29 },   // Tengen
-    {   983,    4, 15 },   // Eikan
-    {   985,    4, 27 },   // Kanna
-    {   987,    4,  5 },   // Ei-en
-    {   989,    8,  8 },   // Eiso
-    {   990,   11,  7 },   // Shoryaku
-    {   995,    2, 22 },   // Chotoku      50
-    {   999,    1, 13 },   // Choho
-    {  1004,    7, 20 },   // Kanko
-    {  1012,   12, 25 },   // Chowa
-    {  1017,    4, 23 },   // Kannin
-    {  1021,    2,  2 },   // Jian
-    {  1024,    7, 13 },   // Manju
-    {  1028,    7, 25 },   // Chogen
-    {  1037,    4, 21 },   // Choryaku
-    {  1040,   11, 10 },   // Chokyu
-    {  1044,   11, 24 },   // Kantoku      60
-    {  1046,    4, 14 },   // Eisho
-    {  1053,    1, 11 },   // Tengi
-    {  1058,    8, 29 },   // Kohei
-    {  1065,    8,  2 },   // Jiryaku
-    {  1069,    4, 13 },   // Enkyu
-    {  1074,    8, 23 },   // Shoho
-    {  1077,   11, 17 },   // Shoryaku
-    {  1081,    2, 10 },   // Eiho
-    {  1084,    2,  7 },   // Otoku
-    {  1087,    4,  7 },   // Kanji       70
-    {  1094,   12, 15 },   // Kaho
-    {  1096,   12, 17 },   // Eicho
-    {  1097,   11, 21 },   // Shotoku
-    {  1099,    8, 28 },   // Kowa
-    {  1104,    2, 10 },   // Choji
-    {  1106,    4,  9 },   // Kasho
-    {  1108,    8,  3 },   // Tennin
-    {  1110,    7, 13 },   // Ten-ei
-    {  1113,    7, 13 },   // Eikyu
-    {  1118,    4,  3 },   // Gen-ei      80
-    {  1120,    4, 10 },   // Hoan
-    {  1124,    4,  3 },   // Tenji
-    {  1126,    1, 22 },   // Daiji
-    {  1131,    1, 29 },   // Tensho
-    {  1132,    8, 11 },   // Chosho
-    {  1135,    4, 27 },   // Hoen
-    {  1141,    7, 10 },   // Eiji
-    {  1142,    4, 28 },   // Koji
-    {  1144,    2, 23 },   // Tenyo
-    {  1145,    7, 22 },   // Kyuan      90
-    {  1151,    1, 26 },   // Ninpei
-    {  1154,   10, 28 },   // Kyuju
-    {  1156,    4, 27 },   // Hogen
-    {  1159,    4, 20 },   // Heiji
-    {  1160,    1, 10 },   // Eiryaku
-    {  1161,    9,  4 },   // Oho
-    {  1163,    3, 29 },   // Chokan
-    {  1165,    6,  5 },   // Eiman
-    {  1166,    8, 27 },   // Nin-an
-    {  1169,    4,  8 },   // Kao       100
-    {  1171,    4, 21 },   // Shoan
-    {  1175,    7, 28 },   // Angen
-    {  1177,    8,  4 },   // Jisho
-    {  1181,    7, 14 },   // Yowa
-    {  1182,    5, 27 },   // Juei
-    {  1184,    4, 16 },   // Genryuku
-    {  1185,    8, 14 },   // Bunji
-    {  1190,    4, 11 },   // Kenkyu
-    {  1199,    4, 27 },   // Shoji
-    {  1201,    2, 13 },   // Kennin     110
-    {  1204,    2, 20 },   // Genkyu
-    {  1206,    4, 27 },   // Ken-ei
-    {  1207,   10, 25 },   // Shogen
-    {  1211,    3,  9 },   // Kenryaku
-    {  1213,   12,  6 },   // Kenpo
-    {  1219,    4, 12 },   // Shokyu
-    {  1222,    4, 13 },   // Joo
-    {  1224,   11, 20 },   // Gennin
-    {  1225,    4, 20 },   // Karoku
-    {  1227,   12, 10 },   // Antei      120
-    {  1229,    3,  5 },   // Kanki
-    {  1232,    4,  2 },   // Joei
-    {  1233,    4, 15 },   // Tempuku
-    {  1234,   11,  5 },   // Bunryaku
-    {  1235,    9, 19 },   // Katei
-    {  1238,   11, 23 },   // Ryakunin
-    {  1239,    2,  7 },   // En-o
-    {  1240,    7, 16 },   // Ninji
-    {  1243,    2, 26 },   // Kangen
-    {  1247,    2, 28 },   // Hoji      130
-    {  1249,    3, 18 },   // Kencho
-    {  1256,   10,  5 },   // Kogen
-    {  1257,    3, 14 },   // Shoka
-    {  1259,    3, 26 },   // Shogen
-    {  1260,    4, 13 },   // Bun-o
-    {  1261,    2, 20 },   // Kocho
-    {  1264,    2, 28 },   // Bun-ei
-    {  1275,    4, 25 },   // Kenji
-    {  1278,    2, 29 },   // Koan
-    {  1288,    4, 28 },   // Shoo      140
-    {  1293,    8, 55 },   // Einin
-    {  1299,    4, 25 },   // Shoan
-    {  1302,   11, 21 },   // Kengen
-    {  1303,    8,  5 },   // Kagen
-    {  1306,   12, 14 },   // Tokuji
-    {  1308,   10,  9 },   // Enkei
-    {  1311,    4, 28 },   // Ocho
-    {  1312,    3, 20 },   // Showa
-    {  1317,    2,  3 },   // Bunpo
-    {  1319,    4, 28 },   // Geno      150
-    {  1321,    2, 23 },   // Genkyo
-    {  1324,   12,  9 },   // Shochu
-    {  1326,    4, 26 },   // Kareki
-    {  1329,    8, 29 },   // Gentoku
-    {  1331,    8,  9 },   // Genko
-    {  1334,    1, 29 },   // Kemmu
-    {  1336,    2, 29 },   // Engen
-    {  1340,    4, 28 },   // Kokoku
-    {  1346,   12,  8 },   // Shohei
-    {  1370,    7, 24 },   // Kentoku       160
-    {  1372,    4,  1 },   // Bunch\u0169
-    {  1375,    5, 27 },   // Tenju
-    {  1379,    3, 22 },   // Koryaku
-    {  1381,    2, 10 },   // Kowa
-    {  1384,    4, 28 },   // Gench\u0169
-    {  1384,    2, 27 },   // Meitoku
-    {  1387,    8, 23 },   // Kakei
-    {  1389,    2,  9 },   // Koo
-    {  1390,    3, 26 },   // Meitoku
-    {  1394,    7,  5 },   // Oei           170
-    {  1428,    4, 27 },   // Shocho
-    {  1429,    9,  5 },   // Eikyo
-    {  1441,    2, 17 },   // Kakitsu
-    {  1444,    2,  5 },   // Bun-an
-    {  1449,    7, 28 },   // Hotoku
-    {  1452,    7, 25 },   // Kyotoku
-    {  1455,    7, 25 },   // Kosho
-    {  1457,    9, 28 },   // Choroku
-    {  1460,   12, 21 },   // Kansho
-    {  1466,    2, 28 },   // Bunsho        180
-    {  1467,    3,  3 },   // Onin
-    {  1469,    4, 28 },   // Bunmei
-    {  1487,    7, 29 },   // Chokyo
-    {  1489,    8, 21 },   // Entoku
-    {  1492,    7, 19 },   // Meio
-    {  1501,    2, 29 },   // Bunki
-    {  1504,    2, 30 },   // Eisho
-    {  1521,    8, 23 },   // Taiei
-    {  1528,    8, 20 },   // Kyoroku
-    {  1532,    7, 29 },   // Tenmon       190
-    {  1555,   10, 23 },   // Koji
-    {  1558,    2, 28 },   // Eiroku
-    {  1570,    4, 23 },   // Genki
-    {  1573,    7, 28 },   // Tensho
-    {  1592,   12,  8 },   // Bunroku
-    {  1596,   10, 27 },   // Keicho
-    {  1615,    7, 13 },   // Genwa
-    {  1624,    2, 30 },   // Kan-ei
-    {  1644,   12, 16 },   // Shoho
-    {  1648,    2, 15 },   // Keian       200
-    {  1652,    9, 18 },   // Shoo
-    {  1655,    4, 13 },   // Meiryaku
-    {  1658,    7, 23 },   // Manji
-    {  1661,    4, 25 },   // Kanbun
-    {  1673,    9, 21 },   // Enpo
-    {  1681,    9, 29 },   // Tenwa
-    {  1684,    2, 21 },   // Jokyo
-    {  1688,    9, 30 },   // Genroku
-    {  1704,    3, 13 },   // Hoei
-    {  1711,    4, 25 },   // Shotoku      210
-    {  1716,    6, 22 },   // Kyoho
-    {  1736,    4, 28 },   // Genbun
-    {  1741,    2, 27 },   // Kanpo
-    {  1744,    2, 21 },   // Enkyo
-    {  1748,    7, 12 },   // Kan-en
-    {  1751,   10, 27 },   // Horyaku
-    {  1764,    6,  2 },   // Meiwa
-    {  1772,   11, 16 },   // An-ei
-    {  1781,    4,  2 },   // Tenmei
-    {  1789,    1, 25 },   // Kansei      220
-    {  1801,    2,  5 },   // Kyowa
-    {  1804,    2, 11 },   // Bunka
-    {  1818,    4, 22 },   // Bunsei
-    {  1830,   12, 10 },   // Tenpo
-    {  1844,   12,  2 },   // Koka
-    {  1848,    2, 28 },   // Kaei
-    {  1854,   11, 27 },   // Ansei
-    {  1860,    3, 18 },   // Man-en
-    {  1861,    2, 19 },   // Bunkyu
-    {  1864,    2, 20 },   // Genji        230
-    {  1865,    4,  7 },   // Keio     231
-    {  1868,    9,  8 },   // Meiji    232
-    {  1912,    7, 30 },   // Taisho   233
-    {  1926,   12, 25 },   // Showa    234
-    {  1989,    1,  8 }   // Heisei    235
-};
-
-#define kEraCount UPRV_LENGTHOF(kEraInfo)
-
-/**
- * The current era, for reference. 
- */
-static const int32_t kCurrentEra = (kEraCount-1);  // int32_t to match the calendar field type
-
 static const int32_t kGregorianEpoch = 1970;    // used as the default value of EXTENDED_YEAR
+static const char* TENTATIVE_ERA_VAR_NAME = "ICU_ENABLE_TENTATIVE_ERA";
+
+// Initialize global Japanese era data
+static void U_CALLCONV initializeEras(UErrorCode &status) {
+    // Although start date of next Japanese era is planned ahead, a name of
+    // new era might not be available. This implementation allows tester to
+    // check a new era without era names by settings below (in priority order).
+    // By default, such tentative era is disabled.
+
+    // 1. Environment variable ICU_ENABLE_TENTATIVE_ERA=true or false
+    // 2. Windows registry (TBD)
+
+    UBool includeTentativeEra = FALSE;
+
+#if U_PLATFORM_HAS_WINUWP_API == 0
+    char *envVarVal = getenv(TENTATIVE_ERA_VAR_NAME);
+    if (envVarVal != NULL && uprv_stricmp(envVarVal, "true") == 0) {
+        includeTentativeEra = TRUE;
+    }
+#endif
+    gJapaneseEraRules = EraRules::createInstance("japanese", includeTentativeEra, status);
+    if (U_FAILURE(status)) {
+        return;
+    }
+    gCurrentEra = gJapaneseEraRules->getCurrentEraIndex();
+}
+
+static void init(UErrorCode &status) {
+    umtx_initOnce(gJapaneseEraRulesInitOnce, &initializeEras, status);
+    ucln_i18n_registerCleanup(UCLN_I18N_JAPANESE_CALENDAR, japanese_calendar_cleanup);
+}
 
 /* Some platforms don't like to export constants, like old Palm OS and some z/OS configurations. */
 uint32_t JapaneseCalendar::getCurrentEra() {
-    return kCurrentEra;
+    return gCurrentEra;
 }
 
 JapaneseCalendar::JapaneseCalendar(const Locale& aLocale, UErrorCode& success)
 :   GregorianCalendar(aLocale, success)
 {
+    init(success);
     setTimeInMillis(getNow(), success); // Call this again now that the vtable is set up properly.
 }
 
@@ -306,6 +100,9 @@ JapaneseCalendar::~JapaneseCalendar()
 JapaneseCalendar::JapaneseCalendar(const JapaneseCalendar& source)
 : GregorianCalendar(source)
 {
+    UErrorCode status = U_ZERO_ERROR;
+    init(status);
+    U_ASSERT(U_SUCCESS(status));
 }
 
 JapaneseCalendar& JapaneseCalendar::operator= ( const JapaneseCalendar& right)
@@ -332,10 +129,14 @@ int32_t JapaneseCalendar::getDefaultMonthInYear(int32_t eyear)
     int32_t month = 0;
 
     // Find out if we are at the edge of an era
-
-    if(eyear == kEraInfo[era].year) {
+    int32_t eraStart[3] = { 0,0,0 };
+    UErrorCode status = U_ZERO_ERROR;
+    gJapaneseEraRules->getStartDate(era, eraStart, status);
+    U_ASSERT(U_SUCCESS(status));
+    if(eyear == eraStart[0]) {
         // Yes, we're in the first year of this era.
-        return kEraInfo[era].month-1;
+        return eraStart[1]  // month
+                -1;         // return 0-based month
     }
 
     return month;
@@ -346,9 +147,13 @@ int32_t JapaneseCalendar::getDefaultDayInMonth(int32_t eyear, int32_t month)
     int32_t era = internalGetEra();
     int32_t day = 1;
 
-    if(eyear == kEraInfo[era].year) {
-        if(month == (kEraInfo[era].month-1)) {
-            return kEraInfo[era].day;
+    int32_t eraStart[3] = { 0,0,0 };
+    UErrorCode status = U_ZERO_ERROR;
+    gJapaneseEraRules->getStartDate(era, eraStart, status);
+    U_ASSERT(U_SUCCESS(status));
+    if(eyear == eraStart[0]) {
+        if(month == eraStart[1] - 1) {
+            return eraStart[2];
         }
     }
 
@@ -358,7 +163,7 @@ int32_t JapaneseCalendar::getDefaultDayInMonth(int32_t eyear, int32_t month)
 
 int32_t JapaneseCalendar::internalGetEra() const
 {
-    return internalGet(UCAL_ERA, kCurrentEra);
+    return internalGet(UCAL_ERA, gCurrentEra);
 }
 
 int32_t JapaneseCalendar::handleGetExtendedYear()
@@ -369,12 +174,18 @@ int32_t JapaneseCalendar::handleGetExtendedYear()
 
     if (newerField(UCAL_EXTENDED_YEAR, UCAL_YEAR) == UCAL_EXTENDED_YEAR &&
         newerField(UCAL_EXTENDED_YEAR, UCAL_ERA) == UCAL_EXTENDED_YEAR) {
-            year = internalGet(UCAL_EXTENDED_YEAR, kGregorianEpoch);
-        } else {
-            // Subtract one because year starts at 1
-            year = internalGet(UCAL_YEAR) + kEraInfo[internalGetEra()].year - 1;
-        }
-        return year;
+        year = internalGet(UCAL_EXTENDED_YEAR, kGregorianEpoch);
+    } else {
+        UErrorCode status = U_ZERO_ERROR;
+        int32_t eraStartYear = gJapaneseEraRules->getStartYear(internalGet(UCAL_ERA, gCurrentEra), status);
+        U_ASSERT(U_SUCCESS(status));
+
+        // extended year is a gregorian year, where 1 = 1AD,  0 = 1BC, -1 = 2BC, etc
+        year = internalGet(UCAL_YEAR, 1)    // pin to minimum of year 1 (first year)
+            + eraStartYear                  // add gregorian starting year
+            - 1;                            // Subtract one because year starts at 1
+    }
+    return year;
 }
 
 
@@ -383,79 +194,10 @@ void JapaneseCalendar::handleComputeFields(int32_t julianDay, UErrorCode& status
     //Calendar::timeToFields(theTime, quick, status);
     GregorianCalendar::handleComputeFields(julianDay, status);
     int32_t year = internalGet(UCAL_EXTENDED_YEAR); // Gregorian year
+    int32_t eraIdx = gJapaneseEraRules->getEraIndex(year, internalGet(UCAL_MONTH) + 1, internalGet(UCAL_DAY_OF_MONTH), status);
 
-    int32_t low = 0;
-
-    // Short circuit for recent years.  Most modern computations will
-    // occur in the current era and won't require the binary search.
-    // Note that if the year is == the current era year, then we use
-    // the binary search to handle the month/dom comparison.
-#ifdef U_DEBUG_JCAL
-    fprintf(stderr, "==  %d \n", year);
-#endif
-
-    if (year > kEraInfo[kCurrentEra].year) {
-        low = kCurrentEra;
-#ifdef U_DEBUG_JCAL
-        fprintf(stderr, " low=%d (special)\n", low);
-#endif
-    } else {
-        // Binary search
-        int32_t high = kEraCount;
-
-#ifdef U_DEBUG_JCAL
-        fprintf(stderr, " high=%d\n", high);
-#endif
-        while (low < high - 1) {
-            int32_t i = (low + high) / 2;
-            int32_t diff = year - kEraInfo[i].year;
-
-#ifdef U_DEBUG_JCAL
-            fprintf(stderr, "  d=%d   low=%d, high=%d. Considering %d:M%d D%d Y%d. { we are ?:M%d D%d Y%d }\n",
-                diff,low, high, i, kEraInfo[i].month-1, kEraInfo[i].day,  kEraInfo[i].year, internalGet(UCAL_MONTH), internalGet(UCAL_DATE),year);
-#endif
-
-            // If years are the same, then compare the months, and if those
-            // are the same, compare days of month.  In the ERAS array
-            // months are 1-based for easier maintenance.
-            if (diff == 0) {
-                diff = internalGet(UCAL_MONTH) - (kEraInfo[i].month - 1);
-#ifdef U_DEBUG_JCAL
-                fprintf(stderr, "diff now %d (M)  = %d - %d - 1\n", diff, internalGet(UCAL_MONTH), kEraInfo[i].month);
-#endif
-                if (diff == 0) {
-                    diff = internalGet(UCAL_DATE) - kEraInfo[i].day;
-#ifdef U_DEBUG_JCAL
-                    fprintf(stderr, "diff now %d (D)\n", diff);
-#endif
-                }
-            }
-            if (diff >= 0) {
-                low = i;
-            } else {
-                high = i;
-            }
-#ifdef U_DEBUG_JCAL
-            fprintf(stderr, ". low=%d, high=%d, i=%d, diff=%d.. %d\n", low, high, i, diff, year);
-#endif
-
-        }
-    }
-
-#ifdef U_DEBUG_JCAL
-    fprintf(stderr, "  low[era]=%d,.. %d\n", low, year);
-#endif
-    // Now we've found the last era that starts before this date, so
-    // adjust the year to count from the start of that era.  Note that
-    // all dates before the first era will fall into the first era by
-    // the algorithm.
-
-    internalSet(UCAL_ERA, low);
-    internalSet(UCAL_YEAR, year - kEraInfo[low].year + 1);
-#ifdef U_DEBUG_JCAL
-    fprintf(stderr, "  Set ERA=%d, year=%d\n", low, year-kEraInfo[low].year+1);
-#endif
-
+    internalSet(UCAL_ERA, eraIdx);
+    internalSet(UCAL_YEAR, year - gJapaneseEraRules->getStartYear(eraIdx, status) + 1);
 }
 
 /*
@@ -483,7 +225,7 @@ int32_t JapaneseCalendar::handleGetLimit(UCalendarDateFields field, ELimitType l
         if (limitType == UCAL_LIMIT_MINIMUM || limitType == UCAL_LIMIT_GREATEST_MINIMUM) {
             return 0;
         }
-        return kCurrentEra;
+        return gCurrentEra;
     case UCAL_YEAR:
         {
             switch (limitType) {
@@ -494,7 +236,12 @@ int32_t JapaneseCalendar::handleGetLimit(UCalendarDateFields field, ELimitType l
                 return 1;
             case  UCAL_LIMIT_COUNT: //added to avoid warning
             case UCAL_LIMIT_MAXIMUM:
-                return GregorianCalendar::handleGetLimit(UCAL_YEAR, UCAL_LIMIT_MAXIMUM) - kEraInfo[kCurrentEra].year;
+            {
+                UErrorCode status = U_ZERO_ERROR;
+                int32_t eraStartYear = gJapaneseEraRules->getStartYear(gCurrentEra, status);
+                U_ASSERT(U_SUCCESS(status));
+                return GregorianCalendar::handleGetLimit(UCAL_YEAR, UCAL_LIMIT_MAXIMUM) - eraStartYear;
+            }
             default:
                 return 1;    // Error condition, invalid limitType
             }
@@ -510,15 +257,18 @@ int32_t JapaneseCalendar::getActualMaximum(UCalendarDateFields field, UErrorCode
         if (U_FAILURE(status)) {
             return 0; // error case... any value
         }
-        if (era == kCurrentEra) {
+        if (era == gCurrentEra) {
             // TODO: Investigate what value should be used here - revisit after 4.0.
             return handleGetLimit(UCAL_YEAR, UCAL_LIMIT_MAXIMUM);
         } else {
-            int32_t nextEraYear = kEraInfo[era + 1].year;
-            int32_t nextEraMonth = kEraInfo[era + 1].month;
-            int32_t nextEraDate = kEraInfo[era + 1].day;
-
-            int32_t maxYear = nextEraYear - kEraInfo[era].year + 1; // 1-base
+            int32_t nextEraStart[3] = { 0,0,0 };
+            gJapaneseEraRules->getStartDate(era + 1, nextEraStart, status);
+            int32_t nextEraYear = nextEraStart[0];
+            int32_t nextEraMonth = nextEraStart[1]; // 1-base
+            int32_t nextEraDate = nextEraStart[2];
+
+            int32_t eraStartYear = gJapaneseEraRules->getStartYear(era, status);
+            int32_t maxYear = nextEraYear - eraStartYear + 1;   // 1-base
             if (nextEraMonth == 1 && nextEraDate == 1) {
                 // Subtract 1, because the next era starts at Jan 1
                 maxYear--;
index f05b2ac9b779eb0caaef19bce84380ba9e54de74..7a6d13228b1e95849f0431dd742c9c57dfe7907f 100644 (file)
@@ -49,10 +49,18 @@ U_NAMESPACE_BEGIN
  * July 30, 1912 (Taisho), December 25, 1926 (Showa), and January 7, 1989 (Heisei).  Constants
  * for these eras, suitable for use in the <code>UCAL_ERA</code> field, are provided
  * in this class.  Note that the <em>number</em> used for each era is more or
- * less arbitrary.  Currently, the era starting in 1053 AD is era #0; however this
- * may change in the future as we add more historical data.  Use the predefined
- * constants rather than using actual, absolute numbers.
+ * less arbitrary.  Currently, the era starting in 645 AD is era #0; however this
+ * may change in the future.  Use the predefined constants rather than using actual,
+ * absolute numbers.
  * <p>
+ * Since ICU4C 63, start date of each era is imported from CLDR. CLDR era data
+ * may contain tentative era in near future with placeholder names. By default,
+ * such era data is not enabled. ICU4C users who want to test the behavior of
+ * the future era can enable this one of following settings (in the priority
+ * order):
+ * <ol>
+ * <li>Environment variable <code>ICU_ENABLE_TENTATIVE_ERA=true</code>.</li>
+ * </nl>
  * @internal
  */
 class JapaneseCalendar : public GregorianCalendar {
index 337621f4abc4841de08230598c14586c3f410ac7..4c13b9ffcb539a32829572b22babf030409e5557 100644 (file)
@@ -32,6 +32,7 @@ typedef enum ECleanupI18NType {
     UCLN_I18N_SPOOFDATA,
     UCLN_I18N_TRANSLITERATOR,
     UCLN_I18N_REGEX,
+    UCLN_I18N_JAPANESE_CALENDAR,
     UCLN_I18N_ISLAMIC_CALENDAR,
     UCLN_I18N_CHINESE_CALENDAR,
     UCLN_I18N_HEBREW_CALENDAR,
index bf72edfc0bf283715407e33c0d79257c3060d37a..e961c1c649485984f617bcb991f84ea0cab01077 100644 (file)
@@ -167,6 +167,19 @@ class BasicTimeZone;
  * to ~5,800,000 CE. Programmers should use the protected constants in `Calendar` to
  * specify an extremely early or extremely late date.
  *
+ * <p>
+ * The Japanese calendar uses a combination of era name and year number.
+ * When an emperor of Japan abdicates and a new emperor ascends the throne,
+ * a new era is declared and year number is reset to 1. Even if the date of
+ * abdication is scheduled ahead of time, the new era name might not be
+ * announced until just before the date. In such case, ICU4C may include
+ * a start date of future era without actual era name, but not enabled
+ * by default. ICU4C users who want to test the behavior of the future era
+ * can enable the tentative era by:
+ * <ul>
+ * <li>Environment variable <code>ICU_ENABLE_TENTATIVE_ERA=true</code>.</li>
+ * </ul>
+ *
  * @stable ICU 2.0
  */
 class U_I18N_API Calendar : public UObject {
index c765e7859f59f489b7f6d4f1ba9d263d342ecbe7..fb7c387c2d7a540efce3a01b4f00e2ee1a6e2344 100644 (file)
  * For example, subtracting 5 days from the date <code>September 12, 1996</code>
  * results in <code>September 7, 1996</code>.
  *
+ * <p>
+ * The Japanese calendar uses a combination of era name and year number.
+ * When an emperor of Japan abdicates and a new emperor ascends the throne,
+ * a new era is declared and year number is reset to 1. Even if the date of
+ * abdication is scheduled ahead of time, the new era name might not be
+ * announced until just before the date. In such case, ICU4C may include
+ * a start date of future era without actual era name, but not enabled
+ * by default. ICU4C users who want to test the behavior of the future era
+ * can enable the tentative era by:
+ * <ul>
+ * <li>Environment variable <code>ICU_ENABLE_TENTATIVE_ERA=true</code>.</li>
+ * </ul>
+ *
  * @stable ICU 2.0
  */
 
index c2b38c688f76378bb60baa4f2332d6fa689cd9de..4d3e17435ea5de6f5e8672d1678c89693430e6c5 100644 (file)
@@ -66,7 +66,7 @@ numbertest_affixutils.o numbertest_api.o numbertest_decimalquantity.o \
 numbertest_modifiers.o numbertest_patternmodifier.o numbertest_patternstring.o \
 numbertest_stringbuilder.o numbertest_stringsegment.o \
 numbertest_parse.o numbertest_doubleconversion.o numbertest_skeletons.o \
-static_unisets_test.o numfmtdatadriventest.o
+static_unisets_test.o numfmtdatadriventest.o erarulestest.o
 
 DEPS = $(OBJECTS:.o=.d)
 
diff --git a/icu4c/source/test/intltest/erarulestest.cpp b/icu4c/source/test/intltest/erarulestest.cpp
new file mode 100644 (file)
index 0000000..b550361
--- /dev/null
@@ -0,0 +1,130 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "unicode/calendar.h"
+#include "unicode/localpointer.h"
+#include "unicode/unistr.h"
+#include "erarules.h"
+#include "erarulestest.h"
+
+void EraRulesTest::runIndexedTest(int32_t index, UBool exec, const char* &name, char* /*par*/)
+{
+    if (exec) {
+        logln("TestSuite EraRulesTest");
+    }
+    TESTCASE_AUTO_BEGIN;
+    TESTCASE_AUTO(testAPIs);
+    TESTCASE_AUTO(testJapanese);
+    TESTCASE_AUTO_END;
+}
+
+void EraRulesTest::testAPIs() {
+    const char * calTypes[] = {
+        "gregorian",
+        //"iso8601",
+        "buddhist",
+        "chinese",
+        "coptic",
+        "dangi",
+        "ethiopic",
+        "ethiopic-amete-alem",
+        "hebrew",
+        "indian",
+        "islamic",
+        "islamic-civil",
+        "islamic-rgsa",
+        "islamic-tbla",
+        "islamic-umalqura",
+        "japanese",
+        "persian",
+        "roc",
+        //"unknown",
+        NULL
+    };
+
+    for (int32_t i = 0; calTypes[i] != NULL; i++) {
+        UErrorCode status = U_ZERO_ERROR;
+        const char *calId = calTypes[i];
+
+        LocalPointer<EraRules> rules1(EraRules::createInstance(calId, FALSE, status));
+        if (U_FAILURE(status)) {
+            errln(UnicodeString("Era rules for ") + calId + " is not available.");
+            continue;
+        }
+
+        LocalPointer<EraRules> rules2(EraRules::createInstance(calId, TRUE, status));
+        if (U_FAILURE(status)) {
+            errln(UnicodeString("Era rules for ") + calId + " (including tentative eras) is not available.");
+            continue;
+        }
+
+        int32_t numEras1 = rules1->getNumberOfEras();
+        if (numEras1 <= 0) {
+            errln(UnicodeString("Number of era rules for ") + calId + " is " + numEras1);
+        }
+
+        int32_t numEras2 = rules2->getNumberOfEras();
+        if (numEras2 < numEras1) {
+            errln(UnicodeString("Number of era including tentative eras is fewer than one without tentative eras in calendar: ")
+                    + calId);
+        }
+
+        LocalPointer<Calendar> cal(Calendar::createInstance("en", status));
+        if (U_FAILURE(status)) {
+            errln("Failed to create a Calendar instance.");
+            continue;
+        }
+        int32_t currentIdx = rules1->getCurrentEraIndex();
+        int32_t currentYear = cal->get(UCAL_YEAR, status);
+        int32_t idx = rules1->getEraIndex(
+                currentYear, cal->get(UCAL_MONTH, status) + 1,
+                cal->get(UCAL_DATE, status), status);
+        if (U_FAILURE(status)) {
+            errln("Error while getting index of era.");
+            continue;
+        }
+        if (idx != currentIdx) {
+            errln(UnicodeString("Current era index:") + currentIdx + " is different from era index of now:" + idx
+                    + " in calendar:" + calId);
+        }
+
+        int32_t eraStartYear = rules1->getStartYear(currentIdx, status);
+        if (U_FAILURE(status)) {
+            errln(UnicodeString("Failed to get the start year of era index: ") + currentIdx + " in calendar: " + calId);
+        }
+        if (currentYear < eraStartYear) {
+            errln(UnicodeString("Current era's start year is after the current year in calendar:") + calId);
+        }
+    }
+}
+
+void EraRulesTest::testJapanese() {
+    const int32_t HEISEI = 235; // ICU4C does not define constants for eras
+
+    UErrorCode status = U_ZERO_ERROR;
+    LocalPointer<EraRules> rules(EraRules::createInstance("japanese", TRUE, status));
+    if (U_FAILURE(status)) {
+        errln("Failed to get era rules for Japanese calendar.");
+        return;
+    }
+    // Rules should have an era after Heisei
+    int32_t numRules = rules->getNumberOfEras();
+    if (numRules <= HEISEI) {
+        errln("Era after Heisei is not available.");
+        return;
+    }
+    int postHeiseiStartYear = rules->getStartYear(HEISEI + 1, status);
+    if (U_FAILURE(status)) {
+        errln("Failed to get the start year of era after Heisei.");
+    }
+    if (postHeiseiStartYear != 2019) {
+        errln(UnicodeString("Era after Heisei should start in 2019, but got ") + postHeiseiStartYear);
+    }
+}
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
+
diff --git a/icu4c/source/test/intltest/erarulestest.h b/icu4c/source/test/intltest/erarulestest.h
new file mode 100644 (file)
index 0000000..28116af
--- /dev/null
@@ -0,0 +1,23 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
+
+#ifndef ERARULESTEST_H_
+#define ERARULESTEST_H_
+
+#include "unicode/utypes.h"
+
+#if !UCONFIG_NO_FORMATTING
+
+#include "intltest.h"
+
+class EraRulesTest : public IntlTest {
+public:
+    void runIndexedTest(int32_t index, UBool exec, const char* &name, char* par = NULL);
+
+private:
+    void testAPIs();
+    void testJapanese();
+};
+
+#endif /* #if !UCONFIG_NO_FORMATTING */
+#endif /* ERARULESTEST_H_ */
index 0d7bae442ba41e2b54237e5d455b0935380932f7..60d34a0c95710719dec5698e0846bb5a20235b65 100644 (file)
@@ -2,7 +2,6 @@
 <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <!-- The following import will include the 'default' configuration options for VS projects. -->
   <Import Project="..\..\allinone\Build.Windows.ProjectConfiguration.props" />
-
   <PropertyGroup Label="Globals">
     <ProjectGuid>{73632960-B3A6-464D-83A3-4B43365F19B8}</ProjectGuid>
     <RootNamespace>intltest</RootNamespace>
     <ClCompile Include="colldata.cpp">
       <DisableLanguageExtensions>false</DisableLanguageExtensions>
     </ClCompile>
+    <ClCompile Include="erarulestest.cpp" />
     <ClCompile Include="numfmtspectest.cpp" />
     <ClCompile Include="regiontst.cpp" />
     <ClCompile Include="ucharstrietest.cpp" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="colldata.h" />
+    <ClInclude Include="erarulestest.h" />
     <ClInclude Include="itrbbi.h" />
     <ClInclude Include="rbbiapts.h" />
     <ClInclude Include="rbbitst.h" />
index 4fea4428844fa97c382968e2a10b017977d6a15e..fc2ecb53050d4efb58d46ea1f277391266f5a06c 100644 (file)
@@ -72,7 +72,7 @@
     </ClCompile>
     <ClCompile Include="rbbimonkeytest.cpp">
       <Filter>break iteration</Filter>
-      </ClCompile>
+    </ClCompile>
     <ClCompile Include="itspoof.cpp">
       <Filter>spoof detection</Filter>
     </ClCompile>
     <ClCompile Include="ucharstrietest.cpp">
       <Filter>data &amp; memory</Filter>
     </ClCompile>
+    <ClCompile Include="erarulestest.cpp">
+      <Filter>formatting</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="itrbbi.h">
     <ClInclude Include="listformattertest.h">
       <Filter>formatting</Filter>
     </ClInclude>
+    <ClInclude Include="erarulestest.h">
+      <Filter>formatting</Filter>
+    </ClInclude>
   </ItemGroup>
-</Project>
+</Project>
\ No newline at end of file
index cea3249a44873eef45197f2676e9dca82f2c9a58..d450922eb6ed38ef119572f3c7c55d14c3cb9cf0 100644 (file)
@@ -60,6 +60,7 @@
 #include "listformattertest.h"  // ListFormatterTest
 #include "regiontst.h"      // RegionTest
 #include "numbertest.h"     // NumberTest
+#include "erarulestest.h"   // EraRulesTest
 
 extern IntlTest *createCompactDecimalFormatTest();
 extern IntlTest *createGenderInfoTest();
@@ -215,6 +216,7 @@ void IntlTestFormat::runIndexedTest( int32_t index, UBool exec, const char* &nam
           break;
         TESTCLASS(50,NumberFormatDataDrivenTest);
         TESTCLASS(51,NumberTest);
+        TESTCLASS(52,EraRulesTest);
         default: name = ""; break; //needed to end loop
     }
     if (exec) {
index a49de07741ddd742207bc9082c014f4a7522a3c5..c0c2012aa780b8eee58a110fabc359e3bb6c4d9f 100644 (file)
@@ -25805,6 +25805,7 @@ structLocale:table(nofallback){
                     "",
                     "",
                     "",
+                    "",
                 }
                 wide{
                     "",
@@ -26043,6 +26044,7 @@ structLocale:table(nofallback){
                     "",
                     "",
                     "",
+                    "",
                 }
                 narrow{
                     "",
@@ -26281,6 +26283,7 @@ structLocale:table(nofallback){
                     "",
                     "",
                     "",
+                    "",
                 }
             }
             intervalFormats{
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/CalType.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/CalType.java
new file mode 100644 (file)
index 0000000..ad9c3bb
--- /dev/null
@@ -0,0 +1,42 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+package com.ibm.icu.impl;
+
+/**
+ * Calendar type enum, moved from com.ibm.icu.util.Calendar.
+ *
+ * @author Yoshito Umaoka
+ */
+public enum CalType {
+    GREGORIAN("gregorian"),
+    ISO8601("iso8601"),
+
+    BUDDHIST("buddhist"),
+    CHINESE("chinese"),
+    COPTIC("coptic"),
+    DANGI("dangi"),
+    ETHIOPIC("ethiopic"),
+    ETHIOPIC_AMETE_ALEM("ethiopic-amete-alem"),
+    HEBREW("hebrew"),
+    INDIAN("indian"),
+    ISLAMIC("islamic"),
+    ISLAMIC_CIVIL("islamic-civil"),
+    ISLAMIC_RGSA("islamic-rgsa"),
+    ISLAMIC_TBLA("islamic-tbla"),
+    ISLAMIC_UMALQURA("islamic-umalqura"),
+    JAPANESE("japanese"),
+    PERSIAN("persian"),
+    ROC("roc"),
+
+    UNKNOWN("unknown");
+
+    String id;
+
+    CalType(String id) {
+        this.id = id;
+    }
+
+    public String getId() {
+        return id;
+    }
+}
diff --git a/icu4j/main/classes/core/src/com/ibm/icu/impl/EraRules.java b/icu4j/main/classes/core/src/com/ibm/icu/impl/EraRules.java
new file mode 100644 (file)
index 0000000..9b82396
--- /dev/null
@@ -0,0 +1,309 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+package com.ibm.icu.impl;
+
+import java.util.Arrays;
+
+import com.ibm.icu.util.ICUException;
+import com.ibm.icu.util.UResourceBundle;
+import com.ibm.icu.util.UResourceBundleIterator;
+
+/**
+ * <code>EraRules</code> represents calendar era rules specified
+ * in supplementalData/calendarData.
+ *
+ * @author Yoshito Umaoka
+ */
+public class EraRules {
+    private static final int MAX_ENCODED_START_YEAR = 32767;
+    private static final int MIN_ENCODED_START_YEAR = -32768;
+
+    public static final int MIN_ENCODED_START = encodeDate(MIN_ENCODED_START_YEAR, 1, 1);
+
+    private static final int YEAR_MASK = 0xFFFF0000;
+    private static final int MONTH_MASK = 0x0000FF00;
+    private static final int DAY_MASK = 0x000000FF;
+
+    private int[] startDates;
+    private int numEras;
+    private int currentEra;
+
+    private EraRules(int[] startDates, int numEras) {
+        this.startDates = startDates;
+        this.numEras = numEras;
+        initCurrentEra();
+    }
+
+    public static EraRules getInstance(CalType calType, boolean includeTentativeEra) {
+        UResourceBundle supplementalDataRes = UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME,
+                "supplementalData", ICUResourceBundle.ICU_DATA_CLASS_LOADER);
+        UResourceBundle calendarDataRes = supplementalDataRes.get("calendarData");
+        UResourceBundle calendarTypeRes = calendarDataRes.get(calType.getId());
+        UResourceBundle erasRes = calendarTypeRes.get("eras");
+
+        int numEras = erasRes.getSize();
+        int firstTentativeIdx = Integer.MAX_VALUE; // first tentative era index
+        int[] startDates = new int[numEras];
+
+        UResourceBundleIterator itr = erasRes.getIterator();
+        while (itr.hasNext()) {
+            UResourceBundle eraRuleRes = itr.next();
+            String eraIdxStr = eraRuleRes.getKey();
+            int eraIdx = -1;
+            try {
+                eraIdx = Integer.parseInt(eraIdxStr);
+            } catch (NumberFormatException e) {
+                throw new ICUException("Invald era rule key:" + eraIdxStr + " in era rule data for " + calType.getId());
+            }
+            if (eraIdx < 0 || eraIdx >= numEras) {
+                throw new ICUException("Era rule key:" + eraIdxStr + " in era rule data for " + calType.getId()
+                        + " must be in range [0, " + (numEras - 1) + "]");
+            }
+            if (isSet(startDates[eraIdx])) {
+                throw new ICUException(
+                        "Dupulicated era rule for rule key:" + eraIdxStr + " in era rule data for " + calType.getId());
+            }
+
+            boolean hasName = true;
+            boolean hasEnd = false;
+            UResourceBundleIterator ruleItr = eraRuleRes.getIterator();
+            while (ruleItr.hasNext()) {
+                UResourceBundle res = ruleItr.next();
+                String key = res.getKey();
+                if (key.equals("start")) {
+                    int[] fields = res.getIntVector();
+                    if (fields.length != 3 || !isValidRuleStartDate(fields[0], fields[1], fields[2])) {
+                        throw new ICUException(
+                                "Invalid era rule date data:" + Arrays.toString(fields) + " in era rule data for "
+                                + calType.getId());
+                    }
+                    startDates[eraIdx] = encodeDate(fields[0], fields[1], fields[2]);
+                } else if (key.equals("named")) {
+                    String val = res.getString();
+                    if (val.equals("false")) {
+                        hasName = false;
+                    }
+                } else if (key.equals("end")) {
+                    hasEnd = true;
+                }
+            }
+            if (isSet(startDates[eraIdx])) {
+                if (hasEnd) {
+                    // This implementation assumes either start or end is available, not both.
+                    // For now, just ignore the end rule.
+                }
+            } else {
+                if (hasEnd) {
+                    if (eraIdx != 0) {
+                        // This implementation does not support end only rule for eras other than
+                        // the first one.
+                        throw new ICUException(
+                                "Era data for " + eraIdxStr + " in era rule data for " + calType.getId()
+                                + " has only end rule.");
+                    }
+                    startDates[eraIdx] = MIN_ENCODED_START;
+                } else {
+                    throw new ICUException("Missing era start/end rule date for key:" + eraIdxStr + " in era rule data for "
+                            + calType.getId());
+                }
+            }
+
+            if (hasName) {
+                if (eraIdx >= firstTentativeIdx) {
+                    throw new ICUException(
+                            "Non-tentative era(" + eraIdx + ") must be placed before the first tentative era");
+                }
+            } else {
+                if (eraIdx < firstTentativeIdx) {
+                    firstTentativeIdx = eraIdx;
+                }
+            }
+        }
+
+        if (firstTentativeIdx < Integer.MAX_VALUE && !includeTentativeEra) {
+            return new EraRules(startDates, firstTentativeIdx);
+        }
+
+        return new EraRules(startDates, numEras);
+    }
+
+    /**
+     * Gets number of effective eras
+     * @return  number of effective eras
+     */
+    public int getNumberOfEras() {
+        return numEras;
+    }
+
+    /**
+     * Gets start date of an era
+     * @param eraIdx    Era index
+     * @param fillIn    Receives date fields if supplied. If null, or size of array
+     *                  is less than 3, then a new int[] will be newly allocated.
+     * @return  An int array including values of year, month, day of month in this order.
+     *          When an era has no start date, the result will be January 1st in year
+     *          whose value is minimum integer.
+     */
+    public int[] getStartDate(int eraIdx, int[] fillIn) {
+        if (eraIdx < 0 || eraIdx >= numEras) {
+            throw new IllegalArgumentException("eraIdx is out of range");
+        }
+        return decodeDate(startDates[eraIdx], fillIn);
+    }
+
+    /**
+     * Gets start year of an era
+     * @param eraIdx    Era index
+     * @return  The first year of an era. When a era has no start date, minimum integer
+     *          value is returned.
+     */
+    public int getStartYear(int eraIdx) {
+        if (eraIdx < 0 || eraIdx >= numEras) {
+            throw new IllegalArgumentException("eraIdx is out of range");
+        }
+        int[] fields = decodeDate(startDates[eraIdx], null);
+        return fields[0];
+    }
+
+    /**
+     * Returns era index for the specified year/month/day.
+     * @param year  Year
+     * @param month Month (1-base)
+     * @param day   Day of month
+     * @return  era index (or 0, when the specified date is before the first era)
+     */
+    public int getEraIndex(int year, int month, int day) {
+        if (month < 1 || month > 12 || day < 1 || day > 31) {
+            throw new IllegalArgumentException("Illegal date - year:" + year + "month:" + month + "day:" + day);
+        }
+        int high = numEras; // last index + 1
+        int low;
+
+        // Short circuit for recent years.  Most modern computations will
+        // occur in the last few eras.
+        if (compareEncodedDateWithYMD(startDates[getCurrentEraIndex()], year, month, day) <= 0) {
+            low = getCurrentEraIndex();
+        } else {
+            low = 0;
+        }
+
+        // Do binary search
+        while (low < high - 1) {
+            int i = (low + high) / 2;
+            if (compareEncodedDateWithYMD(startDates[i], year, month, day) <= 0) {
+                low = i;
+            } else {
+                high = i;
+            }
+        }
+        return low;
+    }
+
+    /**
+     * Gets the current era index. This is calculated only once for an instance of
+     * EraRules.
+     *
+     * @return era index of current era (or 0, when current date is before the first era)
+     */
+    public int getCurrentEraIndex() {
+        return currentEra;
+    }
+
+    private void initCurrentEra() {
+        int[] fields = Grego.timeToFields(System.currentTimeMillis(), null);
+        int currentEncodedDate = encodeDate(fields[0], fields[1] + 1 /* changes to 1-base */, fields[2]);
+        int eraIdx = numEras - 1;
+        while (eraIdx > 0) {
+            if (currentEncodedDate >= startDates[eraIdx]) {
+                break;
+            }
+            eraIdx--;
+        }
+        // Note: current era could be before the first era.
+        // In this case, this implementation returns the first era index (0).
+        currentEra = eraIdx;
+    }
+
+    //
+    // private methods
+    //
+
+    private static boolean isSet(int startDate) {
+        return startDate != 0;
+    }
+
+    private static boolean isValidRuleStartDate(int year, int month, int day) {
+        return year >= MIN_ENCODED_START_YEAR && year <= MAX_ENCODED_START_YEAR
+                && month >= 1 && month <= 12 && day >= 1 && day <= 31;
+    }
+
+    /**
+     * Encode year/month/date to a single integer.
+     * year is high 16 bits (-32768 to 32767), month is
+     * next 8 bits and day of month is last 8 bits.
+     *
+     * @param year  year
+     * @param month month (1-base)
+     * @param day   day of month
+     * @return  an encoded date.
+     */
+    private static int encodeDate(int year, int month, int day) {
+        return year << 16 | month << 8 | day;
+    }
+
+    private static int[] decodeDate(int encodedDate, int[] fillIn) {
+        int year, month, day;
+        if (encodedDate == MIN_ENCODED_START) {
+            year = Integer.MIN_VALUE;
+            month = 1;
+            day = 1;
+        } else {
+            year = (encodedDate & YEAR_MASK) >> 16;
+            month = (encodedDate & MONTH_MASK) >> 8;
+            day = encodedDate & DAY_MASK;
+        }
+
+        if (fillIn != null && fillIn.length >= 3) {
+            fillIn[0] = year;
+            fillIn[1] = month;
+            fillIn[2] = day;
+            return fillIn;
+        }
+
+        int[] result = {year, month, day};
+        return result;
+    }
+
+    /**
+     * Compare an encoded date with another date specified by year/month/day.
+     * @param encoded   An encoded date
+     * @param year      Year of another date
+     * @param month     Month of another date
+     * @param day       Day of another date
+     * @return -1 when encoded date is earlier, 0 when two dates are same,
+     *          and 1 when encoded date is later.
+     */
+    private static int compareEncodedDateWithYMD(int encoded, int year, int month, int day) {
+        if (year < MIN_ENCODED_START_YEAR) {
+            if (encoded == MIN_ENCODED_START) {
+                if (year > Integer.MIN_VALUE || month > 1 || day > 1) {
+                    return -1;
+                }
+                return 0;
+            } else {
+                return 1;
+            }
+        } else if (year > MAX_ENCODED_START_YEAR) {
+            return -1;
+        } else {
+            int tmp = encodeDate(year, month, day);
+            if (encoded < tmp) {
+                return -1;
+            } else if (encoded == tmp) {
+                return 0;
+            } else {
+                return 1;
+            }
+        }
+    }
+}
\ No newline at end of file
index 81d35403ac5c8420363056e5e3e798ca17ddcd96..2c369058655d9f72e02398840e6add88ab73e374 100644 (file)
@@ -17,6 +17,7 @@ import java.util.Date;
 import java.util.Locale;
 import java.util.MissingResourceException;
 
+import com.ibm.icu.impl.CalType;
 import com.ibm.icu.impl.CalendarUtil;
 import com.ibm.icu.impl.ICUCache;
 import com.ibm.icu.impl.ICUData;
@@ -1780,42 +1781,12 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
         return region;
     }
 
-    private enum CalType {
-        GREGORIAN("gregorian"),
-        ISO8601("iso8601"),
-
-        BUDDHIST("buddhist"),
-        CHINESE("chinese"),
-        COPTIC("coptic"),
-        DANGI("dangi"),
-        ETHIOPIC("ethiopic"),
-        ETHIOPIC_AMETE_ALEM("ethiopic-amete-alem"),
-        HEBREW("hebrew"),
-        INDIAN("indian"),
-        ISLAMIC("islamic"),
-        ISLAMIC_CIVIL("islamic-civil"),
-        ISLAMIC_RGSA("islamic-rgsa"),
-        ISLAMIC_TBLA("islamic-tbla"),
-        ISLAMIC_UMALQURA("islamic-umalqura"),
-        JAPANESE("japanese"),
-        PERSIAN("persian"),
-        ROC("roc"),
-
-        UNKNOWN("unknown");
-
-        String id;
-
-        CalType(String id) {
-            this.id = id;
-        }
-    }
-
     private static CalType getCalendarTypeForLocale(ULocale l) {
         String s = CalendarUtil.getCalendarType(l);
         if (s != null) {
             s = s.toLowerCase(Locale.ENGLISH);
             for (CalType type : CalType.values()) {
-                if (s.equals(type.id)) {
+                if (s.equals(type.getId())) {
                     return type;
                 }
             }
@@ -1938,7 +1909,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
         String prefRegion = ULocale.getRegionForSupplementalData(locale, true);
 
         // Read preferred calendar values from supplementalData calendarPreferences
-        ArrayList<String> values = new ArrayList<String>();
+        ArrayList<String> values = new ArrayList<>();
 
         UResourceBundle rb = UResourceBundle.getBundleInstance(
                 ICUData.ICU_BASE_NAME,
@@ -1965,8 +1936,8 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
         }
         // then, add other available clanedars
         for (CalType t : CalType.values()) {
-            if (!values.contains(t.id)) {
-                values.add(t.id);
+            if (!values.contains(t.getId())) {
+                values.add(t.getId());
             }
         }
         return values.toArray(new String[values.size()]);
@@ -2191,7 +2162,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
         CalType type = CalType.GREGORIAN;
         String typeString = getType();
         for (CalType testType : CalType.values()) {
-            if (typeString.equals(testType.id)) {
+            if (typeString.equals(testType.getId())) {
                 type = testType;
                 break;
             }
@@ -2265,7 +2236,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
         CalType type = CalType.GREGORIAN;
         String typeString = getType();
         for (CalType testType : CalType.values()) {
-            if (typeString.equals(testType.id)) {
+            if (typeString.equals(testType.getId())) {
                 type = testType;
                 break;
             }
@@ -3526,7 +3497,7 @@ public abstract class Calendar implements Serializable, Cloneable, Comparable<Ca
 
     // date format pattern cache
     private static final ICUCache<String, PatternData> PATTERN_CACHE =
-            new SimpleCache<String, PatternData>();
+            new SimpleCache<>();
     // final fallback patterns
     private static final String[] DEFAULT_PATTERNS = {
         "HH:mm:ss z",
index 5463407eb55a11c7e745c7a3feaf880640b6336a..7ba86605a5224c619818ce6ddeef1f24a212c439 100644 (file)
@@ -10,6 +10,9 @@ package com.ibm.icu.util;
 import java.util.Date;
 import java.util.Locale;
 
+import com.ibm.icu.impl.CalType;
+import com.ibm.icu.impl.EraRules;
+
 /**
  * <code>JapaneseCalendar</code> is a subclass of <code>GregorianCalendar</code>
  * that numbers years and eras based on the reigns of the Japanese emperors.
@@ -24,19 +27,34 @@ import java.util.Locale;
  * of that year were in the Showa era, e.g. "January 6, 64 Showa", while the rest
  * of the year was in the Heisei era, e.g. "January 7, 1 Heisei".  This class
  * handles this distinction correctly when computing dates.  However, in lenient
- * mode either form of date is acceptable as input. 
+ * mode either form of date is acceptable as input.
  * <p>
  * In modern times, eras have started on January 8, 1868 AD, Gregorian (Meiji),
  * July 30, 1912 (Taisho), December 25, 1926 (Showa), and January 7, 1989 (Heisei).  Constants
  * for these eras, suitable for use in the <code>ERA</code> field, are provided
  * in this class.  Note that the <em>number</em> used for each era is more or
- * less arbitrary.  Currently, the era starting in 1053 AD is era #0; however this
- * may change in the future as we add more historical data.  Use the predefined
- * constants rather than using actual, absolute numbers.
+ * less arbitrary.  Currently, the era starting in 645 AD is era #0; however this
+ * may change in the future.  Use the predefined constants rather than using actual,
+ * absolute numbers.
+ * <p>
+ * Since ICU4J 63, start date of each era is imported from CLDR. CLDR era data
+ * may contain tentative era in near future with placeholder names. By default,
+ * such era data is not enabled. ICU4J users who want to test the behavior of
+ * the future era can enable this by one of following settings (in the priority
+ * order):
+ * <ol>
+ * <li>Java system property <code>ICU_ENABLE_TENTATIVE_ERA=true</code>.</li>
+ * <li>Environment variable <code>ICU_ENABLE_TENTATIVE_ERA=true</code>.</li>
+ * <li>Java system property <code>jdk.calendar.japanese.supplemental.era=xxx</code>.
+ *     (Note: This configuration is used for specifying a new era's start date and
+ *     names in OpenJDK. ICU4J implementation enables the CLDR tentative era when
+ *     this property is defined, but it does not use the start date and names specified
+ *     by the property value.)</li>
+ * </nl>
  * <p>
  * This class should not be subclassed.</p>
  * <p>
- * JapaneseCalendar usually should be instantiated using 
+ * JapaneseCalendar usually should be instantiated using
  * {@link com.ibm.icu.util.Calendar#getInstance(ULocale)} passing in a <code>ULocale</code>
  * with the tag <code>"@calendar=japanese"</code>.</p>
  *
@@ -210,9 +228,44 @@ public class JapaneseCalendar extends GregorianCalendar {
     // Use 1970 as the default value of EXTENDED_YEAR
     private static final int GREGORIAN_EPOCH = 1970;
 
+    private static final EraRules ERA_RULES;
+
+    static {
+        // Although start date of next Japanese era is planned ahead, a name of
+        // new era might not be available. This implementation allows tester to
+        // check a new era without era names by settings below (in priority order).
+        // By default, such tentative era is disabled.
+        //
+        // 1. System property ICU_ENABLE_TENTATIVE_ERA=true or false
+        // 2. Environment variable ICU_ENABLE_TENTATIVE_ERA=true or false
+        // 3. Java system property - jdk.calendar.japanese.supplemental.era for Japanese
+        //
+        // Note: Java system property specifies the start date of new Japanese era,
+        //      but this implementation always uses the date read from ICU data.
+
+        boolean includeTentativeEra = false;
+
+        final String VAR_NAME = "ICU_ENABLE_TENTATIVE_ERA";
+
+        String eraConf = System.getProperty(VAR_NAME);
+        if (eraConf == null) {
+            eraConf = System.getenv(VAR_NAME);
+        }
+
+        if (eraConf != null) {
+            includeTentativeEra = eraConf.equalsIgnoreCase("true");
+        } else {
+            String jdkEraConf = System.getProperty("jdk.calendar.japanese.supplemental.era");
+            includeTentativeEra = jdkEraConf != null;
+        }
+
+        ERA_RULES = EraRules.getInstance(CalType.JAPANESE, includeTentativeEra);
+    }
+
     /**
      * @stable ICU 2.8
      */
+    @Override
     protected int handleGetExtendedYear() {
         // EXTENDED_YEAR in JapaneseCalendar is a Gregorian year
         // The default value of EXTENDED_YEAR is 1970 (Showa 45)
@@ -221,14 +274,14 @@ public class JapaneseCalendar extends GregorianCalendar {
             newerField(EXTENDED_YEAR, ERA) == EXTENDED_YEAR) {
             year = internalGet(EXTENDED_YEAR, GREGORIAN_EPOCH);
         } else {
-            // extended year is a gregorian year, where 1 = 1AD,  0 = 1BC, -1 = 2BC, etc 
-            year = internalGet(YEAR, 1)                       // pin to minimum of year 1 (first year)
-                    + ERAS[internalGet(ERA, CURRENT_ERA) * 3] // add gregorian starting year
-                    - 1;                                      // Subtract one because year starts at 1
+            // extended year is a gregorian year, where 1 = 1AD,  0 = 1BC, -1 = 2BC, etc
+            year = internalGet(YEAR, 1)                                     // pin to minimum of year 1 (first year)
+                    + ERA_RULES.getStartYear(internalGet(ERA, CURRENT_ERA)) // add gregorian starting year
+                    - 1;                                                    // Subtract one because year starts at 1
         }
         return year;
     }
-    
+
     /**
      * Called by handleComputeJulianDay.  Returns the default month (0-based) for the year,
      * taking year and era into account.  Defaults to 0 (JANUARY) for Gregorian.
@@ -238,18 +291,19 @@ public class JapaneseCalendar extends GregorianCalendar {
      * @draft ICU 3.6 (retain)
      * @see #MONTH
      */
-    protected int getDefaultMonthInYear(int extendedYear)
-    {
-      int era = internalGet(ERA, CURRENT_ERA);
-      //computeFields(status); // No need to compute fields here - expect the caller already did so.
-
-      // Find out if we are at the edge of an era
-      if(extendedYear == ERAS[era*3]) {
-        return ERAS[(era*3)+1] // month..
-            -1; // return 0-based month
-      } else {
-        return super.getDefaultMonthInYear(extendedYear);
-      }
+    @Override
+    protected int getDefaultMonthInYear(int extendedYear) {
+        int era = internalGet(ERA, CURRENT_ERA);
+        // computeFields(status); // No need to compute fields here - expect the caller already did so.
+
+        // Find out if we are at the edge of an era
+        int[] eraStart = ERA_RULES.getStartDate(era, null);
+        if (extendedYear == eraStart[0]) {
+            return eraStart[1]          // month..
+                    - 1;                // return 0-based month
+        } else {
+            return super.getDefaultMonthInYear(extendedYear);
+        }
     }
 
     /**
@@ -262,308 +316,33 @@ public class JapaneseCalendar extends GregorianCalendar {
      * @provisional ICU 3.6
      * @see #DAY_OF_MONTH
      */
+    @Override
     protected int getDefaultDayInMonth(int extendedYear, int month) {
-      int era = internalGet(ERA, CURRENT_ERA);
-          
-      if(extendedYear == ERAS[era*3]) { // if it is year 1..
-        if(month == ((ERAS[(era*3)+1])-1)) { // if it is the emperor's first month.. 
-          return ERAS[(era*3)+2]; // return the D_O_M of acession
+        int era = internalGet(ERA, CURRENT_ERA);
+        int[] eraStart = ERA_RULES.getStartDate(era, null);
+
+        if (extendedYear == eraStart[0]) {      // if it is year 1..
+            if (month == (eraStart[1] - 1)) {   // if it is the emperor's first month..
+                return eraStart[2];             // return the D_O_M of accession
+            }
         }
-      }
 
-      return super.getDefaultDayInMonth(extendedYear, month);
+        return super.getDefaultDayInMonth(extendedYear, month);
     }
 
     /**
      * @stable ICU 2.8
      */
+    @Override
     protected void handleComputeFields(int julianDay) {
         super.handleComputeFields(julianDay);
         int year = internalGet(EXTENDED_YEAR);
+        int eraIdx = ERA_RULES.getEraIndex(year, internalGet(MONTH) + 1 /* 1-base */, internalGet(DAY_OF_MONTH));
 
-        int low = 0;
-
-        // Short circuit for recent years.  Most modern computations will
-        // occur in the current era and won't require the binary search.
-        // Note that if the year is == the current era year, then we use
-        // the binary search to handle the month/dom comparison.
-        if (year > ERAS[ERAS.length - 3]) {
-            low = CURRENT_ERA;
-        } else {
-            // Binary search
-            int high = ERAS.length / 3;
-        
-            while (low < high - 1) {
-                int i = (low + high) / 2;
-                int diff = year - ERAS[i*3];
-
-                // If years are the same, then compare the months, and if those
-                // are the same, compare days of month.  In the ERAS array
-                // months are 1-based for easier maintenance.
-                if (diff == 0) {
-                    diff = internalGet(MONTH) - (ERAS[i*3 + 1] - 1);
-                    if (diff == 0) {
-                        diff = internalGet(DAY_OF_MONTH) - ERAS[i*3 + 2];
-                    }
-                }
-                if (diff >= 0) {
-                    low = i;
-                } else {
-                    high = i;
-                }
-            }
-        }
-
-        // Now we've found the last era that starts before this date, so
-        // adjust the year to count from the start of that era.  Note that
-        // all dates before the first era will fall into the first era by
-        // the algorithm.
-        internalSet(ERA, low);
-        internalSet(YEAR, year - ERAS[low*3] + 1);
+        internalSet(ERA, eraIdx);
+        internalSet(YEAR, year - ERA_RULES.getStartYear(eraIdx) + 1);
     }
 
-    private static final int[] ERAS = {
-    //  Gregorian date of each emperor's ascension
-    //  Years are AD, months are 1-based.
-    //  Year  Month Day
-         645,    6, 19,     // Taika
-         650,    2, 15,     // Hakuchi
-         672,    1,  1,     // Hakuho
-         686,    7, 20,     // Shucho
-         701,    3, 21,     // Taiho
-         704,    5, 10,     // Keiun
-         708,    1, 11,     // Wado
-         715,    9,  2,     // Reiki
-         717,   11, 17,     // Yoro
-         724,    2,  4,     // Jinki
-         729,    8,  5,     // Tempyo
-         749,    4, 14,     // Tempyo-kampo
-         749,    7,  2,     // Tempyo-shoho
-         757,    8, 18,     // Tempyo-hoji
-         765,    1,  7,     // Tempho-jingo
-         767,    8, 16,     // Jingo-keiun
-         770,   10,  1,     // Hoki
-         781,    1,  1,     // Ten-o
-         782,    8, 19,     // Enryaku
-         806,    5, 18,     // Daido
-         810,    9, 19,     // Konin
-         824,    1,  5,     // Tencho
-         834,    1,  3,     // Showa
-         848,    6, 13,     // Kajo
-         851,    4, 28,     // Ninju
-         854,   11, 30,     // Saiko
-         857,    2, 21,     // Tennan
-         859,    4, 15,     // Jogan
-         877,    4, 16,     // Genkei
-         885,    2, 21,     // Ninna
-         889,    4, 27,     // Kampyo
-         898,    4, 26,     // Shotai
-         901,    7, 15,     // Engi
-         923,    4, 11,     // Encho
-         931,    4, 26,     // Shohei
-         938,    5, 22,     // Tengyo
-         947,    4, 22,     // Tenryaku
-         957,   10, 27,     // Tentoku
-         961,    2, 16,     // Owa
-         964,    7, 10,     // Koho
-         968,    8, 13,     // Anna
-         970,    3, 25,     // Tenroku
-         973,   12, 20,     // Ten-en
-         976,    7, 13,     // Jogen
-         978,   11, 29,     // Tengen
-         983,    4, 15,     // Eikan
-         985,    4, 27,     // Kanna
-         987,    4,  5,     // Ei-en
-         989,    8,  8,     // Eiso
-         990,   11,  7,     // Shoryaku
-         995,    2, 22,     // Chotoku
-         999,    1, 13,     // Choho
-        1004,    7, 20,     // Kanko
-        1012,   12, 25,     // Chowa
-        1017,    4, 23,     // Kannin
-        1021,    2,  2,     // Jian
-        1024,    7, 13,     // Manju
-        1028,    7, 25,     // Chogen
-        1037,    4, 21,     // Choryaku
-        1040,   11, 10,     // Chokyu
-        1044,   11, 24,     // Kantoku
-        1046,    4, 14,     // Eisho
-        1053,    1, 11,     // Tengi
-        1058,    8, 29,     // Kohei
-        1065,    8,  2,     // Jiryaku
-        1069,    4, 13,     // Enkyu
-        1074,    8, 23,     // Shoho
-        1077,   11, 17,     // Shoryaku
-        1081,    2, 10,     // Eiho
-        1084,    2,  7,     // Otoku
-        1087,    4,  7,     // Kanji
-        1094,   12, 15,     // Kaho
-        1096,   12, 17,     // Eicho
-        1097,   11, 21,     // Shotoku
-        1099,    8, 28,     // Kowa
-        1104,    2, 10,     // Choji
-        1106,    4,  9,     // Kasho
-        1108,    8,  3,     // Tennin
-        1110,    7, 13,     // Ten-ei
-        1113,    7, 13,     // Eikyu
-        1118,    4,  3,     // Gen-ei
-        1120,    4, 10,     // Hoan
-        1124,    4,  3,     // Tenji
-        1126,    1, 22,     // Daiji
-        1131,    1, 29,     // Tensho
-        1132,    8, 11,     // Chosho
-        1135,    4, 27,     // Hoen
-        1141,    7, 10,     // Eiji
-        1142,    4, 28,     // Koji
-        1144,    2, 23,     // Tenyo
-        1145,    7, 22,     // Kyuan
-        1151,    1, 26,     // Ninpei
-        1154,   10, 28,     // Kyuju
-        1156,    4, 27,     // Hogen
-        1159,    4, 20,     // Heiji
-        1160,    1, 10,     // Eiryaku
-        1161,    9,  4,     // Oho
-        1163,    3, 29,     // Chokan
-        1165,    6,  5,     // Eiman
-        1166,    8, 27,     // Nin-an
-        1169,    4,  8,     // Kao
-        1171,    4, 21,     // Shoan
-        1175,    7, 28,     // Angen
-        1177,    8,  4,     // Jisho
-        1181,    7, 14,     // Yowa
-        1182,    5, 27,     // Juei
-        1184,    4, 16,     // Genryuku
-        1185,    8, 14,     // Bunji
-        1190,    4, 11,     // Kenkyu
-        1199,    4, 27,     // Shoji
-        1201,    2, 13,     // Kennin
-        1204,    2, 20,     // Genkyu
-        1206,    4, 27,     // Ken-ei
-        1207,   10, 25,     // Shogen
-        1211,    3,  9,     // Kenryaku
-        1213,   12,  6,     // Kenpo
-        1219,    4, 12,     // Shokyu
-        1222,    4, 13,     // Joo
-        1224,   11, 20,     // Gennin
-        1225,    4, 20,     // Karoku
-        1227,   12, 10,     // Antei
-        1229,    3,  5,     // Kanki
-        1232,    4,  2,     // Joei
-        1233,    4, 15,     // Tempuku
-        1234,   11,  5,     // Bunryaku
-        1235,    9, 19,     // Katei
-        1238,   11, 23,     // Ryakunin
-        1239,    2,  7,     // En-o
-        1240,    7, 16,     // Ninji
-        1243,    2, 26,     // Kangen
-        1247,    2, 28,     // Hoji
-        1249,    3, 18,     // Kencho
-        1256,   10,  5,     // Kogen
-        1257,    3, 14,     // Shoka
-        1259,    3, 26,     // Shogen
-        1260,    4, 13,     // Bun-o
-        1261,    2, 20,     // Kocho
-        1264,    2, 28,     // Bun-ei
-        1275,    4, 25,     // Kenji
-        1278,    2, 29,     // Koan
-        1288,    4, 28,     // Shoo
-        1293,    8, 55,     // Einin
-        1299,    4, 25,     // Shoan
-        1302,   11, 21,     // Kengen
-        1303,    8,  5,     // Kagen
-        1306,   12, 14,     // Tokuji
-        1308,   10,  9,     // Enkei
-        1311,    4, 28,     // Ocho
-        1312,    3, 20,     // Showa
-        1317,    2,  3,     // Bunpo
-        1319,    4, 28,     // Geno
-        1321,    2, 23,     // Genkyo
-        1324,   12,  9,     // Shochu
-        1326,    4, 26,     // Kareki
-        1329,    8, 29,     // Gentoku
-        1331,    8,  9,     // Genko
-        1334,    1, 29,     // Kemmu
-        1336,    2, 29,     // Engen
-        1340,    4, 28,     // Kokoku
-        1346,   12,  8,     // Shohei
-        1370,    7, 24,     // Kentoku
-        1372,    4,  1,     // Bunch\u0169
-        1375,    5, 27,     // Tenju
-        1379,    3, 22,     // Koryaku
-        1381,    2, 10,     // Kowa
-        1384,    4, 28,     // Gench\u0169
-        1384,    2, 27,     // Meitoku
-        1387,    8, 23,     // Kakei
-        1389,    2,  9,     // Koo
-        1390,    3, 26,     // Meitoku
-        1394,    7,  5,     // Oei
-        1428,    4, 27,     // Shocho
-        1429,    9,  5,     // Eikyo
-        1441,    2, 17,     // Kakitsu
-        1444,    2,  5,     // Bun-an
-        1449,    7, 28,     // Hotoku
-        1452,    7, 25,     // Kyotoku
-        1455,    7, 25,     // Kosho
-        1457,    9, 28,     // Choroku
-        1460,   12, 21,     // Kansho
-        1466,    2, 28,     // Bunsho
-        1467,    3,  3,     // Onin
-        1469,    4, 28,     // Bunmei
-        1487,    7, 29,     // Chokyo
-        1489,    8, 21,     // Entoku
-        1492,    7, 19,     // Meio
-        1501,    2, 29,     // Bunki
-        1504,    2, 30,     // Eisho
-        1521,    8, 23,     // Taiei
-        1528,    8, 20,     // Kyoroku
-        1532,    7, 29,     // Tenmon
-        1555,   10, 23,     // Koji
-        1558,    2, 28,     // Eiroku
-        1570,    4, 23,     // Genki
-        1573,    7, 28,     // Tensho
-        1592,   12,  8,     // Bunroku
-        1596,   10, 27,     // Keicho
-        1615,    7, 13,     // Genwa
-        1624,    2, 30,     // Kan-ei
-        1644,   12, 16,     // Shoho
-        1648,    2, 15,     // Keian
-        1652,    9, 18,     // Shoo
-        1655,    4, 13,     // Meiryaku
-        1658,    7, 23,     // Manji
-        1661,    4, 25,     // Kanbun
-        1673,    9, 21,     // Enpo
-        1681,    9, 29,     // Tenwa
-        1684,    2, 21,     // Jokyo
-        1688,    9, 30,     // Genroku
-        1704,    3, 13,     // Hoei
-        1711,    4, 25,     // Shotoku
-        1716,    6, 22,     // Kyoho
-        1736,    4, 28,     // Genbun
-        1741,    2, 27,     // Kanpo
-        1744,    2, 21,     // Enkyo
-        1748,    7, 12,     // Kan-en
-        1751,   10, 27,     // Horyaku
-        1764,    6,  2,     // Meiwa
-        1772,   11, 16,     // An-ei
-        1781,    4,  2,     // Tenmei
-        1789,    1, 25,     // Kansei
-        1801,    2,  5,     // Kyowa
-        1804,    2, 11,     // Bunka
-        1818,    4, 22,     // Bunsei
-        1830,   12, 10,     // Tenpo
-        1844,   12,  2,     // Koka
-        1848,    2, 28,     // Kaei
-        1854,   11, 27,     // Ansei
-        1860,    3, 18,     // Man-en
-        1861,    2, 19,     // Bunkyu
-        1864,    2, 20,     // Genji
-        1865,    4,  7,     // Keio
-        1868,    9,  8,     // Meiji
-        1912,    7, 30,     // Taisho
-        1926,   12, 25,     // Showa
-        1989,    1,  8,     // Heisei
-    };
-
     //-------------------------------------------------------------------------
     // Public constants for some of the recent eras that folks might use...
     //-------------------------------------------------------------------------
@@ -572,31 +351,31 @@ public class JapaneseCalendar extends GregorianCalendar {
     /**
      * @stable ICU 2.8
      */
-    static public final int CURRENT_ERA = (ERAS.length / 3) - 1;
-    
-    /** 
+    static public final int CURRENT_ERA = ERA_RULES.getCurrentEraIndex();
+
+    /**
      * Constant for the era starting on Sept. 8, 1868 AD.
-     * @stable  ICU 2.8 
+     * @stable  ICU 2.8
      */
-    static public final int MEIJI = CURRENT_ERA - 3;
+    static public final int MEIJI = 232;
 
-    /** 
-     * Constant for the era starting on July 30, 1912 AD. 
-     * @stable ICU 2.8 
+    /**
+     * Constant for the era starting on July 30, 1912 AD.
+     * @stable ICU 2.8
      */
-    static public final int TAISHO = CURRENT_ERA - 2;
-    
-    /** 
-     * Constant for the era starting on Dec. 25, 1926 AD. 
-     * @stable ICU 2.8 
+    static public final int TAISHO = 233;
+
+    /**
+     * Constant for the era starting on Dec. 25, 1926 AD.
+     * @stable ICU 2.8
      */
-    static public final int SHOWA = CURRENT_ERA - 1;
+    static public final int SHOWA = 234;
 
-    /** 
-     * Constant for the era starting on Jan. 7, 1989 AD. 
-     * @stable ICU 2.8 
+    /**
+     * Constant for the era starting on Jan. 7, 1989 AD.
+     * @stable ICU 2.8
      */
-    static public final int HEISEI = CURRENT_ERA;
+    static public final int HEISEI = 235;
 
     /**
      * Override GregorianCalendar.  We should really handle YEAR_WOY and
@@ -604,6 +383,7 @@ public class JapaneseCalendar extends GregorianCalendar {
      * not critical.
      * @stable ICU 2.8
      */
+    @Override
     @SuppressWarnings("fallthrough")
     protected int handleGetLimit(int field, int limitType) {
         switch (field) {
@@ -621,7 +401,7 @@ public class JapaneseCalendar extends GregorianCalendar {
             case LEAST_MAXIMUM:
                 return 1;
             case MAXIMUM:
-                return super.handleGetLimit(field, MAXIMUM) - ERAS[CURRENT_ERA*3];
+                return super.handleGetLimit(field, MAXIMUM) - ERA_RULES.getStartYear(CURRENT_ERA);
             }
             //Fall through to the default if not handled above
         }
@@ -634,6 +414,7 @@ public class JapaneseCalendar extends GregorianCalendar {
      * {@inheritDoc}
      * @stable ICU 3.8
      */
+    @Override
     public String getType() {
         return "japanese";
     }
@@ -643,6 +424,7 @@ public class JapaneseCalendar extends GregorianCalendar {
      * @internal
      * @deprecated This API is ICU internal only.
      */
+    @Override
     @Deprecated
     public boolean haveDefaultCentury() {
         return false;
@@ -652,6 +434,7 @@ public class JapaneseCalendar extends GregorianCalendar {
      * {@inheritDoc}
      * @stable ICU 4.0
      */
+    @Override
     public int getActualMaximum(int field) {
         if (field == YEAR) {
             int era = get(Calendar.ERA);
@@ -659,11 +442,12 @@ public class JapaneseCalendar extends GregorianCalendar {
                 // TODO: Investigate what value should be used here - revisit after 4.0.
                 return handleGetLimit(YEAR, MAXIMUM);
             } else {
-                int nextEraYear = ERAS[(era+1)*3];
-                int nextEraMonth = ERAS[(era+1)*3 + 1];
-                int nextEraDate = ERAS[(era+1)*3 + 2];
+                int[] nextEraStart = ERA_RULES.getStartDate(era + 1, null);
+                int nextEraYear = nextEraStart[0];
+                int nextEraMonth = nextEraStart[1]; // 1-base
+                int nextEraDate = nextEraStart[2];
 
-                int maxYear = nextEraYear - ERAS[era*3] + 1; // 1-base
+                int maxYear = nextEraYear - ERA_RULES.getStartYear(era) + 1; // 1-base
                 if (nextEraMonth == 1 && nextEraDate == 1) {
                     // Substract 1, because the next era starts at Jan 1
                     maxYear--;
index 198adf2fc9e59473456dc854e6714c75c54f2c2e..e2be2f06c93b0e839d21efdab7baeb91a3eaf43f 100644 (file)
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:36d0ec0c543d1dccafcc6985a7c18285b255afb98bc2bdb16a867a22600bfddb
-size 12487287
+oid sha256:92dc0a5ca71ac54537a6c7c42c2f80ccbd3298d9ebf69c3d732199230d5100c6
+size 12487439
index afa08eb95e7779da06fe3c8b50508938cd1eb59e..6d6bf299cc0b63da2834b2f89e9a4fe910ce0a4c 100755 (executable)
@@ -1,3 +1,3 @@
 version https://git-lfs.github.com/spec/v1
-oid sha256:469f76e391dced8e9ae4a9543513dddd6d4d2026ad6cbc0ab79d9553da803e6a
+oid sha256:d2308b3498ce1c2b869b60b5a0f7cea6f08aff2fac046ae260e10688c15c60b2
 size 92857
diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/EraRulesTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/calendar/EraRulesTest.java
new file mode 100644 (file)
index 0000000..c2cf6e1
--- /dev/null
@@ -0,0 +1,76 @@
+// © 2018 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html#License
+package com.ibm.icu.dev.test.calendar;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import com.ibm.icu.dev.test.TestFmwk;
+import com.ibm.icu.impl.CalType;
+import com.ibm.icu.impl.EraRules;
+import com.ibm.icu.util.Calendar;
+import com.ibm.icu.util.JapaneseCalendar;
+import com.ibm.icu.util.ULocale;
+
+/**
+ * Tests for EraRules class
+ */
+@RunWith(JUnit4.class)
+public class EraRulesTest extends TestFmwk {
+    @Test
+    public void testAPIs() {
+        for (CalType calType : CalType.values()) {
+            String calId = calType.getId();
+            if (calId.equals("iso8601") || calId.equals("unknown")) {
+                continue;
+            }
+            EraRules rules1 = EraRules.getInstance(calType, false);
+            if (rules1 == null) {
+                errln("Era rules for " + calId + " is not available.");
+            }
+
+            EraRules rules2 = EraRules.getInstance(calType, true);
+            if (rules2 == null) {
+                errln("Era rules for " + calId + " (including tentative eras) is not available.");
+            }
+            int numEras1 = rules1.getNumberOfEras();
+            if (numEras1 <= 0) {
+                errln("Number of era rules for " + calId + " is " + numEras1);
+            }
+            int numEras2 = rules2.getNumberOfEras();
+            if (numEras2 < numEras1) {
+                errln("Number of era including tentative eras is fewer than one without tentative eras in calendar: "
+                        + calId);
+            }
+
+            Calendar cal = Calendar.getInstance(new ULocale("en"));
+            int currentIdx = rules1.getCurrentEraIndex();
+            int currentYear = cal.get(Calendar.YEAR);
+            int idx = rules1.getEraIndex(currentYear, cal.get(Calendar.MONTH) + 1, cal.get(Calendar.DATE));
+            if (idx != currentIdx) {
+                errln("Current era index:" + currentIdx + " is different from era index of now:" + idx
+                        + " in calendar:" + calId);
+            }
+
+            int eraStartYear = rules1.getStartYear(currentIdx);
+            if (currentYear < eraStartYear) {
+                errln("Current era's start year is after the current year in calendar:" + calId);
+            }
+        }
+    }
+
+    @Test
+    public void testJapanese() {
+        EraRules rules = EraRules.getInstance(CalType.JAPANESE, true);
+        // Rules should have an era after Heisei
+        int numRules = rules.getNumberOfEras();
+        if (numRules <= JapaneseCalendar.HEISEI) {
+            errln("Era after Heisei is not available.");
+        }
+        int postHeiseiStartYear = rules.getStartYear(JapaneseCalendar.HEISEI + 1);
+        if (postHeiseiStartYear != 2019) {
+            errln("Era after Heisei should start in 2019, but got " + postHeiseiStartYear);
+        }
+    }
+}