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