1 /*********************************************************************
\r
2 * Copyright (C) 2000-2010, International Business Machines Corporation and
\r
3 * others. All Rights Reserved.
\r
4 *********************************************************************
\r
6 package com.ibm.icu.dev.test.calendar;
\r
7 import java.util.Date;
\r
8 import java.util.Locale;
\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
20 * Test of ChineseCalendar.
\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
61 public class ChineseTest extends CalendarTest {
\r
63 public static void main(String args[]) throws Exception {
\r
64 new ChineseTest().run(args);
\r
68 * Test basic mapping to and from Gregorian.
\r
70 public void TestMapping() {
\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
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
91 ChineseCalendar cal = new ChineseCalendar();
\r
92 StringBuffer buf = new StringBuffer();
\r
94 logln("Gregorian -> Chinese");
\r
95 //java.util.Calendar grego = java.util.Calendar.getInstance();
\r
96 Calendar grego = Calendar.getInstance();
\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
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
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
116 errln("Fail: " + buf.toString() + ", expected " +
\r
117 yE + "/" + mE + (LE==1?"(leap)":"") + "/" + dE);
\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
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
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
142 errln("Fail: " + buf.toString() + ", expected " + dexp);
\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
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
165 greg.add(Calendar.DAY_OF_YEAR, 1);
\r
167 logln("End: " + greg.getTime());
\r
171 * Test minimum and maximum functions.
\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
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
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
190 * Run through several standard tests from Dershowitz & Reingold.
\r
192 public void TestJulianDayMapping() {
\r
194 final TestCase[] tests = {
\r
196 // From Dershowitz & Reingold, "Calendrical Calculations".
\r
198 // The months in this table are 1-based rather than 0-based.
\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
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
240 // Additional tests not from D&R
\r
241 new ChineseTestCase(2467496.5, 78, 60, 8, false, 2, FRI), // year 60
\r
244 ChineseCalendar cal = new ChineseCalendar();
\r
245 cal.setLenient(true);
\r
246 doTestCases(tests, cal);
\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
257 java.util.Calendar tempcal = java.util.Calendar.getInstance();
\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
267 for (int i=0; i<DATA.length; ++i) {
\r
268 String s = fmt.format(DATA[i]);
\r
270 Date e = fmt.parse(s);
\r
271 if (e.equals(DATA[i])) {
\r
272 logln("Ok: " + DATA[i] + " -> " + s + " -> " + e);
\r
274 errln("FAIL: " + DATA[i] + " -> " + s + " -> " + e);
\r
276 } catch (java.text.ParseException e) {
\r
277 errln("Fail: " + s + " -> parse failure at " + e.getErrorOffset());
\r
278 errln(e.toString());
\r
284 * Make sure IS_LEAP_MONTH participates in field resolution.
\r
286 public void TestResolution() {
\r
287 ChineseCalendar cal = new ChineseCalendar();
\r
288 DateFormat fmt = DateFormat.getDateInstance(cal, DateFormat.DEFAULT);
\r
290 // May 22 2001 = y4638 m4 d30 doy119
\r
291 // May 23 2001 = y4638 m4* d1 doy120
\r
293 final int THE_YEAR = 4638;
\r
294 final int END = -1;
\r
298 // (field, value)+, END, exp.month, exp.isLeapMonth, exp.DOM
\r
299 // Note: exp.month is ONE-BASED
\r
301 // If we set DAY_OF_YEAR only, that should be used
\r
302 Calendar.DAY_OF_YEAR, 1,
\r
304 1,0,1, // Expect 1-1
\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
311 4,1,1, // Expect 4*-1
\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
319 4,1,2, // Expect 4*-2
\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
331 //! 4,1,1, // Expect 4*-1
\r
333 // If we set IS_LEAP_MONTH last, that should take precedence
\r
335 Calendar.DAY_OF_MONTH, 1,
\r
336 Calendar.DAY_OF_YEAR, 5, // Should ignore
\r
337 Calendar.IS_LEAP_MONTH, 1,
\r
339 4,1,1, // Expect 4*-1
\r
342 StringBuffer buf = new StringBuffer();
\r
343 for (int i=0; i<DATA.length; ) {
\r
345 cal.set(Calendar.EXTENDED_YEAR, THE_YEAR);
\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
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
361 logln("OK: " + buf + " => " + fmt.format(cal.getTime()));
\r
363 String s = fmt.format(cal.getTime());
\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
378 * Test the behavior of fields that are out of range.
\r
380 public void TestOutOfRange() {
\r
381 int[] DATA = new int[] {
\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
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
399 cal.set(Calendar.EXTENDED_YEAR, y1);
\r
400 cal.set(MONTH, m1);
\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
417 * Test the behavior of ChineseCalendar.add(). The only real
\r
418 * nastiness with roll is the MONTH field around leap months.
\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
437 ChineseCalendar cal = new ChineseCalendar();
\r
438 doRollAdd(ADD, cal, tests);
\r
442 * Test the behavior of ChineseCalendar.roll(). The only real
\r
443 * nastiness with roll is the MONTH field around leap months.
\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
468 ChineseCalendar cal = new ChineseCalendar();
\r
469 doRollAdd(ROLL, cal, tests);
\r
472 void doRollAdd(boolean roll, ChineseCalendar cal, int[][] tests) {
\r
473 String name = roll ? "rolling" : "adding";
\r
475 for (int i = 0; i < tests.length; i++) {
\r
476 int[] test = tests[i];
\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
484 cal.roll(test[4], test[5]);
\r
486 cal.add(test[4], test[5]);
\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
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
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
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
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
529 // cal.add(Calendar.DAY_OF_YEAR, 25);
\r
533 public void TestCoverage() {
\r
534 // Coverage for constructors
\r
536 // new ChineseCalendar(Date)
\r
537 ChineseCalendar cal = new ChineseCalendar(new Date());
\r
539 errln("could not create ChineseCalendar with Date");
\r
544 // new ChineseCalendar(int year, int month, int isLeapMonth, int date)
\r
545 ChineseCalendar cal = new ChineseCalendar(23, Calendar.JULY, 1, 2);
\r
547 errln("could not create ChineseCalendar with year,month,isLeapMonth,date");
\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
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
561 errln("could not create ChineseCalendar with year,month,isLeapMonth,date,hour,minute,second");
\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
573 // new ChineseCalendar(Locale)
\r
574 ChineseCalendar cal = new ChineseCalendar(Locale.getDefault());
\r
576 errln("could not create ChineseCalendar with Locale");
\r
581 // new ChineseCalendar(ULocale)
\r
582 ChineseCalendar cal = new ChineseCalendar(ULocale.getDefault());
\r
584 errln("could not create ChineseCalendar with ULocale");
\r
590 // new ChineseCalendar(TimeZone)
\r
591 ChineseCalendar cal = new ChineseCalendar(TimeZone.getDefault());
\r
593 errln("could not create ChineseCalendar with TimeZone");
\r
598 // new ChineseCalendar(TimeZone, Locale)
\r
599 ChineseCalendar cal = new ChineseCalendar(TimeZone.getDefault(), Locale.getDefault());
\r
601 errln("could not create ChineseCalendar with TimeZone,Locale");
\r
606 // new ChineseCalendar(TimeZone, ULocale)
\r
607 ChineseCalendar cal = new ChineseCalendar(TimeZone.getDefault(), ULocale.getDefault());
\r
609 errln("could not create ChineseCalendar with TimeZone,ULocale");
\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
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
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
629 //new ChineseCalendar(TimeZone,ULocale)
\r
630 ChineseCalendar ccal2 = new ChineseCalendar(TimeZone.getDefault(),
\r
633 errln("could not create ChineseCalendar with TimeZone ULocale");
\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
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
653 errln("did not get the expected ULocale");
\r
655 logln(uloInd.toString());
\r
656 Locale locInd = uloInd.toLocale();
\r
658 errln("did not get the expected result");
\r
660 logln(locInd.toString());
\r
663 public void TestInitWithCurrentTime() {
\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
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
682 cc.add(Calendar.DATE, 1);
\r
684 Calendar cal = new GregorianCalendar(2005, Calendar.FEBRUARY, 28);
\r
685 Date target = cal.getTime();
\r
686 Date result = cc.getTime();
\r
688 assertEquals("chinese and gregorian date should match", target, result);
\r