/*********************************************************************
 * Copyright (C) 2000-2013, International Business Machines Corporation and
 * others. All Rights Reserved.
 *********************************************************************
 */
package com.ibm.icu.dev.test.calendar;
import java.util.Date;
import java.util.Locale;

import com.ibm.icu.text.ChineseDateFormat;
import com.ibm.icu.text.DateFormat;
import com.ibm.icu.text.DateFormatSymbols;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.ChineseCalendar;
import com.ibm.icu.util.GregorianCalendar;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;

/**
 * Test of ChineseCalendar.
 *
 * Leap months in this century:
 * Wed May 23 2001 = 4638-04*-01, Year 18, Cycle 78
 * Sun Mar 21 2004 = 4641-02*-01, Year 21, Cycle 78
 * Thu Aug 24 2006 = 4643-07*-01, Year 23, Cycle 78
 * Tue Jun 23 2009 = 4646-05*-01, Year 26, Cycle 78
 * Mon May 21 2012 = 4649-04*-01, Year 29, Cycle 78
 * Fri Oct 24 2014 = 4651-09*-01, Year 31, Cycle 78
 * Sun Jul 23 2017 = 4654-06*-01, Year 34, Cycle 78
 * Sat May 23 2020 = 4657-04*-01, Year 37, Cycle 78
 * Wed Mar 22 2023 = 4660-02*-01, Year 40, Cycle 78
 * Fri Jul 25 2025 = 4662-06*-01, Year 42, Cycle 78
 * Fri Jun 23 2028 = 4665-05*-01, Year 45, Cycle 78
 * Tue Apr 22 2031 = 4668-03*-01, Year 48, Cycle 78
 * Thu Dec 22 2033 = 4670-11*-01, Year 50, Cycle 78
 * Wed Jul 23 2036 = 4673-06*-01, Year 53, Cycle 78
 * Wed Jun 22 2039 = 4676-05*-01, Year 56, Cycle 78
 * Sat Mar 22 2042 = 4679-02*-01, Year 59, Cycle 78
 * Tue Aug 23 2044 = 4681-07*-01, Year 01, Cycle 79
 * Sun Jun 23 2047 = 4684-05*-01, Year 04, Cycle 79
 * Thu Apr 21 2050 = 4687-03*-01, Year 07, Cycle 79
 * Mon Sep 23 2052 = 4689-08*-01, Year 09, Cycle 79
 * Sat Jul 24 2055 = 4692-06*-01, Year 12, Cycle 79
 * Wed May 22 2058 = 4695-04*-01, Year 15, Cycle 79
 * Wed Apr 20 2061 = 4698-03*-01, Year 18, Cycle 79
 * Fri Aug 24 2063 = 4700-07*-01, Year 20, Cycle 79
 * Wed Jun 23 2066 = 4703-05*-01, Year 23, Cycle 79
 * Tue May 21 2069 = 4706-04*-01, Year 26, Cycle 79
 * Thu Sep 24 2071 = 4708-08*-01, Year 28, Cycle 79
 * Tue Jul 24 2074 = 4711-06*-01, Year 31, Cycle 79
 * Sat May 22 2077 = 4714-04*-01, Year 34, Cycle 79
 * Sat Apr 20 2080 = 4717-03*-01, Year 37, Cycle 79
 * Mon Aug 24 2082 = 4719-07*-01, Year 39, Cycle 79
 * Fri Jun 22 2085 = 4722-05*-01, Year 42, Cycle 79
 * Fri May 21 2088 = 4725-04*-01, Year 45, Cycle 79
 * Sun Sep 24 2090 = 4727-08*-01, Year 47, Cycle 79
 * Thu Jul 23 2093 = 4730-06*-01, Year 50, Cycle 79
 * Tue May 22 2096 = 4733-04*-01, Year 53, Cycle 79
 * Sun Mar 22 2099 = 4736-02*-01, Year 56, Cycle 79
 */
public class ChineseTest extends CalendarTest {

    public static void main(String args[]) throws Exception {
        new ChineseTest().run(args);
    }

