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