2 *******************************************************************************
\r
3 * Copyright (C) 2005-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.dev.test.calendar;
\r
9 import java.util.Date;
\r
10 import java.util.Locale;
\r
12 import com.ibm.icu.impl.LocaleUtility;
\r
13 import com.ibm.icu.text.DateFormat;
\r
14 import com.ibm.icu.text.SimpleDateFormat;
\r
15 import com.ibm.icu.util.Calendar;
\r
16 import com.ibm.icu.util.CopticCalendar;
\r
17 import com.ibm.icu.util.EthiopicCalendar;
\r
18 import com.ibm.icu.util.GregorianCalendar;
\r
19 import com.ibm.icu.util.TimeZone;
\r
20 import com.ibm.icu.util.ULocale;
\r
23 * Tests for the <code>CopticCalendar</code> class.
\r
25 public class CopticTest extends CalendarTest
\r
27 public static void main(String args[]) throws Exception {
\r
28 new CopticTest().run(args);
\r
31 /** Constants to save typing. */
\r
32 public static final int TOUT = CopticCalendar.TOUT;
\r
33 public static final int BABA = CopticCalendar.BABA;
\r
34 public static final int HATOR = CopticCalendar.HATOR;
\r
35 public static final int KIAHK = CopticCalendar.KIAHK;
\r
36 public static final int TOBA = CopticCalendar.TOBA;
\r
37 public static final int AMSHIR = CopticCalendar.AMSHIR;
\r
38 public static final int BARAMHAT = CopticCalendar.BARAMHAT;
\r
39 public static final int BARAMOUDA = CopticCalendar.BARAMOUDA;
\r
40 public static final int BASHANS = CopticCalendar.BASHANS;
\r
41 public static final int PAONA = CopticCalendar.PAONA;
\r
42 public static final int EPEP = CopticCalendar.EPEP;
\r
43 public static final int MESRA = CopticCalendar.MESRA;
\r
44 public static final int NASIE = CopticCalendar.NASIE;
\r
47 * "The Amharic Letters of Emperor Theodore of Ethiopia to Queen Victoria and
\r
48 * Her Special Envoy", David Appleyard, Girma Selasse Asfaw, Oxford University Press,
\r
49 * June 1 1979, ISBN: 0856726605, Longwood Pr Ltd
\r
51 * Coptic Gregorian JD
\r
52 * 20/02/1579 29/10/1862 2401443
\r
53 * 29/10/1581 05/07/1865 2402423
\r
54 * 22/05/1582 29/01/1866 2402631
\r
55 * 10/08/1582 17/04/1866 2402709
\r
56 * 28/04/1583 05/01/1867 2402972
\r
57 * 05/05/1584 13/01/1868 2403345
\r
59 * --------------------------------------------------
\r
61 * From the Calendrica applet: http://emr.cs.iit.edu/home/reingold/calendar-book/Calendrica.html
\r
63 * Coptic Gregorian JD
\r
64 * 07/05/-284 01/01/0000 1721060
\r
65 * 08/05/-283 01/01/0001 1721426
\r
66 * 06/13/-1 29/08/0283 1824664
\r
68 * 01/01/0000 30/08/0283 1824665
\r
69 * 01/01/0001 29/08/0284 1825030
\r
70 * 01/01/0002 29/08/0285 1825395
\r
71 * 01/01/0003 29/08/0286 1825760
\r
72 * 01/01/0004 30/08/0287 1826126
\r
73 * 05/13/0000 28/08/0284 1825029
\r
74 * 05/13/0001 28/08/0285 1825394
\r
75 * 05/13/0002 28/08/0286 1825759
\r
76 * 05/13/0003 28/08/0287 1826124
\r
77 * 06/13/0003 29/08/0287 1826125 first coptic leap year
\r
78 * 05/13/0004 28/08/0288 1826490
\r
80 * 06/02/1299 13/10/1582 2299159
\r
81 * 07/02/1299 14/10/1582 2299160 Julian 04/10/1582
\r
82 * 08/02/1299 15/10/1582 2299161
\r
83 * 09/02/1299 16/10/1582 2299162
\r
85 * 23/04/1616 01/01/1900 2415021
\r
86 * 23/04/1721 01/01/2005 2453372
\r
87 * 05/13/2000 12/09/2284 2555529
\r
91 /** A huge list of test cases to make sure that computeTime and computeFields
\r
92 * work properly for a wide range of data in the civil calendar.
\r
94 public void TestCases()
\r
96 final TestCase[] tests = {
\r
98 // The months in this table are 1-based rather than 0-based,
\r
99 // because it's easier to edit that way.
\r
101 // Julian Day Era Year Month Day WkDay Hour Min Sec
\r
103 // Dates from "Emporer Theodore..."
\r
105 new TestCase(2401442.5, 1, 1579, 2, 20, WED, 0, 0, 0), // Gregorian: 20/10/1862
\r
106 new TestCase(2402422.5, 1, 1581, 10, 29, WED, 0, 0, 0), // Gregorian: 05/07/1865
\r
107 new TestCase(2402630.5, 1, 1582, 5, 22, MON, 0, 0, 0), // Gregorian: 29/01/1866
\r
108 new TestCase(2402708.5, 1, 1582, 8, 10, TUE, 0, 0, 0), // Gregorian: 17/04/1866
\r
109 new TestCase(2402971.5, 1, 1583, 4, 28, SAT, 0, 0, 0), // Gregorian: 05/01/1867
\r
110 new TestCase(2403344.5, 1, 1584, 5, 5, MON, 0, 0, 0), // Gregorian: 13/01/1868
\r
111 new TestCase(1721059.5, 0, 285, 5, 7, SAT, 0, 0, 0), // Gregorian: 01/01/0000
\r
112 new TestCase(1721425.5, 0, 284, 5, 8, MON, 0, 0, 0), // Gregorian: 01/01/0001
\r
113 new TestCase(1824663.5, 0, 2, 13, 6, WED, 0, 0, 0), // Gregorian: 29/08/0283
\r
114 new TestCase(1824664.5, 0, 1, 1, 1, THU, 0, 0, 0), // Gregorian: 30/08/0283
\r
115 new TestCase(1825029.5, 1, 1, 1, 1, FRI, 0, 0, 0), // Gregorian: 29/08/0284
\r
116 new TestCase(1825394.5, 1, 2, 1, 1, SAT, 0, 0, 0), // Gregorian: 29/08/0285
\r
117 new TestCase(1825759.5, 1, 3, 1, 1, SUN, 0, 0, 0), // Gregorian: 29/08/0286
\r
118 new TestCase(1826125.5, 1, 4, 1, 1, TUE, 0, 0, 0), // Gregorian: 30/08/0287
\r
119 new TestCase(1825028.5, 0, 1, 13, 5, THU, 0, 0, 0), // Gregorian: 28/08/0284
\r
120 new TestCase(1825393.5, 1, 1, 13, 5, FRI, 0, 0, 0), // Gregorian: 28/08/0285
\r
121 new TestCase(1825758.5, 1, 2, 13, 5, SAT, 0, 0, 0), // Gregorian: 28/08/0286
\r
122 new TestCase(1826123.5, 1, 3, 13, 5, SUN, 0, 0, 0), // Gregorian: 28/08/0287
\r
123 new TestCase(1826124.5, 1, 3, 13, 6, MON, 0, 0, 0), // Gregorian: 29/08/0287
\r
124 // above is first coptic leap year
\r
125 new TestCase(1826489.5, 1, 4, 13, 5, TUE, 0, 0, 0), // Gregorian: 28/08/0288
\r
126 new TestCase(2299158.5, 1, 1299, 2, 6, WED, 0, 0, 0), // Gregorian: 13/10/1582
\r
127 new TestCase(2299159.5, 1, 1299, 2, 7, THU, 0, 0, 0), // Gregorian: 14/10/1582
\r
129 new TestCase(2299160.5, 1, 1299, 2, 8, FRI, 0, 0, 0), // Gregorian: 15/10/1582
\r
130 new TestCase(2299161.5, 1, 1299, 2, 9, SAT, 0, 0, 0), // Gregorian: 16/10/1582
\r
132 new TestCase(2415020.5, 1, 1616, 4, 23, MON, 0, 0, 0), // Gregorian: 01/01/1900
\r
133 new TestCase(2453371.5, 1, 1721, 4, 23, SAT, 0, 0, 0), // Gregorian: 01/01/2005
\r
134 new TestCase(2555528.5, 1, 2000, 13, 5, FRI, 0, 0, 0), // Gregorian: 12/09/2284
\r
137 CopticCalendar testCalendar = new CopticCalendar();
\r
138 testCalendar.setLenient(true);
\r
139 doTestCases(tests, testCalendar);
\r
142 // basic sanity check that the conversion algorithm round-trips
\r
143 public void TestCopticToJD() {
\r
144 CopticCalendar cal = new CopticCalendar();
\r
146 for (int y = -2; y < 3; ++y) {
\r
147 for (int m = 0; m < 12; ++m) { // don't understand rules for 13th month
\r
148 for (int d = 1; d < 25; d += 3) { // play it safe on days per month
\r
149 int jd = CopticCalendar.copticToJD(y, m, d);
\r
150 cal.set(Calendar.JULIAN_DAY, jd);
\r
151 int eyear = cal.get(Calendar.EXTENDED_YEAR);
\r
152 int month = cal.get(Calendar.MONTH);
\r
153 int day = cal.get(Calendar.DAY_OF_MONTH);
\r
154 if (!(y == eyear &&
\r
161 " --> y: " + eyear +
\r
170 // basic check to see that we print out eras ok
\r
171 // eventually should modify to use locale strings and formatter appropriate to coptic calendar
\r
172 public void TestEraStart() {
\r
173 SimpleDateFormat fmt = new SimpleDateFormat("EEE MMM dd, yyyy GG");
\r
174 SimpleDateFormat copticFmt = new SimpleDateFormat("EEE MMM dd, yyyy GG");
\r
175 copticFmt.setCalendar(new CopticCalendar());
\r
177 CopticCalendar cal = new CopticCalendar(1, 0, 1);
\r
178 assertEquals("Coptic Date", "Fri Jan 01, 0001 AD", copticFmt.format(cal));
\r
179 assertEquals("Gregorian Date", "Fri Aug 29, 0284 AD", fmt.format(cal.getTime()));
\r
181 cal.set(Calendar.ERA, 0);
\r
182 cal.set(Calendar.YEAR, 1);
\r
183 assertEquals("Coptic Date", "Thu Jan 01, 0001 BC", copticFmt.format(cal));
\r
184 assertEquals("Gregorian Date", "Thu Aug 30, 0283 AD", fmt.format(cal.getTime()));
\r
187 public void TestBasic() {
\r
188 CopticCalendar cal = new CopticCalendar();
\r
190 cal.set(1000, 0, 30);
\r
191 logln("1000/0/30-> " +
\r
192 cal.get(YEAR) + "/" +
\r
193 cal.get(MONTH) + "/" +
\r
197 logln("1/0/30 -> " +
\r
198 cal.get(YEAR) + "/" +
\r
199 cal.get(MONTH) + "/" +
\r
204 * Test limits of the Coptic calendar
\r
206 public void TestLimits() {
\r
207 Calendar cal = Calendar.getInstance();
\r
208 cal.set(2007, Calendar.JANUARY, 1);
\r
209 CopticCalendar coptic = new CopticCalendar();
\r
210 doLimitsTest(coptic, null, cal.getTime());
\r
211 doTheoreticalLimitsTest(coptic, true);
\r
215 * Test for track ticket 6379 - proper reporting of
\r
216 * maximum month lengths
\r
218 public void Test6379()
\r
220 CopticCalendar copticCal = new CopticCalendar();
\r
223 for (int year = 1725; year < 1735; year++) { // Coptic 1725-01-01 = Gregorian 2008-09-11
\r
224 boolean isLeap = ((year % 4) == 3);
\r
225 copticCal.set(Calendar.YEAR, year);
\r
227 int maxMonth = copticCal.getActualMaximum(Calendar.MONTH);
\r
229 for (int month = 0; month <= maxMonth; month++) {
\r
230 copticCal.set(Calendar.MONTH, month);
\r
231 int maxDayOfMonth = copticCal.getActualMaximum(Calendar.DAY_OF_MONTH);
\r
233 int expected = (month != maxMonth) ? 30 : (isLeap ? 6 : 5);
\r
234 if (maxDayOfMonth != expected) {
\r
235 errln("FAIL: Expected maximum " + expected + " days for month #"
\r
236 + (month + 1) + " - returned:" + maxDayOfMonth);
\r
242 public void TestCoverage() {
\r
245 // new CopticCalendar(TimeZone)
\r
246 CopticCalendar cal = new CopticCalendar(TimeZone.getDefault());
\r
248 errln("could not create CopticCalendar with TimeZone");
\r
253 // new CopticCalendar(ULocale)
\r
254 CopticCalendar cal = new CopticCalendar(ULocale.getDefault());
\r
256 errln("could not create CopticCalendar with ULocale");
\r
261 // new CopticCalendar(Locale)
\r
262 CopticCalendar cal = new CopticCalendar(Locale.getDefault());
\r
264 errln("could not create CopticCalendar with Locale");
\r
269 // new CopticCalendar(TimeZone, Locale)
\r
270 CopticCalendar cal = new CopticCalendar(TimeZone.getDefault(),Locale.getDefault());
\r
272 errln("could not create CopticCalendar with TimeZone, Locale");
\r
277 // new CopticCalendar(TimeZone, ULocale)
\r
278 CopticCalendar cal = new CopticCalendar(TimeZone.getDefault(),ULocale.getDefault());
\r
280 errln("could not create CopticCalendar with TimeZone, ULocale");
\r
285 // new CopticCalendar(Date)
\r
286 CopticCalendar cal = new CopticCalendar(new Date());
\r
288 errln("could not create CopticCalendar with Date");
\r
293 // new CopticCalendar(int year, int month, int date)
\r
294 CopticCalendar cal = new CopticCalendar(1997, CopticCalendar.TOUT, 1);
\r
296 errln("could not create CopticCalendar with year,month,date");
\r
301 // new CopticCalendar(int year, int month, int date, int hour, int minute, int second)
\r
302 CopticCalendar cal = new CopticCalendar(1997, CopticCalendar.TOUT, 1, 1, 1, 1);
\r
304 errln("could not create CopticCalendar with year,month,date,hour,minute,second");
\r
310 CopticCalendar cal = new CopticCalendar(1997, CopticCalendar.TOUT, 1);
\r
311 Date time = cal.getTime();
\r
313 String[] calendarLocales = {
\r
314 "am_ET", "gez_ET", "ti_ET"
\r
317 String[] formatLocales = {
\r
318 "en", "am", "am_ET", "gez", "ti"
\r
320 for (int i = 0; i < calendarLocales.length; ++i) {
\r
321 String calLocName = calendarLocales[i];
\r
322 Locale calLocale = LocaleUtility.getLocaleFromName(calLocName);
\r
323 cal = new CopticCalendar(calLocale);
\r
325 for (int j = 0; j < formatLocales.length; ++j) {
\r
326 String locName = formatLocales[j];
\r
327 Locale formatLocale = LocaleUtility.getLocaleFromName(locName);
\r
328 DateFormat format = DateFormat.getDateTimeInstance(cal, DateFormat.FULL, DateFormat.FULL, formatLocale);
\r
329 logln(calLocName + "/" + locName + " --> " + format.format(time));
\r
335 public void TestYear() {
\r
336 // Gregorian Calendar
\r
337 Calendar gCal= new GregorianCalendar();
\r
338 Date gToday=gCal.getTime();
\r
339 gCal.add(GregorianCalendar.MONTH,2);
\r
340 Date gFuture=gCal.getTime();
\r
341 DateFormat gDF = DateFormat.getDateInstance(gCal,DateFormat.FULL);
\r
342 logln("gregorian calendar: " + gDF.format(gToday) +
\r
343 " + 2 months = " + gDF.format(gFuture));
\r
346 CopticCalendar cCal= new CopticCalendar();
\r
347 Date cToday=cCal.getTime();
\r
348 cCal.add(CopticCalendar.MONTH,2);
\r
349 Date cFuture=cCal.getTime();
\r
350 DateFormat cDF = DateFormat.getDateInstance(cCal,DateFormat.FULL);
\r
351 logln("coptic calendar: " + cDF.format(cToday) +
\r
352 " + 2 months = " + cDF.format(cFuture));
\r
354 // EthiopicCalendar
\r
355 EthiopicCalendar eCal= new EthiopicCalendar();
\r
356 Date eToday=eCal.getTime();
\r
357 eCal.add(EthiopicCalendar.MONTH,2); // add 2 months
\r
358 eCal.setAmeteAlemEra(false);
\r
359 Date eFuture=eCal.getTime();
\r
360 DateFormat eDF = DateFormat.getDateInstance(eCal,DateFormat.FULL);
\r
361 logln("ethiopic calendar: " + eDF.format(eToday) +
\r
362 " + 2 months = " + eDF.format(eFuture));
\r
365 public void TestAddSet() {
\r
366 class TestAddSetItem {
\r
367 private int startYear;
\r
368 private int startMonth; // 0-based
\r
369 private int startDay; // 1-based
\r
370 private int fieldToChange;
\r
371 private int fieldDelta;
\r
372 private int endYear;
\r
373 private int endMonth;
\r
374 private int endDay;
\r
375 TestAddSetItem(int sYr, int sMo, int sDa, int field, int delta, int eYr, int eMo, int eDa) {
\r
379 fieldToChange = field;
\r
380 fieldDelta = delta;
\r
385 public int getStartYear() { return startYear; }
\r
386 public int getStartMonth() { return startMonth; }
\r
387 public int getStartDay() { return startDay; }
\r
388 public int getField() { return fieldToChange; }
\r
389 public int getDelta() { return fieldDelta; }
\r
390 public int getEndYear() { return endYear; }
\r
391 public int getEndMonth() { return endMonth; }
\r
392 public int getEndDay() { return endDay; }
\r
394 final TestAddSetItem[] tests = {
\r
395 new TestAddSetItem( 1724, 12, 1, Calendar.MONTH, +1, 1725, 0, 1 ),
\r
396 new TestAddSetItem( 1724, 12, 1, Calendar.MONTH, +9, 1725, 8, 1 ),
\r
397 new TestAddSetItem( 1723, 12, 2, Calendar.MONTH, +1, 1724, 0, 2 ), // 1723 is a leap year
\r
398 new TestAddSetItem( 1723, 12, 2, Calendar.MONTH, +9, 1724, 8, 2 ),
\r
399 new TestAddSetItem( 1725, 0, 1, Calendar.MONTH, -1, 1724, 12, 1 ),
\r
400 new TestAddSetItem( 1725, 0, 1, Calendar.MONTH, -6, 1724, 7, 1 ),
\r
401 new TestAddSetItem( 1724, 12, 1, Calendar.DATE, +8, 1725, 0, 4 ),
\r
402 new TestAddSetItem( 1723, 12, 1, Calendar.DATE, +8, 1724, 0, 3 ), // 1723 is a leap year
\r
403 new TestAddSetItem( 1724, 0, 1, Calendar.DATE, -1, 1723, 12, 6 ),
\r
405 CopticCalendar testCalendar = new CopticCalendar();
\r
406 for ( int i = 0; i < tests.length; i++ ) {
\r
407 TestAddSetItem item = tests[i];
\r
408 testCalendar.set( item.getStartYear(), item.getStartMonth(), item.getStartDay(), 9, 0 );
\r
409 testCalendar.add( item.getField(), item.getDelta() );
\r
410 int endYear = testCalendar.get(Calendar.YEAR);
\r
411 int endMonth = testCalendar.get(Calendar.MONTH);
\r
412 int endDay = testCalendar.get(Calendar.DATE);
\r
413 if ( endYear != item.getEndYear() || endMonth != item.getEndMonth() || endDay != item.getEndDay() ) {
\r
414 errln("CToJD FAILS: field " + item.getField() + " delta " + item.getDelta() +
\r
415 " expected yr " + item.getEndYear() + " mo " + item.getEndMonth() + " da " + item.getEndDay() +
\r
416 " got yr " + endYear + " mo " + endMonth + " da " + endDay);
\r