    /**
     * Test basic mapping to and from Gregorian.
     */
    public void TestMapping() {

        final int[] DATA = {
            // (Note: months are 1-based)
            // Gregorian    Chinese
            1964,  9,  4,   4601,  7,0, 28,
            1964,  9,  5,   4601,  7,0, 29,
            1964,  9,  6,   4601,  8,0,  1,
            1964,  9,  7,   4601,  8,0,  2,
            1961, 12, 25,   4598, 11,0, 18,
            1999,  6,  4,   4636,  4,0, 21,
            
            1990,  5, 23,   4627,  4,0, 29,
            1990,  5, 24,   4627,  5,0,  1,
            1990,  6, 22,   4627,  5,0, 30,
            1990,  6, 23,   4627,  5,1,  1,
            1990,  7, 20,   4627,  5,1, 28,
            1990,  7, 21,   4627,  5,1, 29,
            1990,  7, 22,   4627,  6,0,  1,
        };

        ChineseCalendar cal = new ChineseCalendar();
        StringBuffer buf = new StringBuffer();

        logln("Gregorian -> Chinese");
        //java.util.Calendar grego = java.util.Calendar.getInstance();
        Calendar grego = Calendar.getInstance();
        grego.clear();
        for (int i=0; i<DATA.length; ) {
            grego.set(DATA[i++], DATA[i++]-1, DATA[i++]);
            Date date = grego.getTime();
            cal.setTime(date);
            int y = cal.get(Calendar.EXTENDED_YEAR);
            int m = cal.get(Calendar.MONTH)+1; // 0-based -> 1-based
            int L = cal.get(Calendar.IS_LEAP_MONTH);
            int d = cal.get(Calendar.DAY_OF_MONTH);
            int yE = DATA[i++]; // Expected y, m, isLeapMonth, d
            int mE = DATA[i++]; // 1-based
            int LE = DATA[i++];
            int dE = DATA[i++];
            buf.setLength(0);
            buf.append(date + " -> ");
            buf.append(y + "/" + m + (L==1?"(leap)":"") + "/" + d);
            if (y == yE && m == mE && L == LE && d == dE) {
                logln("OK: " + buf.toString());
            } else {
                errln("Fail: " + buf.toString() + ", expected " +
                      yE + "/" + mE + (LE==1?"(leap)":"") + "/" + dE);
            }
        }

        logln("Chinese -> Gregorian");
        for (int i=0; i<DATA.length; ) {
            grego.set(DATA[i++], DATA[i++]-1, DATA[i++]);
            Date dexp = grego.getTime();
            int cyear = DATA[i++];
            int cmonth = DATA[i++];
            int cisleapmonth = DATA[i++];
            int cdayofmonth = DATA[i++];
            cal.clear();
            cal.set(Calendar.EXTENDED_YEAR, cyear);
            cal.set(Calendar.MONTH, cmonth-1);
            cal.set(Calendar.IS_LEAP_MONTH, cisleapmonth);
            cal.set(Calendar.DAY_OF_MONTH, cdayofmonth);
            Date date = cal.getTime();
            buf.setLength(0);
            buf.append(cyear + "/" + cmonth +
                       (cisleapmonth==1?"(leap)":"") + "/" + cdayofmonth);
            buf.append(" -> " + date);
            if (date.equals(dexp)) {
                logln("OK: " + buf.toString());
            } else {
                errln("Fail: " + buf.toString() + ", expected " + dexp);
            }
        }
    }

    /**
     * Make sure no Gregorian dates map to Chinese 1-based day of
     * month zero.  This was a problem with some of the astronomical
     * new moon determinations.
     */
    public void TestZeroDOM() {
        ChineseCalendar cal = new ChineseCalendar();
        GregorianCalendar greg = new GregorianCalendar(1989, Calendar.SEPTEMBER, 1);
        logln("Start: " + greg.getTime());
        for (int i=0; i<1000; ++i) {
            cal.setTimeInMillis(greg.getTimeInMillis());
            if (cal.get(Calendar.DAY_OF_MONTH) == 0) {
                errln("Fail: " + greg.getTime() + " -> " +
                      cal.get(Calendar.EXTENDED_YEAR) + "/" +
                      cal.get(Calendar.MONTH) +
                      (cal.get(Calendar.IS_LEAP_MONTH)==1?"(leap)":"") +
                      "/" + cal.get(Calendar.DAY_OF_MONTH));
            }
            greg.add(Calendar.DAY_OF_YEAR, 1);
        }
        logln("End: " + greg.getTime());
    }

    /**
     * Test minimum and maximum functions.
     */
    public void TestLimits() {
        // The number of days and the start date can be adjusted
        // arbitrarily to either speed up the test or make it more
        // thorough, but try to test at least a full year, preferably a
        // full non-leap and a full leap year.

        // Final parameter is either number of days, if > 0, or test
        // duration in seconds, if < 0.
        java.util.Calendar tempcal = java.util.Calendar.getInstance();
        tempcal.clear();
        tempcal.set(1989, Calendar.NOVEMBER, 1);
        ChineseCalendar chinese = new ChineseCalendar();
        doLimitsTest(chinese, null, tempcal.getTime());
        doTheoreticalLimitsTest(chinese, true);
    }

