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