1/* GENERATED SOURCE. DO NOT MODIFY. */
2// © 2016 and later: Unicode, Inc. and others.
3// License & terms of use: http://www.unicode.org/copyright.html#License
4/*
5 *******************************************************************************
6 * Copyright (C) 1996-2014, International Business Machines Corporation and    *
7 * others. All Rights Reserved.                                                *
8 *******************************************************************************
9 */
10package android.icu.dev.test.calendar;
11
12import java.util.Date;
13import java.util.Locale;
14
15import org.junit.Before;
16import org.junit.Test;
17import org.junit.runner.RunWith;
18import org.junit.runners.JUnit4;
19
20import android.icu.dev.test.TestFmwk;
21import android.icu.impl.LocaleUtility;
22import android.icu.util.Calendar;
23import android.icu.util.EasterHoliday;
24import android.icu.util.GregorianCalendar;
25import android.icu.util.Holiday;
26import android.icu.util.RangeDateRule;
27import android.icu.util.SimpleDateRule;
28import android.icu.util.SimpleHoliday;
29import android.icu.util.TimeZone;
30import android.icu.util.ULocale;
31import android.icu.testsharding.MainTestShard;
32
33/**
34 * Tests for the <code>Holiday</code> class.
35 */
36@MainTestShard
37@RunWith(JUnit4.class)
38public class HolidayTest extends TestFmwk {
39    @Before
40    public void init() throws Exception {
41        if(cal==null){
42            cal = new GregorianCalendar(1, 0, 1);
43            longTimeAgo = cal.getTime();
44            now = new Date();
45        }
46    }
47
48    private Calendar cal;
49    private Date longTimeAgo;
50    private Date now;
51    private static long awhile = 3600L * 24 * 28; // 28 days
52
53    @Test
54    public void TestAPI() {
55        {
56            // getHolidays
57            Holiday[] holidays = Holiday.getHolidays();
58            exerciseHolidays(holidays, Locale.getDefault());
59        }
60
61        {
62            // getHolidays(Locale)
63            String[] localeNames =
64            {
65                "en_US",
66                "da",
67                "da_DK",
68                "de",
69                "de_AT",
70                "de_DE",
71                "el",
72                "el_GR",
73                "en",
74                "en_CA",
75                "en_GB",
76                "es",
77                "es_MX",
78                "fr",
79                "fr_CA",
80                "fr_FR",
81                "it",
82                "it_IT",
83                "iw",
84                "iw_IL",
85                "ja",
86                "ja_JP",
87            };
88
89            for (int i = 0; i < localeNames.length; ++i) {
90                Locale locale = LocaleUtility.getLocaleFromName(localeNames[i]);
91                Holiday[] holidays = Holiday.getHolidays(locale);
92                exerciseHolidays(holidays, locale);
93            }
94        }
95    }
96
97    void exerciseHolidays(Holiday[] holidays, Locale locale) {
98        for (int i = 0; i < holidays.length; ++i) {
99            exerciseHoliday(holidays[i], locale);
100        }
101    }
102
103    void exerciseHoliday(Holiday h, Locale locale) {
104        logln("holiday: " + h.getDisplayName());
105        logln("holiday in " + locale + ": " + h.getDisplayName(locale));
106
107        Date first = h.firstAfter(longTimeAgo);
108        logln("firstAfter: " + longTimeAgo + " is " + first);
109        if (first == null) {
110            first = longTimeAgo;
111        }
112        first.setTime(first.getTime() + awhile);
113
114        Date second = h.firstBetween(first, now);
115        logln("firstBetween: " + first + " and " + now + " is " + second);
116        if (second == null) {
117            second = now;
118        } else {
119            if(second.after(now)) {
120                errln("Error: "+h.getDisplayName()+".firstBetween("+first+", "+now+")="+second);
121            }
122        }
123
124        logln("is on " + first + ": " + h.isOn(first));
125        logln("is on " + now + ": " + h.isOn(now));
126        logln(
127              "is between "
128              + first
129              + " and "
130              + now
131              + ": "
132              + h.isBetween(first, now));
133        logln(
134              "is between "
135              + first
136              + " and "
137              + second
138              + ": "
139              + h.isBetween(first, second));
140
141        //        logln("rule: " + h.getRule().toString());
142
143        //        h.setRule(h.getRule());
144
145
146        logln("HolidayCalendarDemo test");
147        {
148            final Calendar c = Calendar.getInstance(TimeZone.GMT_ZONE); // Temporary copy
149            c.set(2014, 10, 8); // when this test was hit
150            final Date fStartOfMonth = startOfMonth((Calendar)c.clone());
151
152            // Stash away a few useful constants for this calendar and display
153            //minDay = c.getMinimum(Calendar.DAY_OF_WEEK);
154            //daysInWeek = c.getMaximum(Calendar.DAY_OF_WEEK) - minDay + 1;
155
156            //firstDayOfWeek = Calendar.getInstance(fDisplayLocale).getFirstDayOfWeek();
157
158            // Stash away a Date for the start of this month
159
160            // Find the day of week of the first day in this month
161            c.setTime(fStartOfMonth);
162            //firstDayInMonth = c.get(Calendar.DAY_OF_WEEK);
163
164            // Now find the # of days in the month
165            c.roll(Calendar.DATE, false);
166            // final int daysInMonth = c.get(Calendar.DATE);
167
168            // Finally, find the end of the month, i.e. the start of the next one
169            c.roll(Calendar.DATE, true);
170            c.add(Calendar.MONTH, 1);
171            c.getTime();        // JDK 1.1.2 bug workaround
172            c.add(Calendar.SECOND, -1);
173            Date endOfMonth = c.getTime();
174
175            //
176            // Calculate the number of full or partial weeks in this month.
177            // To do this I can just reuse the code that calculates which
178            // calendar cell contains a given date.
179            //
180            //numWeeks = dateToCell(daysInMonth).y - dateToCell(1).y + 1;
181
182            // Remember which holidays fall on which days in this month,
183            // to save the trouble of having to do it later
184            //fHolidays.setSize(0);
185            int patience=100;
186
187            //for (int h = 0; h < fAllHolidays.length; h++)
188            {
189                Date d = fStartOfMonth;
190                while ( (d = h.firstBetween(d, endOfMonth) ) != null)
191                {
192                    if(--patience <= 0) {
193                        errln("Patience exceeded for " + h.getDisplayName() +" at " + d);
194                        break;
195                    }
196                    if(d.after(endOfMonth)) {
197                        errln("Error: for " + h.getDisplayName()+": " + d +" is after end of month " + endOfMonth);
198                        break;
199                    }
200                    c.setTime(d);
201                    logln("New date: " + d);
202//                    fHolidays.addElement( new HolidayInfo(c.get(Calendar.DATE),
203//                                            fAllHolidays[h],
204//                                            fAllHolidays[h].getDisplayName(fDisplayLocale) ));
205
206                    d.setTime( d.getTime() + 1000 );    // "d++"
207                }
208            }
209//            dirty = false;
210        }
211        // end HolidayDemoApplet code
212
213    }
214
215    // from HolidayCalendarDemo
216    private Date startOfMonth(/*Date dateInMonth,*/ Calendar fCalendar)
217    {
218        //synchronized(fCalendar) {
219        //    fCalendar.setTime(dateInMonth);             // TODO: synchronization
220
221            int era = fCalendar.get(Calendar.ERA);
222            int year = fCalendar.get(Calendar.YEAR);
223            int month = fCalendar.get(Calendar.MONTH);
224
225            fCalendar.clear();
226            fCalendar.set(Calendar.ERA, era);
227            fCalendar.set(Calendar.YEAR, year);
228            fCalendar.set(Calendar.MONTH, month);
229            fCalendar.set(Calendar.DATE, 1);
230
231            return fCalendar.getTime();
232       // }
233    }
234
235    @Test
236    public void TestCoverage(){
237        Holiday[] h = { new EasterHoliday("Ram's Easter"),
238                        new SimpleHoliday(2, 29, 0, "Leap year", 1900, 2100)};
239        exerciseHolidays(h, Locale.getDefault());
240
241        RangeDateRule rdr = new RangeDateRule();
242        rdr.add(new SimpleDateRule(7, 10));
243        Date mbd = getDate(1953, Calendar.JULY, 10);
244        Date dbd = getDate(1958, Calendar.AUGUST, 15);
245        Date nbd = getDate(1990, Calendar.DECEMBER, 17);
246        Date abd = getDate(1992, Calendar.SEPTEMBER, 16);
247        Date xbd = getDate(1976, Calendar.JULY, 4);
248        Date ybd = getDate(2003, Calendar.DECEMBER, 8);
249        rdr.add(new SimpleDateRule(Calendar.JULY, 10, Calendar.MONDAY, false));
250        rdr.add(dbd, new SimpleDateRule(Calendar.AUGUST, 15, Calendar.WEDNESDAY, true));
251        rdr.add(xbd, null);
252        rdr.add(nbd, new SimpleDateRule(Calendar.DECEMBER, 17, Calendar.MONDAY, false));
253        rdr.add(ybd, null);
254
255        logln("first after " + mbd + " is " + rdr.firstAfter(mbd));
256        logln("first between " + mbd + " and " + dbd + " is " + rdr.firstBetween(mbd, dbd));
257        logln("first between " + dbd + " and " + nbd + " is " + rdr.firstBetween(dbd, nbd));
258        logln("first between " + nbd + " and " + abd + " is " + rdr.firstBetween(nbd, abd));
259        logln("first between " + abd + " and " + xbd + " is " + rdr.firstBetween(abd, xbd));
260        logln("first between " + abd + " and " + null + " is " + rdr.firstBetween(abd, null));
261        logln("first between " + xbd + " and " + null + " is " + rdr.firstBetween(xbd, null));
262
263        //getRule, setRule
264        logln("The rule in the holiday: " + h[1].getRule());
265        exerciseHoliday(h[1], Locale.getDefault());
266        h[1].setRule(rdr);
267        logln("Set the new rule to the SimpleHoliday ...");
268        if (!rdr.equals(h[1].getRule())) {
269            errln("FAIL: getRule and setRule not matched.");
270        }
271        exerciseHoliday(h[1], Locale.getDefault());
272    }
273
274    @Test
275    public void TestEaster(){
276        // Verify that Easter is working. Should be April 20, 2014
277        final Holiday h = new EasterHoliday("Easter Sunday");
278        final Date beginApril = getDate(2014, Calendar.APRIL, 1);
279        final Date endApril   = getDate(2014, Calendar.APRIL, 30);
280        final Date expect     = getDate(2014, Calendar.APRIL, 20);
281        final Date actual     = h.firstBetween(beginApril, endApril);
282
283        if(actual == null) {
284            errln("Error: Easter 2014 should be on " + expect + " but got null.");
285        } else {
286            Calendar c = Calendar.getInstance(TimeZone.GMT_ZONE, Locale.US);
287            c.setTime(actual);
288            assertEquals("Easter's year:  ", 2014, c.get(Calendar.YEAR));
289            assertEquals("Easter's month: ", Calendar.APRIL, c.get(Calendar.MONTH));
290            assertEquals("Easter's date:  ", 20, c.get(Calendar.DATE));
291        }
292    }
293
294    @Test
295    public void TestIsOn() {
296        // jb 1901
297        SimpleHoliday sh = new SimpleHoliday(Calendar.AUGUST, 15, "Doug's Day", 1958, 2058);
298
299        Calendar gcal = new GregorianCalendar();
300        gcal.clear();
301        gcal.set(Calendar.YEAR, 2000);
302        gcal.set(Calendar.MONTH, Calendar.AUGUST);
303        gcal.set(Calendar.DAY_OF_MONTH, 15);
304
305        Date d0 = gcal.getTime();
306        gcal.add(Calendar.SECOND, 1);
307        Date d1 = gcal.getTime();
308        gcal.add(Calendar.SECOND, -2);
309        Date d2 = gcal.getTime();
310        gcal.add(Calendar.DAY_OF_MONTH, 1);
311        Date d3 = gcal.getTime();
312        gcal.add(Calendar.SECOND, 1);
313        Date d4 = gcal.getTime();
314        gcal.add(Calendar.SECOND, -2);
315        gcal.set(Calendar.YEAR, 1957);
316        Date d5 = gcal.getTime();
317        gcal.set(Calendar.YEAR, 1958);
318        Date d6 = gcal.getTime();
319        gcal.set(Calendar.YEAR, 2058);
320        Date d7 = gcal.getTime();
321        gcal.set(Calendar.YEAR, 2059);
322        Date d8 = gcal.getTime();
323
324        Date[] dates = { d0, d1, d2, d3, d4, d5, d6, d7, d8 };
325        boolean[] isOns = { true, true, false, true, false, false, true, true, false };
326        for (int i = 0; i < dates.length; ++i) {
327            Date d = dates[i];
328            logln("\ndate: " + d);
329            boolean isOn = sh.isOn(d);
330            logln("isOnDate: " + isOn);
331            if (isOn != isOns[i]) {
332                errln("date: " + d + " should be on Doug's Day!");
333            }
334            Date h = sh.firstAfter(d);
335            logln("firstAfter: " + h);
336        }
337    }
338
339    @Test
340    public void TestDisplayName() {
341        Holiday[] holidays = Holiday.getHolidays(ULocale.US);
342        for (int i = 0; i < holidays.length; ++i) {
343            Holiday h = holidays[i];
344            // only need to test one
345            // if the display names differ, we're using our data.  We know these names
346            // should differ for this holiday (not all will).
347            if ("Christmas".equals(h.getDisplayName(ULocale.US))) {
348                if ("Christmas".equals(h.getDisplayName(ULocale.GERMANY))) {
349                    errln("Using default name for holidays");
350                }
351            }
352        }
353    }
354}
355