    /**
     * Run through several standard tests from Dershowitz & Reingold.
     */
    public void TestJulianDayMapping() {

        final TestCase[] tests = {
            //
            // From Dershowitz & Reingold, "Calendrical Calculations".
            //
            // The months in this table are 1-based rather than 0-based.
            //
            // * Failing fields->millis
            // ** Millis->fields gives 0-based month -1
            // These failures were fixed by changing the start search date
            // for the winter solstice from Dec 15 to Dec 1.
            // 
            //                  Julian Day   Era  Year Month  Leap   DOM WkDay
            new ChineseTestCase(1507231.5,   35,   11,    6, false,   12,  SUN),
            new ChineseTestCase(1660037.5,   42,    9,   10, false,   27,  WED),
            new ChineseTestCase(1746893.5,   46,    7,    8, false,    4,  WED),
            new ChineseTestCase(1770641.5,   47,   12,    8, false,    9,  SUN),
            new ChineseTestCase(1892731.5,   52,   46,   11, false,   20,  WED),
            new ChineseTestCase(1931579.5,   54,   33,    4, false,    5,  MON),
            new ChineseTestCase(1974851.5,   56,   31,   10, false,   15,  SAT),
            new ChineseTestCase(2091164.5,   61,   50,    3, false,    7,  SUN),
            new ChineseTestCase(2121509.5,   63,   13,    4, false,   24,  SUN),
            new ChineseTestCase(2155779.5,   64,   47,    2, false,    9,  FRI),
            new ChineseTestCase(2174029.5,   65,   37,    2, false,    9,  SAT),
            new ChineseTestCase(2191584.5,   66,   25,    2, false,   23,  FRI),
            new ChineseTestCase(2195261.5,   66,   35,    3, false,    9,  SUN), //*
            new ChineseTestCase(2229274.5,   68,    8,    5, false,    2,  SUN), //*
            new ChineseTestCase(2245580.5,   68,   53,    1, false,    8,  WED), //**
            new ChineseTestCase(2266100.5,   69,   49,    3, false,    4,  SAT), 
            new ChineseTestCase(2288542.5,   70,   50,    8, false,    2,  SAT), //*
            new ChineseTestCase(2290901.5,   70,   57,    1, false,   29,  SAT), //*
            new ChineseTestCase(2323140.5,   72,   25,    4,  true,   20,  WED), //*
            new ChineseTestCase(2334848.5,   72,   57,    6, false,    5,  SUN),
            new ChineseTestCase(2348020.5,   73,   33,    6, false,    6,  FRI),
            new ChineseTestCase(2366978.5,   74,   25,    5, false,    5,  SUN),
            new ChineseTestCase(2385648.5,   75,   16,    6, false,   12,  MON),
            new ChineseTestCase(2392825.5,   75,   36,    2, false,   13,  WED),
            new ChineseTestCase(2416223.5,   76,   40,    3, false,   22,  SUN),
            new ChineseTestCase(2425848.5,   77,    6,    7, false,   21,  SUN),
            new ChineseTestCase(2430266.5,   77,   18,    8, false,    9,  MON),
            new ChineseTestCase(2430833.5,   77,   20,    3, false,   15,  MON),
            new ChineseTestCase(2431004.5,   77,   20,    9, false,    9,  THU),
            new ChineseTestCase(2448698.5,   78,    9,    2, false,   14,  TUE),
            new ChineseTestCase(2450138.5,   78,   13,    1, false,    7,  SUN),
            new ChineseTestCase(2465737.5,   78,   55,   10, false,   14,  WED),
            new ChineseTestCase(2486076.5,   79,   51,    6, false,    7,  SUN),

            // Additional tests not from D&R
            new ChineseTestCase(2467496.5,   78,   60,    8, false,    2,  FRI), // year 60
        };

        ChineseCalendar cal = new ChineseCalendar();
        cal.setLenient(true);
        doTestCases(tests, cal);
    }

