]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_2_1-src/src/com/ibm/icu/dev/test/calendar/ChineseTest.java
icu4jsrc
[Dictionary.git] / jars / icu4j-4_2_1-src / src / com / ibm / icu / dev / test / calendar / ChineseTest.java
1 /*********************************************************************\r
2  * Copyright (C) 2000-2008, International Business Machines Corporation and\r
3  * others. All Rights Reserved.\r
4  *********************************************************************\r
5  */\r
6 package com.ibm.icu.dev.test.calendar;\r
7 import com.ibm.icu.util.*;\r
8 import com.ibm.icu.text.*;\r
9 \r
10 import java.util.Date;\r
11 import java.util.Locale;\r
12 \r
13 /**\r
14  * Test of ChineseCalendar.\r
15  *\r
16  * Leap months in this century:\r
17  * Wed May 23 2001 = 4638-04*-01, Year 18, Cycle 78\r
18  * Sun Mar 21 2004 = 4641-02*-01, Year 21, Cycle 78\r
19  * Thu Aug 24 2006 = 4643-07*-01, Year 23, Cycle 78\r
20  * Tue Jun 23 2009 = 4646-05*-01, Year 26, Cycle 78\r
21  * Mon May 21 2012 = 4649-04*-01, Year 29, Cycle 78\r
22  * Fri Oct 24 2014 = 4651-09*-01, Year 31, Cycle 78\r
23  * Sun Jul 23 2017 = 4654-06*-01, Year 34, Cycle 78\r
24  * Sat May 23 2020 = 4657-04*-01, Year 37, Cycle 78\r
25  * Wed Mar 22 2023 = 4660-02*-01, Year 40, Cycle 78\r
26  * Fri Jul 25 2025 = 4662-06*-01, Year 42, Cycle 78\r
27  * Fri Jun 23 2028 = 4665-05*-01, Year 45, Cycle 78\r
28  * Tue Apr 22 2031 = 4668-03*-01, Year 48, Cycle 78\r
29  * Thu Dec 22 2033 = 4670-11*-01, Year 50, Cycle 78\r
30  * Wed Jul 23 2036 = 4673-06*-01, Year 53, Cycle 78\r
31  * Wed Jun 22 2039 = 4676-05*-01, Year 56, Cycle 78\r
32  * Sat Mar 22 2042 = 4679-02*-01, Year 59, Cycle 78\r
33  * Tue Aug 23 2044 = 4681-07*-01, Year 01, Cycle 79\r
34  * Sun Jun 23 2047 = 4684-05*-01, Year 04, Cycle 79\r
35  * Thu Apr 21 2050 = 4687-03*-01, Year 07, Cycle 79\r
36  * Mon Sep 23 2052 = 4689-08*-01, Year 09, Cycle 79\r
37  * Sat Jul 24 2055 = 4692-06*-01, Year 12, Cycle 79\r
38  * Wed May 22 2058 = 4695-04*-01, Year 15, Cycle 79\r
39  * Wed Apr 20 2061 = 4698-03*-01, Year 18, Cycle 79\r
40  * Fri Aug 24 2063 = 4700-07*-01, Year 20, Cycle 79\r
41  * Wed Jun 23 2066 = 4703-05*-01, Year 23, Cycle 79\r
42  * Tue May 21 2069 = 4706-04*-01, Year 26, Cycle 79\r
43  * Thu Sep 24 2071 = 4708-08*-01, Year 28, Cycle 79\r
44  * Tue Jul 24 2074 = 4711-06*-01, Year 31, Cycle 79\r
45  * Sat May 22 2077 = 4714-04*-01, Year 34, Cycle 79\r
46  * Sat Apr 20 2080 = 4717-03*-01, Year 37, Cycle 79\r
47  * Mon Aug 24 2082 = 4719-07*-01, Year 39, Cycle 79\r
48  * Fri Jun 22 2085 = 4722-05*-01, Year 42, Cycle 79\r
49  * Fri May 21 2088 = 4725-04*-01, Year 45, Cycle 79\r
50  * Sun Sep 24 2090 = 4727-08*-01, Year 47, Cycle 79\r
51  * Thu Jul 23 2093 = 4730-06*-01, Year 50, Cycle 79\r
52  * Tue May 22 2096 = 4733-04*-01, Year 53, Cycle 79\r
53  * Sun Mar 22 2099 = 4736-02*-01, Year 56, Cycle 79\r
54  */\r
55 public class ChineseTest extends CalendarTest {\r
56 \r
57     public static void main(String args[]) throws Exception {\r
58         new ChineseTest().run(args);\r
59     }\r
60 \r
61     /**\r
62      * Test basic mapping to and from Gregorian.\r
63      */\r
64     public void TestMapping() {\r
65 \r
66         final int[] DATA = {\r
67             // (Note: months are 1-based)\r
68             // Gregorian    Chinese\r
69             1964,  9,  4,   4601,  7,0, 28,\r
70             1964,  9,  5,   4601,  7,0, 29,\r
71             1964,  9,  6,   4601,  8,0,  1,\r
72             1964,  9,  7,   4601,  8,0,  2,\r
73             1961, 12, 25,   4598, 11,0, 18,\r
74             1999,  6,  4,   4636,  4,0, 21,\r
75             \r
76             1990,  5, 23,   4627,  4,0, 29,\r
77             1990,  5, 24,   4627,  5,0,  1,\r
78             1990,  6, 22,   4627,  5,0, 30,\r
79             1990,  6, 23,   4627,  5,1,  1,\r
80             1990,  7, 20,   4627,  5,1, 28,\r
81             1990,  7, 21,   4627,  5,1, 29,\r
82             1990,  7, 22,   4627,  6,0,  1,\r
83         };\r
84 \r
85         ChineseCalendar cal = new ChineseCalendar();\r
86         StringBuffer buf = new StringBuffer();\r
87 \r
88         logln("Gregorian -> Chinese");\r
89         //java.util.Calendar grego = java.util.Calendar.getInstance();\r
90         Calendar grego = Calendar.getInstance();\r
91         grego.clear();\r
92         for (int i=0; i<DATA.length; ) {\r
93             grego.set(DATA[i++], DATA[i++]-1, DATA[i++]);\r
94             Date date = grego.getTime();\r
95             cal.setTime(date);\r
96             int y = cal.get(Calendar.EXTENDED_YEAR);\r
97             int m = cal.get(Calendar.MONTH)+1; // 0-based -> 1-based\r
98             int L = cal.get(ChineseCalendar.IS_LEAP_MONTH);\r
99             int d = cal.get(Calendar.DAY_OF_MONTH);\r
100             int yE = DATA[i++]; // Expected y, m, isLeapMonth, d\r
101             int mE = DATA[i++]; // 1-based\r
102             int LE = DATA[i++];\r
103             int dE = DATA[i++];\r
104             buf.setLength(0);\r
105             buf.append(date + " -> ");\r
106             buf.append(y + "/" + m + (L==1?"(leap)":"") + "/" + d);\r
107             if (y == yE && m == mE && L == LE && d == dE) {\r
108                 logln("OK: " + buf.toString());\r
109             } else {\r
110                 errln("Fail: " + buf.toString() + ", expected " +\r
111                       yE + "/" + mE + (LE==1?"(leap)":"") + "/" + dE);\r
112             }\r
113         }\r
114 \r
115         logln("Chinese -> Gregorian");\r
116         for (int i=0; i<DATA.length; ) {\r
117             grego.set(DATA[i++], DATA[i++]-1, DATA[i++]);\r
118             Date dexp = grego.getTime();\r
119             int cyear = DATA[i++];\r
120             int cmonth = DATA[i++];\r
121             int cisleapmonth = DATA[i++];\r
122             int cdayofmonth = DATA[i++];\r
123             cal.clear();\r
124             cal.set(Calendar.EXTENDED_YEAR, cyear);\r
125             cal.set(Calendar.MONTH, cmonth-1);\r
126             cal.set(ChineseCalendar.IS_LEAP_MONTH, cisleapmonth);\r
127             cal.set(Calendar.DAY_OF_MONTH, cdayofmonth);\r
128             Date date = cal.getTime();\r
129             buf.setLength(0);\r
130             buf.append(cyear + "/" + cmonth +\r
131                        (cisleapmonth==1?"(leap)":"") + "/" + cdayofmonth);\r
132             buf.append(" -> " + date);\r
133             if (date.equals(dexp)) {\r
134                 logln("OK: " + buf.toString());\r
135             } else {\r
136                 errln("Fail: " + buf.toString() + ", expected " + dexp);\r
137             }\r
138         }\r
139     }\r
140 \r
141     /**\r
142      * Make sure no Gregorian dates map to Chinese 1-based day of\r
143      * month zero.  This was a problem with some of the astronomical\r
144      * new moon determinations.\r
145      */\r
146     public void TestZeroDOM() {\r
147         ChineseCalendar cal = new ChineseCalendar();\r
148         GregorianCalendar greg = new GregorianCalendar(1989, Calendar.SEPTEMBER, 1);\r
149         logln("Start: " + greg.getTime());\r
150         for (int i=0; i<1000; ++i) {\r
151             cal.setTimeInMillis(greg.getTimeInMillis());\r
152             if (cal.get(Calendar.DAY_OF_MONTH) == 0) {\r
153                 errln("Fail: " + greg.getTime() + " -> " +\r
154                       cal.get(Calendar.EXTENDED_YEAR) + "/" +\r
155                       cal.get(Calendar.MONTH) +\r
156                       (cal.get(ChineseCalendar.IS_LEAP_MONTH)==1?"(leap)":"") +\r
157                       "/" + cal.get(Calendar.DAY_OF_MONTH));\r
158             }\r
159             greg.add(Calendar.DAY_OF_YEAR, 1);\r
160         }\r
161         logln("End: " + greg.getTime());\r
162     }\r
163 \r
164     /**\r
165      * Test minimum and maximum functions.\r
166      */\r
167     public void TestLimits() {\r
168         // The number of days and the start date can be adjusted\r
169         // arbitrarily to either speed up the test or make it more\r
170         // thorough, but try to test at least a full year, preferably a\r
171         // full non-leap and a full leap year.\r
172 \r
173         // Final parameter is either number of days, if > 0, or test\r
174         // duration in seconds, if < 0.\r
175         java.util.Calendar tempcal = java.util.Calendar.getInstance();\r
176         tempcal.clear();\r
177         tempcal.set(1989, Calendar.NOVEMBER, 1);\r
178         ChineseCalendar chinese = new ChineseCalendar();\r
179         doLimitsTest(chinese, null, tempcal.getTime());\r
180         doTheoreticalLimitsTest(chinese, true);\r
181     }\r
182 \r
183     /**\r
184      * Run through several standard tests from Dershowitz & Reingold.\r
185      */\r
186     public void TestJulianDayMapping() {\r
187 \r
188         final TestCase[] tests = {\r
189             //\r
190             // From Dershowitz & Reingold, "Calendrical Calculations".\r
191             //\r
192             // The months in this table are 1-based rather than 0-based.\r
193             //\r
194             // * Failing fields->millis\r
195             // ** Millis->fields gives 0-based month -1\r
196             // These failures were fixed by changing the start search date\r
197             // for the winter solstice from Dec 15 to Dec 1.\r
198             // \r
199             //                  Julian Day   Era  Year Month  Leap   DOM WkDay\r
200             new ChineseTestCase(1507231.5,   35,   11,    6, false,   12,  SUN),\r
201             new ChineseTestCase(1660037.5,   42,    9,   10, false,   27,  WED),\r
202             new ChineseTestCase(1746893.5,   46,    7,    8, false,    4,  WED),\r
203             new ChineseTestCase(1770641.5,   47,   12,    8, false,    9,  SUN),\r
204             new ChineseTestCase(1892731.5,   52,   46,   11, false,   20,  WED),\r
205             new ChineseTestCase(1931579.5,   54,   33,    4, false,    5,  MON),\r
206             new ChineseTestCase(1974851.5,   56,   31,   10, false,   15,  SAT),\r
207             new ChineseTestCase(2091164.5,   61,   50,    3, false,    7,  SUN),\r
208             new ChineseTestCase(2121509.5,   63,   13,    4, false,   24,  SUN),\r
209             new ChineseTestCase(2155779.5,   64,   47,    2, false,    9,  FRI),\r
210             new ChineseTestCase(2174029.5,   65,   37,    2, false,    9,  SAT),\r
211             new ChineseTestCase(2191584.5,   66,   25,    2, false,   23,  FRI),\r
212             new ChineseTestCase(2195261.5,   66,   35,    3, false,    9,  SUN), //*\r
213             new ChineseTestCase(2229274.5,   68,    8,    5, false,    2,  SUN), //*\r
214             new ChineseTestCase(2245580.5,   68,   53,    1, false,    8,  WED), //**\r
215             new ChineseTestCase(2266100.5,   69,   49,    3, false,    4,  SAT), \r
216             new ChineseTestCase(2288542.5,   70,   50,    8, false,    2,  SAT), //*\r
217             new ChineseTestCase(2290901.5,   70,   57,    1, false,   29,  SAT), //*\r
218             new ChineseTestCase(2323140.5,   72,   25,    4,  true,   20,  WED), //*\r
219             new ChineseTestCase(2334848.5,   72,   57,    6, false,    5,  SUN),\r
220             new ChineseTestCase(2348020.5,   73,   33,    6, false,    6,  FRI),\r
221             new ChineseTestCase(2366978.5,   74,   25,    5, false,    5,  SUN),\r
222             new ChineseTestCase(2385648.5,   75,   16,    6, false,   12,  MON),\r
223             new ChineseTestCase(2392825.5,   75,   36,    2, false,   13,  WED),\r
224             new ChineseTestCase(2416223.5,   76,   40,    3, false,   22,  SUN),\r
225             new ChineseTestCase(2425848.5,   77,    6,    7, false,   21,  SUN),\r
226             new ChineseTestCase(2430266.5,   77,   18,    8, false,    9,  MON),\r
227             new ChineseTestCase(2430833.5,   77,   20,    3, false,   15,  MON),\r
228             new ChineseTestCase(2431004.5,   77,   20,    9, false,    9,  THU),\r
229             new ChineseTestCase(2448698.5,   78,    9,    2, false,   14,  TUE),\r
230             new ChineseTestCase(2450138.5,   78,   13,    1, false,    7,  SUN),\r
231             new ChineseTestCase(2465737.5,   78,   55,   10, false,   14,  WED),\r
232             new ChineseTestCase(2486076.5,   79,   51,    6, false,    7,  SUN),\r
233 \r
234             // Additional tests not from D&R\r
235             new ChineseTestCase(2467496.5,   78,   60,    8, false,    2,  FRI), // year 60\r
236         };\r
237 \r
238         ChineseCalendar cal = new ChineseCalendar();\r
239         cal.setLenient(true);\r
240         doTestCases(tests, cal);\r
241     }\r
242 \r
243     /**\r
244      * Test formatting.\r
245      */\r
246     public void TestFormat() {\r
247         ChineseCalendar cal = new ChineseCalendar();\r
248         DateFormat fmt = DateFormat.getDateTimeInstance(cal,\r
249                                     DateFormat.DEFAULT, DateFormat.DEFAULT);\r
250 \r
251         java.util.Calendar tempcal = java.util.Calendar.getInstance();\r
252         tempcal.clear();\r
253         \r
254         Date[] DATA = new Date[2];\r
255         tempcal.set(2001, Calendar.MAY, 22);\r
256         DATA[0] = tempcal.getTime();\r
257         tempcal.set(2001, Calendar.MAY, 23);\r
258         DATA[1] = tempcal.getTime();\r
259         // Wed May 23 2001 = Month 4(leap), Day 1, Year 18, Cycle 78\r
260         \r
261         for (int i=0; i<DATA.length; ++i) {\r
262             String s = fmt.format(DATA[i]);\r
263             try {\r
264                 Date e = fmt.parse(s);\r
265                 if (e.equals(DATA[i])) {\r
266                     logln("Ok: " + DATA[i] + " -> " + s + " -> " + e);\r
267                 } else {\r
268                     errln("FAIL: " + DATA[i] + " -> " + s + " -> " + e);\r
269                 }\r
270             } catch (java.text.ParseException e) {\r
271                 errln("Fail: " + s + " -> parse failure at " + e.getErrorOffset());\r
272                 errln(e.toString());\r
273             }\r
274         }\r
275     }\r
276 \r
277     /**\r
278      * Make sure IS_LEAP_MONTH participates in field resolution.\r
279      */\r
280     public void TestResolution() {\r
281         ChineseCalendar cal = new ChineseCalendar();\r
282         DateFormat fmt = DateFormat.getDateInstance(cal, DateFormat.DEFAULT);\r
283 \r
284         // May 22 2001 = y4638 m4 d30 doy119\r
285         // May 23 2001 = y4638 m4* d1 doy120\r
286 \r
287         final int THE_YEAR = 4638;\r
288         final int END = -1;\r
289 \r
290         int[] DATA = {\r
291             // Format:\r
292             // (field, value)+, END, exp.month, exp.isLeapMonth, exp.DOM\r
293             // Note: exp.month is ONE-BASED\r
294 \r
295             // If we set DAY_OF_YEAR only, that should be used\r
296             Calendar.DAY_OF_YEAR, 1,\r
297             END,\r
298             1,0,1, // Expect 1-1\r
299             \r
300             // If we set MONTH only, that should be used\r
301             ChineseCalendar.IS_LEAP_MONTH, 1,\r
302             Calendar.DAY_OF_MONTH, 1,\r
303             Calendar.MONTH, 3,\r
304             END,\r
305             4,1,1, // Expect 4*-1\r
306             \r
307             // If we set the DOY last, that should take precedence\r
308             Calendar.MONTH, 1, // Should ignore\r
309             ChineseCalendar.IS_LEAP_MONTH, 1, // Should ignore\r
310             Calendar.DAY_OF_MONTH, 1, // Should ignore\r
311             Calendar.DAY_OF_YEAR, 121,\r
312             END,\r
313             4,1,2, // Expect 4*-2\r
314             \r
315             // I've disabled this test because it doesn't work this way,\r
316             // not even with a GregorianCalendar!  MONTH alone isn't enough\r
317             // to supersede DAY_OF_YEAR.  Some other month-related field is\r
318             // also required. - Liu 11/28/00\r
319             //! // If we set MONTH last, that should take precedence\r
320             //! ChineseCalendar.IS_LEAP_MONTH, 1,\r
321             //! Calendar.DAY_OF_MONTH, 1,\r
322             //! Calendar.DAY_OF_YEAR, 5, // Should ignore\r
323             //! Calendar.MONTH, 3,\r
324             //! END,\r
325             //! 4,1,1, // Expect 4*-1\r
326             \r
327             // If we set IS_LEAP_MONTH last, that should take precedence\r
328             Calendar.MONTH, 3,\r
329             Calendar.DAY_OF_MONTH, 1,\r
330             Calendar.DAY_OF_YEAR, 5, // Should ignore\r
331             ChineseCalendar.IS_LEAP_MONTH, 1,\r
332             END,\r
333             4,1,1, // Expect 4*-1\r
334         };\r
335 \r
336         StringBuffer buf = new StringBuffer();\r
337         for (int i=0; i<DATA.length; ) {\r
338             cal.clear();\r
339             cal.set(Calendar.EXTENDED_YEAR, THE_YEAR);\r
340             buf.setLength(0);\r
341             buf.append("EXTENDED_YEAR=" + THE_YEAR);\r
342             while (DATA[i] != END) {\r
343                 cal.set(DATA[i++], DATA[i++]);\r
344                 buf.append(" " + fieldName(DATA[i-2]) + "=" + DATA[i-1]);\r
345             }\r
346             ++i; // Skip over END mark\r
347             int expMonth = DATA[i++]-1;\r
348             int expIsLeapMonth = DATA[i++];\r
349             int expDOM = DATA[i++];\r
350             int month = cal.get(Calendar.MONTH);\r
351             int isLeapMonth = cal.get(ChineseCalendar.IS_LEAP_MONTH);\r
352             int dom = cal.get(Calendar.DAY_OF_MONTH);\r
353             if (expMonth == month && expIsLeapMonth == isLeapMonth &&\r
354                 dom == expDOM) {\r
355                 logln("OK: " + buf + " => " + fmt.format(cal.getTime()));\r
356             } else {\r
357                 String s = fmt.format(cal.getTime());\r
358                 cal.clear();\r
359                 cal.set(Calendar.EXTENDED_YEAR, THE_YEAR);\r
360                 cal.set(Calendar.MONTH, expMonth);\r
361                 cal.set(ChineseCalendar.IS_LEAP_MONTH, expIsLeapMonth);\r
362                 cal.set(Calendar.DAY_OF_MONTH, expDOM);\r
363                 errln("Fail: " + buf + " => " + s +\r
364                       "=" + (month+1) + "," + isLeapMonth + "," + dom +\r
365                       ", expected " + fmt.format(cal.getTime()) +\r
366                       "=" + (expMonth+1) + "," + expIsLeapMonth + "," + expDOM);\r
367             }\r
368         }\r
369     }\r
370 \r
371     /**\r
372      * Test the behavior of fields that are out of range.\r
373      */\r
374     public void TestOutOfRange() {\r
375         int[] DATA = new int[] {\r
376             // Input       Output\r
377             4638, 13,  1,   4639,  1,  1,\r
378             4638, 18,  1,   4639,  6,  1,\r
379             4639,  0,  1,   4638, 12,  1,\r
380             4639, -6,  1,   4638,  6,  1,\r
381             4638,  1, 32,   4638,  2,  2, // 1-4638 has 30 days\r
382             4638,  2, -1,   4638,  1, 29,\r
383         };\r
384         ChineseCalendar cal = new ChineseCalendar();\r
385         for (int i=0; i<DATA.length; ) {\r
386             int y1 = DATA[i++];\r
387             int m1 = DATA[i++]-1;\r
388             int d1 = DATA[i++];\r
389             int y2 = DATA[i++];\r
390             int m2 = DATA[i++]-1;\r
391             int d2 = DATA[i++];\r
392             cal.clear();\r
393             cal.set(Calendar.EXTENDED_YEAR, y1);\r
394             cal.set(MONTH, m1);\r
395             cal.set(DATE, d1);\r
396             int y = cal.get(Calendar.EXTENDED_YEAR);\r
397             int m = cal.get(MONTH);\r
398             int d = cal.get(DATE);\r
399             if (y!=y2 || m!=m2 || d!=d2) {\r
400                 errln("Fail: " + y1 + "/" + (m1+1) + "/" + d1 + " resolves to " +\r
401                       y + "/" + (m+1) + "/" + d + ", expected " +\r
402                       y2 + "/" + (m2+1) + "/" + d2);\r
403             } else  if (isVerbose()) {\r
404                 logln("OK: " + y1 + "/" + (m1+1) + "/" + d1 + " resolves to " +\r
405                       y + "/" + (m+1) + "/" + d);\r
406             }\r
407         }\r
408     }\r
409 \r
410     /**\r
411      * Test the behavior of ChineseCalendar.add().  The only real\r
412      * nastiness with roll is the MONTH field around leap months.\r
413      */\r
414     public void TestAdd() {\r
415         int[][] tests = new int[][] {\r
416             // MONTHS ARE 1-BASED HERE\r
417             // input               add           output\r
418             // year  mon    day    field amount  year  mon    day\r
419             {  4642,   3,0,  15,   MONTH,   3,   4642,   6,0,  15 }, // normal\r
420             {  4639,  12,0,  15,   MONTH,   1,   4640,   1,0,  15 }, // across year\r
421             {  4640,   1,0,  15,   MONTH,  -1,   4639,  12,0,  15 }, // across year\r
422             {  4638,   3,0,  15,   MONTH,   3,   4638,   5,0,  15 }, // 4=leap\r
423             {  4638,   3,0,  15,   MONTH,   2,   4638,   4,1,  15 }, // 4=leap\r
424             {  4638,   4,0,  15,   MONTH,   1,   4638,   4,1,  15 }, // 4=leap\r
425             {  4638,   4,1,  15,   MONTH,   1,   4638,   5,0,  15 }, // 4=leap\r
426             {  4638,   4,0,  30,   MONTH,   1,   4638,   4,1,  29 }, // dom should pin\r
427             {  4638,   4,0,  30,   MONTH,   2,   4638,   5,0,  30 }, // no dom pin\r
428             {  4638,   4,0,  30,   MONTH,   3,   4638,   6,0,  29 }, // dom should pin\r
429         };\r
430        \r
431         ChineseCalendar cal = new ChineseCalendar();\r
432         doRollAdd(ADD, cal, tests);\r
433     }\r
434 \r
435     /**\r
436      * Test the behavior of ChineseCalendar.roll().  The only real\r
437      * nastiness with roll is the MONTH field around leap months.\r
438      */\r
439     public void TestRoll() {\r
440         int[][] tests = new int[][] {\r
441             // MONTHS ARE 1-BASED HERE\r
442             // input               add           output\r
443             // year  mon    day    field amount  year  mon    day\r
444             {  4642,   3,0,  15,   MONTH,   3,   4642,   6,0,  15 }, // normal\r
445             {  4642,   3,0,  15,   MONTH,  11,   4642,   2,0,  15 }, // normal\r
446             {  4639,  12,0,  15,   MONTH,   1,   4639,   1,0,  15 }, // across year\r
447             {  4640,   1,0,  15,   MONTH,  -1,   4640,  12,0,  15 }, // across year\r
448             {  4638,   3,0,  15,   MONTH,   3,   4638,   5,0,  15 }, // 4=leap\r
449             {  4638,   3,0,  15,   MONTH,  16,   4638,   5,0,  15 }, // 4=leap\r
450             {  4638,   3,0,  15,   MONTH,   2,   4638,   4,1,  15 }, // 4=leap\r
451             {  4638,   3,0,  15,   MONTH,  28,   4638,   4,1,  15 }, // 4=leap\r
452             {  4638,   4,0,  15,   MONTH,   1,   4638,   4,1,  15 }, // 4=leap\r
453             {  4638,   4,0,  15,   MONTH, -12,   4638,   4,1,  15 }, // 4=leap\r
454             {  4638,   4,1,  15,   MONTH,   1,   4638,   5,0,  15 }, // 4=leap\r
455             {  4638,   4,1,  15,   MONTH, -25,   4638,   5,0,  15 }, // 4=leap\r
456             {  4638,   4,0,  30,   MONTH,   1,   4638,   4,1,  29 }, // dom should pin\r
457             {  4638,   4,0,  30,   MONTH,  14,   4638,   4,1,  29 }, // dom should pin\r
458             {  4638,   4,0,  30,   MONTH,  15,   4638,   5,0,  30 }, // no dom pin\r
459             {  4638,   4,0,  30,   MONTH, -10,   4638,   6,0,  29 }, // dom should pin\r
460         };\r
461        \r
462         ChineseCalendar cal = new ChineseCalendar();\r
463         doRollAdd(ROLL, cal, tests);\r
464     }\r
465     \r
466     void doRollAdd(boolean roll, ChineseCalendar cal, int[][] tests) {\r
467         String name = roll ? "rolling" : "adding";\r
468         \r
469         for (int i = 0; i < tests.length; i++) {\r
470             int[] test = tests[i];\r
471 \r
472             cal.clear();\r
473                 cal.set(Calendar.EXTENDED_YEAR, test[0]);\r
474                 cal.set(Calendar.MONTH, test[1]-1);\r
475                 cal.set(ChineseCalendar.IS_LEAP_MONTH, test[2]);\r
476                 cal.set(Calendar.DAY_OF_MONTH, test[3]);\r
477             if (roll) {\r
478                 cal.roll(test[4], test[5]);\r
479             } else {\r
480                 cal.add(test[4], test[5]);\r
481             }\r
482             if (cal.get(Calendar.EXTENDED_YEAR) != test[6] ||\r
483                 cal.get(MONTH) != (test[7]-1) ||\r
484                 cal.get(ChineseCalendar.IS_LEAP_MONTH) != test[8] ||\r
485                 cal.get(DATE) != test[9]) {\r
486                 errln("Fail: " + name + " " +\r
487                       ymdToString(test[0], test[1]-1, test[2], test[3])\r
488                       + " " + fieldName(test[4]) + " by " + test[5]\r
489                       + ": expected " +\r
490                       ymdToString(test[6], test[7]-1, test[8], test[9])\r
491                       + ", got " + ymdToString(cal));\r
492             } else if (isVerbose()) {\r
493                 logln("OK: " + name + " " +\r
494                       ymdToString(test[0], test[1]-1, test[2], test[3])\r
495                     + " " + fieldName(test[4]) + " by " + test[5]\r
496                     + ": got " + ymdToString(cal));\r
497             }\r
498         }\r
499     }\r
500 \r
501     /**\r
502      * Convert year,month,day values to the form "year/month/day".\r
503      * On input the month value is zero-based, but in the result string it is one-based.\r
504      */\r
505     static public String ymdToString(int year, int month, int isLeapMonth, int day) {\r
506         return "" + year + "/" + (month+1) +\r
507             ((isLeapMonth!=0)?"(leap)":"") +\r
508             "/" + day;\r
509     }\r
510 \r
511 //    public void TestFindLeapMonths() {\r
512 //        ChineseCalendar cal = new ChineseCalendar();\r
513 //        cal.setTime(new Date(2000-1900, Calendar.JANUARY, 1));\r
514 //        long end = new Date(2100-1900, Calendar.JANUARY, 1).getTime();\r
515 //        ChineseDateFormat fmt = (ChineseDateFormat) DateFormat.getInstance(cal);\r
516 //        fmt.applyPattern("u-MMl-dd, 'Year' y, 'Cycle' G");\r
517 //        while (cal.getTimeInMillis() < end) {\r
518 //            if (cal.get(ChineseCalendar.IS_LEAP_MONTH) != 0) {\r
519 //                cal.set(Calendar.DAY_OF_MONTH, 1);\r
520 //                logln(cal.getTime() + " = " + fmt.format(cal.getTime()));\r
521 //                cal.set(Calendar.DAY_OF_MONTH, 29);\r
522 //            }\r
523 //            cal.add(Calendar.DAY_OF_YEAR, 25);\r
524 //        }\r
525 //    }\r
526 \r
527     public void TestCoverage() {\r
528         // Coverage for constructors\r
529         {\r
530             // new ChineseCalendar(Date)\r
531             ChineseCalendar cal = new ChineseCalendar(new Date());\r
532             if(cal == null){\r
533                 errln("could not create ChineseCalendar with Date");\r
534             }\r
535         }\r
536 \r
537         {\r
538             // new ChineseCalendar(int year, int month, int isLeapMonth, int date)\r
539             ChineseCalendar cal = new ChineseCalendar(23, Calendar.JULY, 1, 2);\r
540             if(cal == null){\r
541                 errln("could not create ChineseCalendar with year,month,isLeapMonth,date");\r
542             }\r
543             // Make sure the given values are properly set\r
544             if (cal.get(Calendar.YEAR) != 23 || cal.get(Calendar.MONTH) != Calendar.JULY\r
545                     || cal.get(ChineseCalendar.IS_LEAP_MONTH) != 1 || cal.get(Calendar.DATE) != 2\r
546                     || cal.get(Calendar.MILLISECONDS_IN_DAY) != 0) {\r
547                 errln("ChineseCalendar was initialized incorrectly with year,month,isLeapMonth,date");\r
548             }\r
549         }\r
550 \r
551         {\r
552             // new ChineseCalendar(int year, int month, int isLeapMonth, int date, int hour, int minute, int second)\r
553             ChineseCalendar cal = new ChineseCalendar(23, Calendar.JULY, 1, 2, 12, 34, 56);\r
554             if(cal == null){\r
555                 errln("could not create ChineseCalendar with year,month,isLeapMonth,date,hour,minute,second");\r
556             }\r
557             // Make sure the given values are properly set\r
558             if (cal.get(Calendar.YEAR) != 23 || cal.get(Calendar.MONTH) != Calendar.JULY\r
559                     || cal.get(ChineseCalendar.IS_LEAP_MONTH) != 1 || cal.get(Calendar.DATE) != 2\r
560                     || cal.get(Calendar.HOUR_OF_DAY) != 12 || cal.get(Calendar.MINUTE) != 34\r
561                     || cal.get(Calendar.SECOND) != 56 || cal.get(Calendar.MILLISECOND) != 0) {\r
562                 errln("ChineseCalendar was initialized incorrectly with year,month,isLeapMonth,date,hour,minute,second");\r
563             }\r
564         }\r
565 \r
566         {\r
567             // new ChineseCalendar(Locale)\r
568             ChineseCalendar cal = new ChineseCalendar(Locale.getDefault());\r
569             if(cal == null){\r
570                 errln("could not create ChineseCalendar with Locale");\r
571             }\r
572         }\r
573 \r
574         {\r
575             // new ChineseCalendar(ULocale)\r
576             ChineseCalendar cal = new ChineseCalendar(ULocale.getDefault());\r
577             if(cal == null){\r
578                 errln("could not create ChineseCalendar with ULocale");\r
579             }\r
580         }\r
581         \r
582 \r
583         {\r
584             // new ChineseCalendar(TimeZone)\r
585             ChineseCalendar cal = new ChineseCalendar(TimeZone.getDefault()); \r
586             if(cal == null){\r
587                 errln("could not create ChineseCalendar with TimeZone");\r
588             }\r
589         }\r
590 \r
591         {\r
592             // new ChineseCalendar(TimeZone, Locale)\r
593             ChineseCalendar cal = new ChineseCalendar(TimeZone.getDefault(), Locale.getDefault());\r
594             if(cal == null){\r
595                 errln("could not create ChineseCalendar with TimeZone,Locale");\r
596             }\r
597         }\r
598 \r
599         {\r
600             // new ChineseCalendar(TimeZone, ULocale)\r
601             ChineseCalendar cal = new ChineseCalendar(TimeZone.getDefault(), ULocale.getDefault());\r
602             if(cal == null){\r
603                 errln("could not create ChineseCalendar with TimeZone,ULocale");\r
604             }\r
605         }\r
606 \r
607         ChineseCalendar cal = new ChineseCalendar();\r
608         DateFormat format = DateFormat.getInstance(cal);\r
609         if(!(format instanceof ChineseDateFormat)){\r
610             errln("DateFormat.getInstance("+cal+") did not return a ChineseDateFormat");\r
611         }\r
612         ChineseDateFormat fmt = (ChineseDateFormat)format;\r
613         fmt.applyPattern("llyyll");\r
614         Date time = getDate(2100, Calendar.JANUARY, 1);\r
615         String str = fmt.format(time);\r
616         try {\r
617             Date e = fmt.parse(str);\r
618             logln("chinese calendar time: " + time + " result: " + str + " --> " + e);\r
619         } catch (java.text.ParseException ex) {\r
620             logln(ex.getMessage()); // chinese calendar can't parse this, no error for now\r
621         }\r
622 \r
623         //new ChineseCalendar(TimeZone,ULocale)\r
624         ChineseCalendar ccal2 = new ChineseCalendar(TimeZone.getDefault(),\r
625                                                    ULocale.CHINA);\r
626         if(ccal2==null){\r
627             errln("could not create ChineseCalendar with TimeZone ULocale");\r
628         } else {\r
629             fmt = (ChineseDateFormat)DateFormat.getDateInstance(ccal2, DateFormat.DEFAULT, ULocale.CHINA);\r
630             time = getDate(2001, Calendar.MAY, 23);\r
631             str = fmt.format(time);\r
632             logln("Chinese calendar time: " + time + " result: " + str);\r
633         }\r
634     }\r
635     public void TestScratch(){\r
636         String[] strMonths = {"Januari", "Pebruari", "Maret", "April", "Mei", "Juni",\r
637                 "Juli", "Agustus", "September", "Oktober", "Nopember", "Desember"};\r
638         String[] strShortMonths = {"Jan", "Peb", "Mar", "Apr", "Mei", "Jun",\r
639                      "Jul", "Agt", "Sep", "Okt", "Nop", "Des"};\r
640         String[] strWeeks = {"", "Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"};\r
641         DateFormatSymbols dfsDate = new DateFormatSymbols(new Locale("id", "ID"));\r
642         dfsDate.setMonths(strMonths);\r
643         dfsDate.setShortMonths(strShortMonths);\r
644         dfsDate.setWeekdays(strWeeks);\r
645         ULocale uloInd = dfsDate.getLocale(ULocale.ACTUAL_LOCALE);\r
646         if(uloInd==null){\r
647             errln("did not get the expected ULocale");\r
648         }\r
649         logln(uloInd.toString());\r
650         Locale locInd = uloInd.toLocale();\r
651         if(locInd==null){\r
652             errln("did not get the expected result");\r
653         }\r
654         logln(locInd.toString());\r
655     }\r
656 \r
657     public void TestInitWithCurrentTime() {\r
658         // jb4555\r
659         // if the chinese calendar current millis isn't called, the default year is wrong.\r
660         // this test is assuming the 'year' is the current cycle\r
661         // so when we cross a cycle boundary, the target will need to change\r
662         // that shouldn't be for awhile yet... \r
663 \r
664         ChineseCalendar cc = new ChineseCalendar();\r
665         cc.set(Calendar.YEAR, 22);\r
666         cc.set(Calendar.MONTH, 0);\r
667          // need to set leap month flag off, otherwise, the test case always fails when\r
668          // current time is in a leap month\r
669         cc.set(ChineseCalendar.IS_LEAP_MONTH, 0);\r
670         cc.set(Calendar.DATE, 19);\r
671         cc.set(Calendar.HOUR_OF_DAY, 0);\r
672         cc.set(Calendar.MINUTE, 0);\r
673         cc.set(Calendar.SECOND, 0);\r
674         cc.set(Calendar.MILLISECOND, 0);\r
675 \r
676         cc.add(Calendar.DATE, 1);\r
677  \r
678         Calendar cal = new GregorianCalendar(2005, Calendar.FEBRUARY, 28);\r
679         Date target = cal.getTime();\r
680         Date result = cc.getTime();\r
681 \r
682         assertEquals("chinese and gregorian date should match", target, result);\r
683     }\r
684 }\r