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