    /**
     * Test formatting.
     * Q: Why is this in Calendar tests instead of Format tests?
     * Note: This test assumes that Chinese calendar formatted dates can be parsed
     * unambiguously to recover the original Date that was formatted. This is not
     * currently true since Chinese calendar formatted dates do not include an era.
     * To address this will require formatting/parsing of fields from some other
     * associated calendar, as per ICU ticket #9043. This test should be timebombed
     * until that ticket is addressed.
     */
    public void TestFormat() {
        ChineseCalendar cal = new ChineseCalendar();
        DateFormat fmt = DateFormat.getDateTimeInstance(cal,
                                    DateFormat.DEFAULT, DateFormat.DEFAULT);

        java.util.Calendar tempcal = java.util.Calendar.getInstance();
        tempcal.clear();
        
        Date[] DATA = new Date[2];
        tempcal.set(2001, Calendar.MAY, 22);
        DATA[0] = tempcal.getTime();
        tempcal.set(2001, Calendar.MAY, 23);
        DATA[1] = tempcal.getTime();
        // Wed May 23 2001 = Month 4(leap), Day 1, Year 18, Cycle 78
        
        for (int i=0; i<DATA.length; ++i) {
            String s = fmt.format(DATA[i]);
            try {
                Date e = fmt.parse(s);
                if (e.equals(DATA[i])) {
                    logln("Ok: " + DATA[i] + " -> " + s + " -> " + e);
                } else if (logKnownIssue("9043", "Ambiguous Chinese era parsing")) {
                    logln("Ambiguous parse fails: " + DATA[i] + " -> " + s + " -> " + e);
                } else {
                    errln("FAIL: " + DATA[i] + " -> " + s + " -> " + e);
                }
            } catch (java.text.ParseException e) {
                errln("Fail: " + s + " -> parse failure at " + e.getErrorOffset());
                errln(e.toString());
            }
        }
    }

    /**
     * Make sure IS_LEAP_MONTH participates in field resolution.
     */
    public void TestResolution() {
        ChineseCalendar cal = new ChineseCalendar();
        DateFormat fmt = DateFormat.getDateInstance(cal, DateFormat.DEFAULT);

        // May 22 2001 = y4638 m4 d30 doy119
        // May 23 2001 = y4638 m4* d1 doy120

        final int THE_YEAR = 4638;
        final int END = -1;

        int[] DATA = {
            // Format:
            // (field, value)+, END, exp.month, exp.isLeapMonth, exp.DOM
            // Note: exp.month is ONE-BASED

            // If we set DAY_OF_YEAR only, that should be used
            Calendar.DAY_OF_YEAR, 1,
            END,
            1,0,1, // Expect 1-1
            
            // If we set MONTH only, that should be used
            Calendar.IS_LEAP_MONTH, 1,
            Calendar.DAY_OF_MONTH, 1,
            Calendar.MONTH, 3,
            END,
            4,1,1, // Expect 4*-1
            
            // If we set the DOY last, that should take precedence
            Calendar.MONTH, 1, // Should ignore
            Calendar.IS_LEAP_MONTH, 1, // Should ignore
            Calendar.DAY_OF_MONTH, 1, // Should ignore
            Calendar.DAY_OF_YEAR, 121,
            END,
            4,1,2, // Expect 4*-2
            
            // I've disabled this test because it doesn't work this way,
            // not even with a GregorianCalendar!  MONTH alone isn't enough
            // to supersede DAY_OF_YEAR.  Some other month-related field is
            // also required. - Liu 11/28/00
            //! // If we set MONTH last, that should take precedence
            //! ChineseCalendar.IS_LEAP_MONTH, 1,
            //! Calendar.DAY_OF_MONTH, 1,
            //! Calendar.DAY_OF_YEAR, 5, // Should ignore
            //! Calendar.MONTH, 3,
            //! END,
            //! 4,1,1, // Expect 4*-1
            
            // If we set IS_LEAP_MONTH last, that should take precedence
            Calendar.MONTH, 3,
            Calendar.DAY_OF_MONTH, 1,
            Calendar.DAY_OF_YEAR, 5, // Should ignore
            Calendar.IS_LEAP_MONTH, 1,
            END,
            4,1,1, // Expect 4*-1
        };

        StringBuffer buf = new StringBuffer();
        for (int i=0; i<DATA.length; ) {
            cal.clear();
            cal.set(Calendar.EXTENDED_YEAR, THE_YEAR);
            buf.setLength(0);
            buf.append("EXTENDED_YEAR=" + THE_YEAR);
            while (DATA[i] != END) {
                cal.set(DATA[i++], DATA[i++]);
                buf.append(" " + fieldName(DATA[i-2]) + "=" + DATA[i-1]);
            }
            ++i; // Skip over END mark
            int expMonth = DATA[i++]-1;
            int expIsLeapMonth = DATA[i++];
            int expDOM = DATA[i++];
            int month = cal.get(Calendar.MONTH);
            int isLeapMonth = cal.get(Calendar.IS_LEAP_MONTH);
            int dom = cal.get(Calendar.DAY_OF_MONTH);
            if (expMonth == month && expIsLeapMonth == isLeapMonth &&
                dom == expDOM) {
                logln("OK: " + buf + " => " + fmt.format(cal.getTime()));
            } else {
                String s = fmt.format(cal.getTime());
                cal.clear();
                cal.set(Calendar.EXTENDED_YEAR, THE_YEAR);
                cal.set(Calendar.MONTH, expMonth);
                cal.set(Calendar.IS_LEAP_MONTH, expIsLeapMonth);
                cal.set(Calendar.DAY_OF_MONTH, expDOM);
                errln("Fail: " + buf + " => " + s +
                      "=" + (month+1) + "," + isLeapMonth + "," + dom +
                      ", expected " + fmt.format(cal.getTime()) +
                      "=" + (expMonth+1) + "," + expIsLeapMonth + "," + expDOM);
            }
        }
    }

