12d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// © 2016 and later: Unicode, Inc. and others.
22d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html#License
37935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/*********************************************************************
4e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer * Copyright (C) 2000-2016, International Business Machines Corporation and
57935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * others. All Rights Reserved.
67935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *********************************************************************
77935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
87935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertpackage com.ibm.icu.dev.test.calendar;
97935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Date;
107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport java.util.Locale;
117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
122d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubertimport org.junit.Test;
132d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert
147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.ChineseDateFormat;
157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.DateFormat;
167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.DateFormatSymbols;
177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.text.SimpleDateFormat;
187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.Calendar;
197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.ChineseCalendar;
207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.GregorianCalendar;
217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.TimeZone;
227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubertimport com.ibm.icu.util.ULocale;
237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert/**
257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Test of ChineseCalendar.
267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert *
277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Leap months in this century:
287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Wed May 23 2001 = 4638-04*-01, Year 18, Cycle 78
297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Sun Mar 21 2004 = 4641-02*-01, Year 21, Cycle 78
307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Thu Aug 24 2006 = 4643-07*-01, Year 23, Cycle 78
317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Tue Jun 23 2009 = 4646-05*-01, Year 26, Cycle 78
327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Mon May 21 2012 = 4649-04*-01, Year 29, Cycle 78
337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Fri Oct 24 2014 = 4651-09*-01, Year 31, Cycle 78
347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Sun Jul 23 2017 = 4654-06*-01, Year 34, Cycle 78
357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Sat May 23 2020 = 4657-04*-01, Year 37, Cycle 78
367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Wed Mar 22 2023 = 4660-02*-01, Year 40, Cycle 78
377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Fri Jul 25 2025 = 4662-06*-01, Year 42, Cycle 78
387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Fri Jun 23 2028 = 4665-05*-01, Year 45, Cycle 78
397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Tue Apr 22 2031 = 4668-03*-01, Year 48, Cycle 78
407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Thu Dec 22 2033 = 4670-11*-01, Year 50, Cycle 78
417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Wed Jul 23 2036 = 4673-06*-01, Year 53, Cycle 78
427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Wed Jun 22 2039 = 4676-05*-01, Year 56, Cycle 78
437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Sat Mar 22 2042 = 4679-02*-01, Year 59, Cycle 78
447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Tue Aug 23 2044 = 4681-07*-01, Year 01, Cycle 79
457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Sun Jun 23 2047 = 4684-05*-01, Year 04, Cycle 79
467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Thu Apr 21 2050 = 4687-03*-01, Year 07, Cycle 79
477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Mon Sep 23 2052 = 4689-08*-01, Year 09, Cycle 79
487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Sat Jul 24 2055 = 4692-06*-01, Year 12, Cycle 79
497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Wed May 22 2058 = 4695-04*-01, Year 15, Cycle 79
507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Wed Apr 20 2061 = 4698-03*-01, Year 18, Cycle 79
517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Fri Aug 24 2063 = 4700-07*-01, Year 20, Cycle 79
527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Wed Jun 23 2066 = 4703-05*-01, Year 23, Cycle 79
537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Tue May 21 2069 = 4706-04*-01, Year 26, Cycle 79
547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Thu Sep 24 2071 = 4708-08*-01, Year 28, Cycle 79
557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Tue Jul 24 2074 = 4711-06*-01, Year 31, Cycle 79
567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Sat May 22 2077 = 4714-04*-01, Year 34, Cycle 79
577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Sat Apr 20 2080 = 4717-03*-01, Year 37, Cycle 79
587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Mon Aug 24 2082 = 4719-07*-01, Year 39, Cycle 79
597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Fri Jun 22 2085 = 4722-05*-01, Year 42, Cycle 79
607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Fri May 21 2088 = 4725-04*-01, Year 45, Cycle 79
617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Sun Sep 24 2090 = 4727-08*-01, Year 47, Cycle 79
627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Thu Jul 23 2093 = 4730-06*-01, Year 50, Cycle 79
637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Tue May 22 2096 = 4733-04*-01, Year 53, Cycle 79
647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert * Sun Mar 22 2099 = 4736-02*-01, Year 56, Cycle 79
657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert */
662d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubertpublic class ChineseTest extends CalendarTestFmwk {
677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Test basic mapping to and from Gregorian.
697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
702d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestMapping() {
727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final int[] DATA = {
747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // (Note: months are 1-based)
757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Gregorian    Chinese
767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1964,  9,  4,   4601,  7,0, 28,
777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1964,  9,  5,   4601,  7,0, 29,
787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1964,  9,  6,   4601,  8,0,  1,
797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1964,  9,  7,   4601,  8,0,  2,
807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1961, 12, 25,   4598, 11,0, 18,
817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1999,  6,  4,   4636,  4,0, 21,
827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1990,  5, 23,   4627,  4,0, 29,
847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1990,  5, 24,   4627,  5,0,  1,
857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1990,  6, 22,   4627,  5,0, 30,
867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1990,  6, 23,   4627,  5,1,  1,
877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1990,  7, 20,   4627,  5,1, 28,
887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1990,  7, 21,   4627,  5,1, 29,
897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1990,  7, 22,   4627,  6,0,  1,
907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ChineseCalendar cal = new ChineseCalendar();
937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StringBuffer buf = new StringBuffer();
947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("Gregorian -> Chinese");
967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //java.util.Calendar grego = java.util.Calendar.getInstance();
977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Calendar grego = Calendar.getInstance();
987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        grego.clear();
997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i<DATA.length; ) {
1007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            grego.set(DATA[i++], DATA[i++]-1, DATA[i++]);
1017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Date date = grego.getTime();
1027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.setTime(date);
1037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int y = cal.get(Calendar.EXTENDED_YEAR);
1047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int m = cal.get(Calendar.MONTH)+1; // 0-based -> 1-based
1057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int L = cal.get(Calendar.IS_LEAP_MONTH);
1067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int d = cal.get(Calendar.DAY_OF_MONTH);
1077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int yE = DATA[i++]; // Expected y, m, isLeapMonth, d
1087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int mE = DATA[i++]; // 1-based
1097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int LE = DATA[i++];
1107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int dE = DATA[i++];
1117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            buf.setLength(0);
1127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            buf.append(date + " -> ");
1137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            buf.append(y + "/" + m + (L==1?"(leap)":"") + "/" + d);
1147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (y == yE && m == mE && L == LE && d == dE) {
1157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln("OK: " + buf.toString());
1167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
1177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + buf.toString() + ", expected " +
1187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      yE + "/" + mE + (LE==1?"(leap)":"") + "/" + dE);
1197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("Chinese -> Gregorian");
1237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i<DATA.length; ) {
1247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            grego.set(DATA[i++], DATA[i++]-1, DATA[i++]);
1257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Date dexp = grego.getTime();
1267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int cyear = DATA[i++];
1277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int cmonth = DATA[i++];
1287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int cisleapmonth = DATA[i++];
1297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int cdayofmonth = DATA[i++];
1307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.clear();
1317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.set(Calendar.EXTENDED_YEAR, cyear);
1327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.set(Calendar.MONTH, cmonth-1);
1337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.set(Calendar.IS_LEAP_MONTH, cisleapmonth);
1347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.set(Calendar.DAY_OF_MONTH, cdayofmonth);
1357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Date date = cal.getTime();
1367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            buf.setLength(0);
1377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            buf.append(cyear + "/" + cmonth +
1387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                       (cisleapmonth==1?"(leap)":"") + "/" + cdayofmonth);
1397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            buf.append(" -> " + date);
1407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (date.equals(dexp)) {
1417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln("OK: " + buf.toString());
1427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
1437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + buf.toString() + ", expected " + dexp);
1447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Make sure no Gregorian dates map to Chinese 1-based day of
1507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * month zero.  This was a problem with some of the astronomical
1517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * new moon determinations.
1527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1532d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
1547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestZeroDOM() {
1557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ChineseCalendar cal = new ChineseCalendar();
1567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        GregorianCalendar greg = new GregorianCalendar(1989, Calendar.SEPTEMBER, 1);
1577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("Start: " + greg.getTime());
1587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i<1000; ++i) {
1597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.setTimeInMillis(greg.getTimeInMillis());
1607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (cal.get(Calendar.DAY_OF_MONTH) == 0) {
1617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + greg.getTime() + " -> " +
1627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      cal.get(Calendar.EXTENDED_YEAR) + "/" +
1637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      cal.get(Calendar.MONTH) +
1647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      (cal.get(Calendar.IS_LEAP_MONTH)==1?"(leap)":"") +
1657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      "/" + cal.get(Calendar.DAY_OF_MONTH));
1667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
1677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            greg.add(Calendar.DAY_OF_YEAR, 1);
1687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
1697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln("End: " + greg.getTime());
1707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Test minimum and maximum functions.
1747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1752d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
1767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestLimits() {
1777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // The number of days and the start date can be adjusted
1787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // arbitrarily to either speed up the test or make it more
1797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // thorough, but try to test at least a full year, preferably a
1807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // full non-leap and a full leap year.
1817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Final parameter is either number of days, if > 0, or test
1837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // duration in seconds, if < 0.
1847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        java.util.Calendar tempcal = java.util.Calendar.getInstance();
1857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        tempcal.clear();
1867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        tempcal.set(1989, Calendar.NOVEMBER, 1);
1877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ChineseCalendar chinese = new ChineseCalendar();
1887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        doLimitsTest(chinese, null, tempcal.getTime());
1897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        doTheoreticalLimitsTest(chinese, true);
1907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
1917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
1937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Run through several standard tests from Dershowitz & Reingold.
1947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
1952d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
1967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestJulianDayMapping() {
1977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
1987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final TestCase[] tests = {
1997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //
2007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // From Dershowitz & Reingold, "Calendrical Calculations".
2017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //
2027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // The months in this table are 1-based rather than 0-based.
2037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //
2047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // * Failing fields->millis
2057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // ** Millis->fields gives 0-based month -1
2067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // These failures were fixed by changing the start search date
2077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // for the winter solstice from Dec 15 to Dec 1.
2087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //
2097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //                  Julian Day   Era  Year Month  Leap   DOM WkDay
2107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(1507231.5,   35,   11,    6, false,   12,  SUN),
2117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(1660037.5,   42,    9,   10, false,   27,  WED),
2127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(1746893.5,   46,    7,    8, false,    4,  WED),
2137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(1770641.5,   47,   12,    8, false,    9,  SUN),
2147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(1892731.5,   52,   46,   11, false,   20,  WED),
2157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(1931579.5,   54,   33,    4, false,    5,  MON),
2167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(1974851.5,   56,   31,   10, false,   15,  SAT),
2177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2091164.5,   61,   50,    3, false,    7,  SUN),
2187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2121509.5,   63,   13,    4, false,   24,  SUN),
2197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2155779.5,   64,   47,    2, false,    9,  FRI),
2207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2174029.5,   65,   37,    2, false,    9,  SAT),
2217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2191584.5,   66,   25,    2, false,   23,  FRI),
2227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2195261.5,   66,   35,    3, false,    9,  SUN), //*
2237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2229274.5,   68,    8,    5, false,    2,  SUN), //*
2247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2245580.5,   68,   53,    1, false,    8,  WED), //**
2257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2266100.5,   69,   49,    3, false,    4,  SAT),
2267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2288542.5,   70,   50,    8, false,    2,  SAT), //*
2277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2290901.5,   70,   57,    1, false,   29,  SAT), //*
2287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2323140.5,   72,   25,    4,  true,   20,  WED), //*
2297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2334848.5,   72,   57,    6, false,    5,  SUN),
2307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2348020.5,   73,   33,    6, false,    6,  FRI),
2317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2366978.5,   74,   25,    5, false,    5,  SUN),
2327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2385648.5,   75,   16,    6, false,   12,  MON),
2337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2392825.5,   75,   36,    2, false,   13,  WED),
2347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2416223.5,   76,   40,    3, false,   22,  SUN),
2357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2425848.5,   77,    6,    7, false,   21,  SUN),
2367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2430266.5,   77,   18,    8, false,    9,  MON),
2377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2430833.5,   77,   20,    3, false,   15,  MON),
2387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2431004.5,   77,   20,    9, false,    9,  THU),
2397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2448698.5,   78,    9,    2, false,   14,  TUE),
2407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2450138.5,   78,   13,    1, false,    7,  SUN),
2417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2465737.5,   78,   55,   10, false,   14,  WED),
2427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2486076.5,   79,   51,    6, false,    7,  SUN),
2437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Additional tests not from D&R
2457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            new ChineseTestCase(2467496.5,   78,   60,    8, false,    2,  FRI), // year 60
2467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
2477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ChineseCalendar cal = new ChineseCalendar();
2497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cal.setLenient(true);
2507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        doTestCases(tests, cal);
2517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Test formatting.
2557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Q: Why is this in Calendar tests instead of Format tests?
2567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Note: This test assumes that Chinese calendar formatted dates can be parsed
2577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * unambiguously to recover the original Date that was formatted. This is not
2587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * currently true since Chinese calendar formatted dates do not include an era.
2597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * To address this will require formatting/parsing of fields from some other
2607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * associated calendar, as per ICU ticket #9043. This test should be timebombed
2617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * until that ticket is addressed.
2627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2632d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
2647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestFormat() {
2657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ChineseCalendar cal = new ChineseCalendar();
2667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        DateFormat fmt = DateFormat.getDateTimeInstance(cal,
2677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                    DateFormat.DEFAULT, DateFormat.DEFAULT);
2687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        java.util.Calendar tempcal = java.util.Calendar.getInstance();
2707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        tempcal.clear();
2717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Date[] DATA = new Date[2];
2737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        tempcal.set(2001, Calendar.MAY, 22);
2747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        DATA[0] = tempcal.getTime();
2757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        tempcal.set(2001, Calendar.MAY, 23);
2767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        DATA[1] = tempcal.getTime();
2777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Wed May 23 2001 = Month 4(leap), Day 1, Year 18, Cycle 78
2787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i<DATA.length; ++i) {
2807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String s = fmt.format(DATA[i]);
2817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            try {
2827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                Date e = fmt.parse(s);
2837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                if (e.equals(DATA[i])) {
2847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    logln("Ok: " + DATA[i] + " -> " + s + " -> " + e);
2857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                } else {
2867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    errln("FAIL: " + DATA[i] + " -> " + s + " -> " + e);
2877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                }
2887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } catch (java.text.ParseException e) {
2897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + s + " -> parse failure at " + e.getErrorOffset());
2907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln(e.toString());
2917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
2927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
2937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
2947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
2957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
2967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Make sure IS_LEAP_MONTH participates in field resolution.
2977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
2982d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
2997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestResolution() {
3007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ChineseCalendar cal = new ChineseCalendar();
3017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        DateFormat fmt = DateFormat.getDateInstance(cal, DateFormat.DEFAULT);
3027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // May 22 2001 = y4638 m4 d30 doy119
3047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // May 23 2001 = y4638 m4* d1 doy120
3057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final int THE_YEAR = 4638;
3077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        final int END = -1;
3087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int[] DATA = {
3107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Format:
3117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // (field, value)+, END, exp.month, exp.isLeapMonth, exp.DOM
3127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Note: exp.month is ONE-BASED
3137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // If we set DAY_OF_YEAR only, that should be used
3157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Calendar.DAY_OF_YEAR, 1,
3167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            END,
3177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            1,0,1, // Expect 1-1
3187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // If we set MONTH only, that should be used
3207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Calendar.IS_LEAP_MONTH, 1,
3217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Calendar.DAY_OF_MONTH, 1,
3227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Calendar.MONTH, 3,
3237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            END,
3247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            4,1,1, // Expect 4*-1
3257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // If we set the DOY last, that should take precedence
3277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Calendar.MONTH, 1, // Should ignore
3287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Calendar.IS_LEAP_MONTH, 1, // Should ignore
3297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Calendar.DAY_OF_MONTH, 1, // Should ignore
3307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Calendar.DAY_OF_YEAR, 121,
3317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            END,
3327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            4,1,2, // Expect 4*-2
3337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // I've disabled this test because it doesn't work this way,
3357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // not even with a GregorianCalendar!  MONTH alone isn't enough
3367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // to supersede DAY_OF_YEAR.  Some other month-related field is
3377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // also required. - Liu 11/28/00
3387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //! // If we set MONTH last, that should take precedence
3397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //! ChineseCalendar.IS_LEAP_MONTH, 1,
3407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //! Calendar.DAY_OF_MONTH, 1,
3417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //! Calendar.DAY_OF_YEAR, 5, // Should ignore
3427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //! Calendar.MONTH, 3,
3437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //! END,
3447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            //! 4,1,1, // Expect 4*-1
3457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // If we set IS_LEAP_MONTH last, that should take precedence
3477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Calendar.MONTH, 3,
3487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Calendar.DAY_OF_MONTH, 1,
3497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Calendar.DAY_OF_YEAR, 5, // Should ignore
3507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Calendar.IS_LEAP_MONTH, 1,
3517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            END,
3527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            4,1,1, // Expect 4*-1
3537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
3547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        StringBuffer buf = new StringBuffer();
3567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i<DATA.length; ) {
3577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.clear();
3587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.set(Calendar.EXTENDED_YEAR, THE_YEAR);
3597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            buf.setLength(0);
3607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            buf.append("EXTENDED_YEAR=" + THE_YEAR);
3617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            while (DATA[i] != END) {
3627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.set(DATA[i++], DATA[i++]);
3637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                buf.append(" " + fieldName(DATA[i-2]) + "=" + DATA[i-1]);
3647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
3657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ++i; // Skip over END mark
3667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int expMonth = DATA[i++]-1;
3677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int expIsLeapMonth = DATA[i++];
3687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int expDOM = DATA[i++];
3697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int month = cal.get(Calendar.MONTH);
3707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int isLeapMonth = cal.get(Calendar.IS_LEAP_MONTH);
3717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int dom = cal.get(Calendar.DAY_OF_MONTH);
3727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (expMonth == month && expIsLeapMonth == isLeapMonth &&
3737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                dom == expDOM) {
3747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln("OK: " + buf + " => " + fmt.format(cal.getTime()));
3757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
3767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                String s = fmt.format(cal.getTime());
3777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.clear();
3787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.set(Calendar.EXTENDED_YEAR, THE_YEAR);
3797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.set(Calendar.MONTH, expMonth);
3807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.set(Calendar.IS_LEAP_MONTH, expIsLeapMonth);
3817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.set(Calendar.DAY_OF_MONTH, expDOM);
3827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + buf + " => " + s +
3837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      "=" + (month+1) + "," + isLeapMonth + "," + dom +
3847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      ", expected " + fmt.format(cal.getTime()) +
3857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      "=" + (expMonth+1) + "," + expIsLeapMonth + "," + expDOM);
3867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
3877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
3887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
3897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
3907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
3917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Test the behavior of fields that are out of range.
3927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
3932d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
3947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestOutOfRange() {
3957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int[] DATA = new int[] {
3967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Input       Output
3977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            4638, 13,  1,   4639,  1,  1,
3987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            4638, 18,  1,   4639,  6,  1,
3997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            4639,  0,  1,   4638, 12,  1,
4007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            4639, -6,  1,   4638,  6,  1,
4017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            4638,  1, 32,   4638,  2,  2, // 1-4638 has 30 days
4027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            4638,  2, -1,   4638,  1, 29,
4037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
4047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ChineseCalendar cal = new ChineseCalendar();
4057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i=0; i<DATA.length; ) {
4067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int y1 = DATA[i++];
4077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int m1 = DATA[i++]-1;
4087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int d1 = DATA[i++];
4097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int y2 = DATA[i++];
4107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int m2 = DATA[i++]-1;
4117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int d2 = DATA[i++];
4127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.clear();
4137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.set(Calendar.EXTENDED_YEAR, y1);
4147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.set(MONTH, m1);
4157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.set(DATE, d1);
4167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int y = cal.get(Calendar.EXTENDED_YEAR);
4177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int m = cal.get(MONTH);
4187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int d = cal.get(DATE);
4197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (y!=y2 || m!=m2 || d!=d2) {
4207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + y1 + "/" + (m1+1) + "/" + d1 + " resolves to " +
4217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      y + "/" + (m+1) + "/" + d + ", expected " +
4227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      y2 + "/" + (m2+1) + "/" + d2);
4237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else  if (isVerbose()) {
4247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln("OK: " + y1 + "/" + (m1+1) + "/" + d1 + " resolves to " +
4257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      y + "/" + (m+1) + "/" + d);
4267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
4277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
4287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
4317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Test the behavior of ChineseCalendar.add().  The only real
4327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * nastiness with roll is the MONTH field around leap months.
4337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4342d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
4357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestAdd() {
4367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int[][] tests = new int[][] {
4377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // MONTHS ARE 1-BASED HERE
4387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // input               add           output
4397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // year  mon    day    field amount  year  mon    day
4407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4642,   3,0,  15,   MONTH,   3,   4642,   6,0,  15 }, // normal
4417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4639,  12,0,  15,   MONTH,   1,   4640,   1,0,  15 }, // across year
4427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4640,   1,0,  15,   MONTH,  -1,   4639,  12,0,  15 }, // across year
4437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   3,0,  15,   MONTH,   3,   4638,   5,0,  15 }, // 4=leap
4447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   3,0,  15,   MONTH,   2,   4638,   4,1,  15 }, // 4=leap
4457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   4,0,  15,   MONTH,   1,   4638,   4,1,  15 }, // 4=leap
4467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   4,1,  15,   MONTH,   1,   4638,   5,0,  15 }, // 4=leap
4477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   4,0,  30,   MONTH,   1,   4638,   4,1,  29 }, // dom should pin
4487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   4,0,  30,   MONTH,   2,   4638,   5,0,  30 }, // no dom pin
4497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   4,0,  30,   MONTH,   3,   4638,   6,0,  29 }, // dom should pin
4507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
4517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ChineseCalendar cal = new ChineseCalendar();
4537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        doRollAdd(ADD, cal, tests);
4547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
4577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Test the behavior of ChineseCalendar.roll().  The only real
4587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * nastiness with roll is the MONTH field around leap months.
4597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
4602d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
4617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestRoll() {
4627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        int[][] tests = new int[][] {
4637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // MONTHS ARE 1-BASED HERE
4647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // input               add           output
4657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // year  mon    day    field amount  year  mon    day
4667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4642,   3,0,  15,   MONTH,   3,   4642,   6,0,  15 }, // normal
4677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4642,   3,0,  15,   MONTH,  11,   4642,   2,0,  15 }, // normal
4687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4639,  12,0,  15,   MONTH,   1,   4639,   1,0,  15 }, // across year
4697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4640,   1,0,  15,   MONTH,  -1,   4640,  12,0,  15 }, // across year
4707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   3,0,  15,   MONTH,   3,   4638,   5,0,  15 }, // 4=leap
4717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   3,0,  15,   MONTH,  16,   4638,   5,0,  15 }, // 4=leap
4727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   3,0,  15,   MONTH,   2,   4638,   4,1,  15 }, // 4=leap
4737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   3,0,  15,   MONTH,  28,   4638,   4,1,  15 }, // 4=leap
4747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   4,0,  15,   MONTH,   1,   4638,   4,1,  15 }, // 4=leap
4757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   4,0,  15,   MONTH, -12,   4638,   4,1,  15 }, // 4=leap
4767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   4,1,  15,   MONTH,   1,   4638,   5,0,  15 }, // 4=leap
4777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   4,1,  15,   MONTH, -25,   4638,   5,0,  15 }, // 4=leap
4787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   4,0,  30,   MONTH,   1,   4638,   4,1,  29 }, // dom should pin
4797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   4,0,  30,   MONTH,  14,   4638,   4,1,  29 }, // dom should pin
4807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   4,0,  30,   MONTH,  15,   4638,   5,0,  30 }, // no dom pin
4817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            {  4638,   4,0,  30,   MONTH, -10,   4638,   6,0,  29 }, // dom should pin
4827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        };
4837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ChineseCalendar cal = new ChineseCalendar();
4857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        doRollAdd(ROLL, cal, tests);
4867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
4877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    void doRollAdd(boolean roll, ChineseCalendar cal, int[][] tests) {
4897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String name = roll ? "rolling" : "adding";
4907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        for (int i = 0; i < tests.length; i++) {
4927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            int[] test = tests[i];
4937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
4947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            cal.clear();
4957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.set(Calendar.EXTENDED_YEAR, test[0]);
4967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.set(Calendar.MONTH, test[1]-1);
4977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.set(Calendar.IS_LEAP_MONTH, test[2]);
4987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.set(Calendar.DAY_OF_MONTH, test[3]);
4997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (roll) {
5007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.roll(test[4], test[5]);
5017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else {
5027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.add(test[4], test[5]);
5037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (cal.get(Calendar.EXTENDED_YEAR) != test[6] ||
5057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.get(MONTH) != (test[7]-1) ||
5067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.get(Calendar.IS_LEAP_MONTH) != test[8] ||
5077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                cal.get(DATE) != test[9]) {
5087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("Fail: " + name + " " +
5097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      ymdToString(test[0], test[1]-1, test[2], test[3])
5107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + " " + fieldName(test[4]) + " by " + test[5]
5117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + ": expected " +
5127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      ymdToString(test[6], test[7]-1, test[8], test[9])
5137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      + ", got " + ymdToString(cal));
5147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            } else if (isVerbose()) {
5157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                logln("OK: " + name + " " +
5167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                      ymdToString(test[0], test[1]-1, test[2], test[3])
5177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    + " " + fieldName(test[4]) + " by " + test[5]
5187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    + ": got " + ymdToString(cal));
5197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    /**
5247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * Convert year,month,day values to the form "year/month/day".
5257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     * On input the month value is zero-based, but in the result string it is one-based.
5267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert     */
5277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    static public String ymdToString(int year, int month, int isLeapMonth, int day) {
5287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        return "" + year + "/" + (month+1) +
5297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ((isLeapMonth!=0)?"(leap)":"") +
5307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            "/" + day;
5317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
5327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//    public void TestFindLeapMonths() {
5347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        ChineseCalendar cal = new ChineseCalendar();
5357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        cal.setTime(new Date(2000-1900, Calendar.JANUARY, 1));
5367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        long end = new Date(2100-1900, Calendar.JANUARY, 1).getTime();
5377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        ChineseDateFormat fmt = (ChineseDateFormat) DateFormat.getInstance(cal);
5387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        fmt.applyPattern("u-MMl-dd, 'Year' y, 'Cycle' G");
5397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        while (cal.getTimeInMillis() < end) {
5407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//            if (cal.get(ChineseCalendar.IS_LEAP_MONTH) != 0) {
5417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//                cal.set(Calendar.DAY_OF_MONTH, 1);
5427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//                logln(cal.getTime() + " = " + fmt.format(cal.getTime()));
5437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//                cal.set(Calendar.DAY_OF_MONTH, 29);
5447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//            }
5457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//            cal.add(Calendar.DAY_OF_YEAR, 25);
5467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        }
5477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//    }
5487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5492d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
5507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestCoverage() {
5517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Coverage for constructors
5527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
5537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // new ChineseCalendar(Date)
5547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ChineseCalendar cal = new ChineseCalendar(new Date());
5557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(cal == null){
5567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("could not create ChineseCalendar with Date");
5577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
5617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // new ChineseCalendar(int year, int month, int isLeapMonth, int date)
5627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ChineseCalendar cal = new ChineseCalendar(23, Calendar.JULY, 1, 2);
5637935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(cal == null){
5647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("could not create ChineseCalendar with year,month,isLeapMonth,date");
5657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Make sure the given values are properly set
5677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (cal.get(Calendar.YEAR) != 23 || cal.get(Calendar.MONTH) != Calendar.JULY
5687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    || cal.get(Calendar.IS_LEAP_MONTH) != 1 || cal.get(Calendar.DATE) != 2
5697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    || cal.get(Calendar.MILLISECONDS_IN_DAY) != 0) {
5707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("ChineseCalendar was initialized incorrectly with year,month,isLeapMonth,date");
5717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
5757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // new ChineseCalendar(int year, int month, int isLeapMonth, int date, int hour, int minute, int second)
5767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ChineseCalendar cal = new ChineseCalendar(23, Calendar.JULY, 1, 2, 12, 34, 56);
5777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(cal == null){
5787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("could not create ChineseCalendar with year,month,isLeapMonth,date,hour,minute,second");
5797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // Make sure the given values are properly set
5817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if (cal.get(Calendar.YEAR) != 23 || cal.get(Calendar.MONTH) != Calendar.JULY
5827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    || cal.get(Calendar.IS_LEAP_MONTH) != 1 || cal.get(Calendar.DATE) != 2
5837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    || cal.get(Calendar.HOUR_OF_DAY) != 12 || cal.get(Calendar.MINUTE) != 34
5847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                    || cal.get(Calendar.SECOND) != 56 || cal.get(Calendar.MILLISECOND) != 0) {
5857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("ChineseCalendar was initialized incorrectly with year,month,isLeapMonth,date,hour,minute,second");
5867935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
5907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // new ChineseCalendar(Locale)
5917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ChineseCalendar cal = new ChineseCalendar(Locale.getDefault());
5927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(cal == null){
5937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("could not create ChineseCalendar with Locale");
5947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
5957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
5967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
5977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
5987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // new ChineseCalendar(ULocale)
5997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ChineseCalendar cal = new ChineseCalendar(ULocale.getDefault());
6007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(cal == null){
6017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("could not create ChineseCalendar with ULocale");
6027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
6077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // new ChineseCalendar(TimeZone)
6087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ChineseCalendar cal = new ChineseCalendar(TimeZone.getDefault());
6097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(cal == null){
6107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("could not create ChineseCalendar with TimeZone");
6117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
6157935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // new ChineseCalendar(TimeZone, Locale)
6167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ChineseCalendar cal = new ChineseCalendar(TimeZone.getDefault(), Locale.getDefault());
6177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(cal == null){
6187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("could not create ChineseCalendar with TimeZone,Locale");
6197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
6237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            // new ChineseCalendar(TimeZone, ULocale)
6247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            ChineseCalendar cal = new ChineseCalendar(TimeZone.getDefault(), ULocale.getDefault());
6257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            if(cal == null){
6267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                errln("could not create ChineseCalendar with TimeZone,ULocale");
6277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            }
6287935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6297935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6307935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // Note: ICU 50 or later versions, DateFormat.getInstance(ChineseCalendar) no longer
6317935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // returns an instance of ChineseDateFormat. Chinese calendar formatting support was
6327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // changed and integrated into SimpleDateFormat since ICU 49. Also, ChineseDateFormat
6337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // specific pattern letter "l" is no longer used by the new implementation.
6347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        ChineseCalendar cal = new ChineseCalendar();
6367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        DateFormat format = DateFormat.getInstance(cal);
6377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        if(!(format instanceof ChineseDateFormat)){
6387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//            errln("DateFormat.getInstance("+cal+") did not return a ChineseDateFormat");
6397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        }
6407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        ChineseDateFormat fmt = (ChineseDateFormat)format;
6417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        fmt.applyPattern("llyyll");
6427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        Date time = getDate(2100, Calendar.JANUARY, 1);
6437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        String str = fmt.format(time);
6447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        try {
6457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//            Date e = fmt.parse(str);
6467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//            logln("chinese calendar time: " + time + " result: " + str + " --> " + e);
6477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        } catch (java.text.ParseException ex) {
6487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//            logln(ex.getMessage()); // chinese calendar can't parse this, no error for now
6497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert//        }
6507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6517935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        //new ChineseCalendar(TimeZone,ULocale)
6527935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ChineseCalendar ccal2 = new ChineseCalendar(TimeZone.getDefault(),
6537935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                                                   ULocale.CHINA);
6547935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(ccal2==null){
6557935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("could not create ChineseCalendar with TimeZone ULocale");
6567935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        } else {
6577935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            DateFormat fmt2 = DateFormat.getDateInstance(ccal2, DateFormat.DEFAULT, ULocale.CHINA);
6587935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            Date time2 = getDate(2001, Calendar.MAY, 23);
6597935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            String str2 = fmt2.format(time2);
6607935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            logln("Chinese calendar time: " + time2 + " result: " + str2);
6617935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6627935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6632d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
6647935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestScratch(){
6657935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String[] strMonths = {"Januari", "Pebruari", "Maret", "April", "Mei", "Juni",
6667935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                "Juli", "Agustus", "September", "Oktober", "Nopember", "Desember"};
6677935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String[] strShortMonths = {"Jan", "Peb", "Mar", "Apr", "Mei", "Jun",
6687935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert                     "Jul", "Agt", "Sep", "Okt", "Nop", "Des"};
6697935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        String[] strWeeks = {"", "Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"};
6707935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        DateFormatSymbols dfsDate = new DateFormatSymbols(new Locale("id", "ID"));
6717935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        dfsDate.setMonths(strMonths);
6727935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        dfsDate.setShortMonths(strShortMonths);
6737935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        dfsDate.setWeekdays(strWeeks);
6747935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ULocale uloInd = dfsDate.getLocale(ULocale.ACTUAL_LOCALE);
6757935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(uloInd==null){
6767935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("did not get the expected ULocale");
6777935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6787935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln(uloInd.toString());
6797935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Locale locInd = uloInd.toLocale();
6807935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if(locInd==null){
6817935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("did not get the expected result");
6827935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
6837935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        logln(locInd.toString());
6847935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
6857935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6862d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
6877935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void TestInitWithCurrentTime() {
6887935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // jb4555
6897935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // if the chinese calendar current millis isn't called, the default year is wrong.
6907935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // this test is assuming the 'year' is the current cycle
6917935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // so when we cross a cycle boundary, the target will need to change
6927935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // that shouldn't be for awhile yet...
6937935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
6947935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ChineseCalendar cc = new ChineseCalendar();
6957935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cc.set(Calendar.YEAR, 22);
6967935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cc.set(Calendar.MONTH, 0);
6977935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // need to set leap month flag off, otherwise, the test case always fails when
6987935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert         // current time is in a leap month
6997935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cc.set(Calendar.IS_LEAP_MONTH, 0);
7007935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cc.set(Calendar.DATE, 19);
7017935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cc.set(Calendar.HOUR_OF_DAY, 0);
7027935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cc.set(Calendar.MINUTE, 0);
7037935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cc.set(Calendar.SECOND, 0);
7047935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cc.set(Calendar.MILLISECOND, 0);
7057935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7067935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        cc.add(Calendar.DATE, 1);
7077935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7087935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Calendar cal = new GregorianCalendar(2005, Calendar.FEBRUARY, 28);
7097935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Date target = cal.getTime();
7107935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Date result = cc.getTime();
7117935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7127935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        assertEquals("chinese and gregorian date should match", target, result);
7137935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7147935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7152d2bb24f747c65578da13d5b13b82f0669690461Fredrik Roubert    @Test
7167935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    public void Test6510()
7177935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    {
7187935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        Calendar gregorianCalendar;
7197935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ChineseCalendar chineseCalendar, chineseCalendar2;
7207935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        ChineseDateFormat dateFormat;
7217935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        SimpleDateFormat simpleDateFormat;
7227935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7237935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        simpleDateFormat = new com.ibm.icu.text.SimpleDateFormat("MM/dd/yyyy G 'at' HH:mm:ss vvvv", Locale.US);
7247935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        dateFormat = new com.ibm.icu.text.ChineseDateFormat("MM/dd/yyyy(G) HH:mm:ss", Locale.CHINA);
7257935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7267935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // lunar to gregorian
7277935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        chineseCalendar = new ChineseCalendar(77, 26, Calendar.JANUARY, 0, 6, 0, 0, 0);
728e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer        // coverage
729e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer        assertEquals("equivalent ChineseCalendar() constructors", chineseCalendar,
730e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer                new ChineseCalendar(77, 26, Calendar.JANUARY, 0, 6));
731e7a7efded856b8959849879938d1cb2e8ccab318Markus Scherer
7327935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        gregorianCalendar = Calendar.getInstance(Locale.US);
7337935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        gregorianCalendar.setTime(chineseCalendar.getTime());
7347935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7357935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // gregorian to lunar
7367935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        chineseCalendar2 = new ChineseCalendar();
7377935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        chineseCalendar2.setTimeInMillis(gregorianCalendar.getTimeInMillis());
7387935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert
7397935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        // validate roundtrip
7407935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        if (chineseCalendar.getTimeInMillis() != chineseCalendar2.getTimeInMillis())
7417935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        {
7427935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("time1: " + chineseCalendar.getTimeInMillis());
7437935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("time2: " + chineseCalendar2.getTimeInMillis());
7447935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("Lunar [MM/dd/y(G) HH:mm:ss] " + dateFormat.format(chineseCalendar));
7457935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("**PROBLEM Grego [MM/dd/y(G) HH:mm:ss] " + simpleDateFormat.format(gregorianCalendar));
7467935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("Grego [MM/dd/y(G) HH:mm:ss] " + simpleDateFormat.format(gregorianCalendar));
7477935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert            errln("Lunar [MM/dd/y(G) HH:mm:ss] " + dateFormat.format(chineseCalendar2));
7487935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert        }
7497935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert    }
7507935b1839a081ed19ae0d33029ad3c09632a2caaFredrik Roubert}
751