/*********************************************************************
 * Copyright (C) 2000-2012, 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;
import com.ibm.icu.util.VersionInfo;

/**
 * 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 (isICUVersionBefore(50, 1)) { // until ticket #9043 fixes the ambiguous era problem
                    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");
            }
        }

        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 {
            fmt = (ChineseDateFormat)DateFormat.getDateInstance(ccal2, DateFormat.DEFAULT, ULocale.CHINA);
            time = getDate(2001, Calendar.MAY, 23);
            str = fmt.format(time);
            logln("Chinese calendar time: " + time + " result: " + str);
        }
    }
    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)); 
        } 
    }         
}