    /**
     * Test the behavior of fields that are out of range.
     */
    public void TestOutOfRange() {
        int[] DATA = new int[] {
            // Input       Output
            4638, 13,  1,   4639,  1,  1,
            4638, 18,  1,   4639,  6,  1,
            4639,  0,  1,   4638, 12,  1,
            4639, -6,  1,   4638,  6,  1,
            4638,  1, 32,   4638,  2,  2, // 1-4638 has 30 days
            4638,  2, -1,   4638,  1, 29,
        };
        ChineseCalendar cal = new ChineseCalendar();
        for (int i=0; i<DATA.length; ) {
            int y1 = DATA[i++];
            int m1 = DATA[i++]-1;
            int d1 = DATA[i++];
            int y2 = DATA[i++];
            int m2 = DATA[i++]-1;
            int d2 = DATA[i++];
            cal.clear();
            cal.set(Calendar.EXTENDED_YEAR, y1);
            cal.set(MONTH, m1);
            cal.set(DATE, d1);
            int y = cal.get(Calendar.EXTENDED_YEAR);
            int m = cal.get(MONTH);
            int d = cal.get(DATE);
            if (y!=y2 || m!=m2 || d!=d2) {
                errln("Fail: " + y1 + "/" + (m1+1) + "/" + d1 + " resolves to " +
                      y + "/" + (m+1) + "/" + d + ", expected " +
                      y2 + "/" + (m2+1) + "/" + d2);
            } else  if (isVerbose()) {
                logln("OK: " + y1 + "/" + (m1+1) + "/" + d1 + " resolves to " +
                      y + "/" + (m+1) + "/" + d);
            }
        }
    }

    /**
     * Test the behavior of ChineseCalendar.add().  The only real
     * nastiness with roll is the MONTH field around leap months.
     */
    public void TestAdd() {
        int[][] tests = new int[][] {
            // MONTHS ARE 1-BASED HERE
            // input               add           output
            // year  mon    day    field amount  year  mon    day
            {  4642,   3,0,  15,   MONTH,   3,   4642,   6,0,  15 }, // normal
            {  4639,  12,0,  15,   MONTH,   1,   4640,   1,0,  15 }, // across year
            {  4640,   1,0,  15,   MONTH,  -1,   4639,  12,0,  15 }, // across year
            {  4638,   3,0,  15,   MONTH,   3,   4638,   5,0,  15 }, // 4=leap
            {  4638,   3,0,  15,   MONTH,   2,   4638,   4,1,  15 }, // 4=leap
            {  4638,   4,0,  15,   MONTH,   1,   4638,   4,1,  15 }, // 4=leap
            {  4638,   4,1,  15,   MONTH,   1,   4638,   5,0,  15 }, // 4=leap
            {  4638,   4,0,  30,   MONTH,   1,   4638,   4,1,  29 }, // dom should pin
            {  4638,   4,0,  30,   MONTH,   2,   4638,   5,0,  30 }, // no dom pin
            {  4638,   4,0,  30,   MONTH,   3,   4638,   6,0,  29 }, // dom should pin
        };
       
        ChineseCalendar cal = new ChineseCalendar();
        doRollAdd(ADD, cal, tests);
    }

    /**
     * Test the behavior of ChineseCalendar.roll().  The only real
     * nastiness with roll is the MONTH field around leap months.
     */
    public void TestRoll() {
        int[][] tests = new int[][] {
            // MONTHS ARE 1-BASED HERE
            // input               add           output
            // year  mon    day    field amount  year  mon    day
            {  4642,   3,0,  15,   MONTH,   3,   4642,   6,0,  15 }, // normal
            {  4642,   3,0,  15,   MONTH,  11,   4642,   2,0,  15 }, // normal
            {  4639,  12,0,  15,   MONTH,   1,   4639,   1,0,  15 }, // across year
            {  4640,   1,0,  15,   MONTH,  -1,   4640,  12,0,  15 }, // across year
            {  4638,   3,0,  15,   MONTH,   3,   4638,   5,0,  15 }, // 4=leap
            {  4638,   3,0,  15,   MONTH,  16,   4638,   5,0,  15 }, // 4=leap
            {  4638,   3,0,  15,   MONTH,   2,   4638,   4,1,  15 }, // 4=leap
            {  4638,   3,0,  15,   MONTH,  28,   4638,   4,1,  15 }, // 4=leap
            {  4638,   4,0,  15,   MONTH,   1,   4638,   4,1,  15 }, // 4=leap
            {  4638,   4,0,  15,   MONTH, -12,   4638,   4,1,  15 }, // 4=leap
            {  4638,   4,1,  15,   MONTH,   1,   4638,   5,0,  15 }, // 4=leap
            {  4638,   4,1,  15,   MONTH, -25,   4638,   5,0,  15 }, // 4=leap
            {  4638,   4,0,  30,   MONTH,   1,   4638,   4,1,  29 }, // dom should pin
            {  4638,   4,0,  30,   MONTH,  14,   4638,   4,1,  29 }, // dom should pin
            {  4638,   4,0,  30,   MONTH,  15,   4638,   5,0,  30 }, // no dom pin
            {  4638,   4,0,  30,   MONTH, -10,   4638,   6,0,  29 }, // dom should pin
        };
       
        ChineseCalendar cal = new ChineseCalendar();
        doRollAdd(ROLL, cal, tests);
    }
    
    void doRollAdd(boolean roll, ChineseCalendar cal, int[][] tests) {
        String name = roll ? "rolling" : "adding";
        
        for (int i = 0; i < tests.length; i++) {
            int[] test = tests[i];

            cal.clear();
                cal.set(Calendar.EXTENDED_YEAR, test[0]);
                cal.set(Calendar.MONTH, test[1]-1);
                cal.set(Calendar.IS_LEAP_MONTH, test[2]);
                cal.set(Calendar.DAY_OF_MONTH, test[3]);
            if (roll) {
                cal.roll(test[4], test[5]);
            } else {
                cal.add(test[4], test[5]);
            }
            if (cal.get(Calendar.EXTENDED_YEAR) != test[6] ||
                cal.get(MONTH) != (test[7]-1) ||
                cal.get(Calendar.IS_LEAP_MONTH) != test[8] ||
                cal.get(DATE) != test[9]) {
                errln("Fail: " + name + " " +
                      ymdToString(test[0], test[1]-1, test[2], test[3])
                      + " " + fieldName(test[4]) + " by " + test[5]
                      + ": expected " +
                      ymdToString(test[6], test[7]-1, test[8], test[9])
                      + ", got " + ymdToString(cal));
            } else if (isVerbose()) {
                logln("OK: " + name + " " +
                      ymdToString(test[0], test[1]-1, test[2], test[3])
                    + " " + fieldName(test[4]) + " by " + test[5]
                    + ": got " + ymdToString(cal));
            }
        }
    }

    /**
     * Convert year,month,day values to the form "year/month/day".
     * On input the month value is zero-based, but in the result string it is one-based.
     */
    static public String ymdToString(int year, int month, int isLeapMonth, int day) {
        return "" + year + "/" + (month+1) +
            ((isLeapMonth!=0)?"(leap)":"") +
            "/" + day;
    }

//    public void TestFindLeapMonths() {
//        ChineseCalendar cal = new ChineseCalendar();
//        cal.setTime(new Date(2000-1900, Calendar.JANUARY, 1));
//        long end = new Date(2100-1900, Calendar.JANUARY, 1).getTime();
//        ChineseDateFormat fmt = (ChineseDateFormat) DateFormat.getInstance(cal);
//        fmt.applyPattern("u-MMl-dd, 'Year' y, 'Cycle' G");
//        while (cal.getTimeInMillis() < end) {
//            if (cal.get(ChineseCalendar.IS_LEAP_MONTH) != 0) {
//                cal.set(Calendar.DAY_OF_MONTH, 1);
//                logln(cal.getTime() + " = " + fmt.format(cal.getTime()));
//                cal.set(Calendar.DAY_OF_MONTH, 29);
//            }
//            cal.add(Calendar.DAY_OF_YEAR, 25);
//        }
//    }

    public void TestCoverage() {
        // Coverage for constructors
        {
            // new ChineseCalendar(Date)
            ChineseCalendar cal = new ChineseCalendar(new Date());
            if(cal == null){
                errln("could not create ChineseCalendar with Date");
            }
        }

        {
            // new ChineseCalendar(int year, int month, int isLeapMonth, int date)
            ChineseCalendar cal = new ChineseCalendar(23, Calendar.JULY, 1, 2);
            if(cal == null){
                errln("could not create ChineseCalendar with year,month,isLeapMonth,date");
            }
            // Make sure the given values are properly set
            if (cal.get(Calendar.YEAR) != 23 || cal.get(Calendar.MONTH) != Calendar.JULY
                    || cal.get(Calendar.IS_LEAP_MONTH) != 1 || cal.get(Calendar.DATE) != 2
                    || cal.get(Calendar.MILLISECONDS_IN_DAY) != 0) {
                errln("ChineseCalendar was initialized incorrectly with year,month,isLeapMonth,date");
            }
        }

        {
            // new ChineseCalendar(int year, int month, int isLeapMonth, int date, int hour, int minute, int second)
            ChineseCalendar cal = new ChineseCalendar(23, Calendar.JULY, 1, 2, 12, 34, 56);
            if(cal == null){
                errln("could not create ChineseCalendar with year,month,isLeapMonth,date,hour,minute,second");
            }
            // Make sure the given values are properly set
            if (cal.get(Calendar.YEAR) != 23 || cal.get(Calendar.MONTH) != Calendar.JULY
                    || cal.get(Calendar.IS_LEAP_MONTH) != 1 || cal.get(Calendar.DATE) != 2
                    || cal.get(Calendar.HOUR_OF_DAY) != 12 || cal.get(Calendar.MINUTE) != 34
                    || cal.get(Calendar.SECOND) != 56 || cal.get(Calendar.MILLISECOND) != 0) {
                errln("ChineseCalendar was initialized incorrectly with year,month,isLeapMonth,date,hour,minute,second");
            }
        }

        {
            // new ChineseCalendar(Locale)
            ChineseCalendar cal = new ChineseCalendar(Locale.getDefault());
            if(cal == null){
                errln("could not create ChineseCalendar with Locale");
            }
        }

        {
            // new ChineseCalendar(ULocale)
            ChineseCalendar cal = new ChineseCalendar(ULocale.getDefault());
            if(cal == null){
                errln("could not create ChineseCalendar with ULocale");
            }
        }
        

        {
            // new ChineseCalendar(TimeZone)
            ChineseCalendar cal = new ChineseCalendar(TimeZone.getDefault()); 
            if(cal == null){
                errln("could not create ChineseCalendar with TimeZone");
            }
        }

        {
            // new ChineseCalendar(TimeZone, Locale)
            ChineseCalendar cal = new ChineseCalendar(TimeZone.getDefault(), Locale.getDefault());
            if(cal == null){
                errln("could not create ChineseCalendar with TimeZone,Locale");
            }
        }

        {
            // new ChineseCalendar(TimeZone, ULocale)
            ChineseCalendar cal = new ChineseCalendar(TimeZone.getDefault(), ULocale.getDefault());
            if(cal == null){
                errln("could not create ChineseCalendar with TimeZone,ULocale");
            }
        }

        // Note: ICU 50 or later versions, DateFormat.getInstance(ChineseCalendar) no longer
        // returns an instance of ChineseDateFormat. Chinese calendar formatting support was
        // changed and integrated into SimpleDateFormat since ICU 49. Also, ChineseDateFormat
        // specific pattern letter "l" is no longer used by the new implementation.

//        ChineseCalendar cal = new ChineseCalendar();
//        DateFormat format = DateFormat.getInstance(cal);
//        if(!(format instanceof ChineseDateFormat)){
//            errln("DateFormat.getInstance("+cal+") did not return a ChineseDateFormat");
//        }
//        ChineseDateFormat fmt = (ChineseDateFormat)format;
//        fmt.applyPattern("llyyll");
//        Date time = getDate(2100, Calendar.JANUARY, 1);
//        String str = fmt.format(time);
//        try {
//            Date e = fmt.parse(str);
//            logln("chinese calendar time: " + time + " result: " + str + " --> " + e);
//        } catch (java.text.ParseException ex) {
//            logln(ex.getMessage()); // chinese calendar can't parse this, no error for now
//        }

        //new ChineseCalendar(TimeZone,ULocale)
        ChineseCalendar ccal2 = new ChineseCalendar(TimeZone.getDefault(),
                                                   ULocale.CHINA);
        if(ccal2==null){
            errln("could not create ChineseCalendar with TimeZone ULocale");
        } else {
            DateFormat fmt2 = DateFormat.getDateInstance(ccal2, DateFormat.DEFAULT, ULocale.CHINA);
            Date time2 = getDate(2001, Calendar.MAY, 23);
            String str2 = fmt2.format(time2);
            logln("Chinese calendar time: " + time2 + " result: " + str2);
        }
    }
    public void TestScratch(){
        String[] strMonths = {"Januari", "Pebruari", "Maret", "April", "Mei", "Juni",
                "Juli", "Agustus", "September", "Oktober", "Nopember", "Desember"};
        String[] strShortMonths = {"Jan", "Peb", "Mar", "Apr", "Mei", "Jun",
                     "Jul", "Agt", "Sep", "Okt", "Nop", "Des"};
        String[] strWeeks = {"", "Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"};
        DateFormatSymbols dfsDate = new DateFormatSymbols(new Locale("id", "ID"));
        dfsDate.setMonths(strMonths);
        dfsDate.setShortMonths(strShortMonths);
        dfsDate.setWeekdays(strWeeks);
        ULocale uloInd = dfsDate.getLocale(ULocale.ACTUAL_LOCALE);
        if(uloInd==null){
            errln("did not get the expected ULocale");
        }
        logln(uloInd.toString());
        Locale locInd = uloInd.toLocale();
        if(locInd==null){
            errln("did not get the expected result");
        }
        logln(locInd.toString());
    }

    public void TestInitWithCurrentTime() {
        // jb4555
        // if the chinese calendar current millis isn't called, the default year is wrong.
        // this test is assuming the 'year' is the current cycle
        // so when we cross a cycle boundary, the target will need to change
        // that shouldn't be for awhile yet... 

        ChineseCalendar cc = new ChineseCalendar();
        cc.set(Calendar.YEAR, 22);
        cc.set(Calendar.MONTH, 0);
         // need to set leap month flag off, otherwise, the test case always fails when
         // current time is in a leap month
        cc.set(Calendar.IS_LEAP_MONTH, 0);
        cc.set(Calendar.DATE, 19);
        cc.set(Calendar.HOUR_OF_DAY, 0);
        cc.set(Calendar.MINUTE, 0);
        cc.set(Calendar.SECOND, 0);
        cc.set(Calendar.MILLISECOND, 0);

        cc.add(Calendar.DATE, 1);
 
        Calendar cal = new GregorianCalendar(2005, Calendar.FEBRUARY, 28);
        Date target = cal.getTime();
        Date result = cc.getTime();

        assertEquals("chinese and gregorian date should match", target, result);
    }

    public void Test6510() 
    { 
        Calendar gregorianCalendar; 
        ChineseCalendar chineseCalendar, chineseCalendar2; 
        ChineseDateFormat dateFormat; 
        SimpleDateFormat simpleDateFormat; 
 
        simpleDateFormat = new com.ibm.icu.text.SimpleDateFormat("MM/dd/yyyy G 'at' HH:mm:ss vvvv", Locale.US); 
        dateFormat = new com.ibm.icu.text.ChineseDateFormat("MM/dd/yyyy(G) HH:mm:ss", Locale.CHINA); 
 
        // lunar to gregorian 
        chineseCalendar = new ChineseCalendar(77, 26, Calendar.JANUARY, 0, 6, 0, 0, 0); 
        gregorianCalendar = Calendar.getInstance(Locale.US); 
        gregorianCalendar.setTime(chineseCalendar.getTime()); 
 
        // gregorian to lunar 
        chineseCalendar2 = new ChineseCalendar(); 
        chineseCalendar2.setTimeInMillis(gregorianCalendar.getTimeInMillis()); 

        // validate roundtrip 
        if (chineseCalendar.getTimeInMillis() != chineseCalendar2.getTimeInMillis()) 
        { 
            errln("time1: " + chineseCalendar.getTimeInMillis()); 
            errln("time2: " + chineseCalendar2.getTimeInMillis()); 
            errln("Lunar [MM/dd/y(G) HH:mm:ss] " + dateFormat.format(chineseCalendar)); 
            errln("**PROBLEM Grego [MM/dd/y(G) HH:mm:ss] " + simpleDateFormat.format(gregorianCalendar)); 
            errln("Grego [MM/dd/y(G) HH:mm:ss] " + simpleDateFormat.format(gregorianCalendar)); 
            errln("Lunar [MM/dd/y(G) HH:mm:ss] " + dateFormat.format(chineseCalendar2)); 
        } 
    }         
}
