ICU-11310 fix Easter holiday

Easter had a simple logic error. 
Also fix the test cases to hit the error.
Also fix the HolidayCalendarDemo to assert an issue if the error shows up
Also fix the copyright string to be dynamic.

X-SVN-Rev: 36654
This commit is contained in:
Steven R. Loomis 2014-10-09 05:19:18 +00:00
parent b2d2691724
commit b39fb3766a
4 changed files with 134 additions and 8 deletions

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1996-2013, International Business Machines Corporation and *
* Copyright (C) 1996-2014, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -37,6 +37,7 @@ import java.util.Vector;
import com.ibm.icu.dev.demo.impl.DemoApplet;
import com.ibm.icu.dev.demo.impl.DemoTextBox;
import com.ibm.icu.dev.demo.impl.DemoUtility;
import com.ibm.icu.text.DateTimePatternGenerator;
import com.ibm.icu.text.SimpleDateFormat;
import com.ibm.icu.util.Calendar;
import com.ibm.icu.util.Holiday;
@ -327,8 +328,11 @@ public class HolidayCalendarDemo extends DemoApplet
private void updateMonthName()
{
SimpleDateFormat f = new SimpleDateFormat("MMMM yyyyy",
calendarPanel.getDisplayLocale());
final Locale displayLocale = calendarPanel.getDisplayLocale();
final String pattern = DateTimePatternGenerator.
getInstance(displayLocale).getBestPattern("MMMMy");
SimpleDateFormat f = new SimpleDateFormat(pattern,
displayLocale);
f.setCalendar(calendarPanel.getCalendar());
monthLabel.setText( f.format( calendarPanel.firstOfMonth() ));
}
@ -542,6 +546,10 @@ public class HolidayCalendarDemo extends DemoApplet
Date d = fStartOfMonth;
while ( (d = fAllHolidays[h].firstBetween(d, endOfMonth) ) != null)
{
if(d.after(endOfMonth)) {
throw new InternalError("Error: for " + fAllHolidays[h].getDisplayName()+
" #" + h + "/"+fAllHolidays.length+": " + d +" is after end of month " + endOfMonth);
}
c.setTime(d);
fHolidays.addElement( new HolidayInfo(c.get(Calendar.DATE),
fAllHolidays[h],

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1997-2010, International Business Machines Corporation and *
* Copyright (C) 1997-2014, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -18,6 +18,8 @@ import java.awt.Panel;
import java.awt.TextComponent;
import java.util.Locale;
import com.ibm.icu.util.Calendar;
public class DemoUtility
{
public static final Font titleFont = new Font("TimesRoman",Font.BOLD,18);
@ -30,8 +32,11 @@ public class DemoUtility
public static final Color bgColor = Color.lightGray;
public static final Color choiceColor = Color.white;
private static final int getCurrentYear() {
return Calendar.getInstance().get(Calendar.YEAR);
}
public static final String copyright1 =
"Copyright (C) IBM Corp and others. 1997 - 2002 All Rights Reserved";
"Copyright (C) IBM Corp and others. 1997 - "+getCurrentYear()+" All Rights Reserved";
/**
Provides easy way to use basic functions of GridBagLayout, without

View File

@ -223,7 +223,7 @@ class EasterRule implements DateRule {
//System.out.println(" result = " + result.toString());
}
if (end != null && !end.before(result)) {
if (end != null && !result.before(end)) {
//System.out.println("Result after end, returning null");
return null;
}

View File

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 1996-2010, International Business Machines Corporation and *
* Copyright (C) 1996-2014, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -18,6 +18,7 @@ import com.ibm.icu.util.Holiday;
import com.ibm.icu.util.RangeDateRule;
import com.ibm.icu.util.SimpleDateRule;
import com.ibm.icu.util.SimpleHoliday;
import com.ibm.icu.util.TimeZone;
import com.ibm.icu.util.ULocale;
/**
@ -103,6 +104,10 @@ public class HolidayTest extends TestFmwk {
logln("firstBetween: " + first + " and " + now + " is " + second);
if (second == null) {
second = now;
} else {
if(second.after(now)) {
errln("Error: "+h.getDisplayName()+".firstBetween("+first+", "+now+")="+second);
}
}
logln("is on " + first + ": " + h.isOn(first));
@ -125,8 +130,97 @@ public class HolidayTest extends TestFmwk {
// logln("rule: " + h.getRule().toString());
// h.setRule(h.getRule());
logln("HolidayCalendarDemo test");
{
final Calendar c = Calendar.getInstance(TimeZone.GMT_ZONE); // Temporary copy
c.set(2014, 10, 8); // when this test was hit
final Date fStartOfMonth = startOfMonth((Calendar)c.clone());
// Stash away a few useful constants for this calendar and display
//minDay = c.getMinimum(Calendar.DAY_OF_WEEK);
//daysInWeek = c.getMaximum(Calendar.DAY_OF_WEEK) - minDay + 1;
//firstDayOfWeek = Calendar.getInstance(fDisplayLocale).getFirstDayOfWeek();
// Stash away a Date for the start of this month
// Find the day of week of the first day in this month
c.setTime(fStartOfMonth);
//firstDayInMonth = c.get(Calendar.DAY_OF_WEEK);
// Now find the # of days in the month
c.roll(Calendar.DATE, false);
final int daysInMonth = c.get(Calendar.DATE);
// Finally, find the end of the month, i.e. the start of the next one
c.roll(Calendar.DATE, true);
c.add(Calendar.MONTH, 1);
c.getTime(); // JDK 1.1.2 bug workaround
c.add(Calendar.SECOND, -1);
Date endOfMonth = c.getTime();
//
// Calculate the number of full or partial weeks in this month.
// To do this I can just reuse the code that calculates which
// calendar cell contains a given date.
//
//numWeeks = dateToCell(daysInMonth).y - dateToCell(1).y + 1;
// Remember which holidays fall on which days in this month,
// to save the trouble of having to do it later
//fHolidays.setSize(0);
int patience=100;
//for (int h = 0; h < fAllHolidays.length; h++)
{
Date d = fStartOfMonth;
while ( (d = h.firstBetween(d, endOfMonth) ) != null)
{
if(--patience <= 0) {
errln("Patience exceeded for " + h.getDisplayName() +" at " + d);
break;
}
if(d.after(endOfMonth)) {
errln("Error: for " + h.getDisplayName()+": " + d +" is after end of month " + endOfMonth);
break;
}
c.setTime(d);
logln("New date: " + d);
// fHolidays.addElement( new HolidayInfo(c.get(Calendar.DATE),
// fAllHolidays[h],
// fAllHolidays[h].getDisplayName(fDisplayLocale) ));
d.setTime( d.getTime() + 1000 ); // "d++"
}
}
// dirty = false;
}
// end HolidayDemoApplet code
}
// from HolidayCalendarDemo
private Date startOfMonth(/*Date dateInMonth,*/ Calendar fCalendar)
{
//synchronized(fCalendar) {
// fCalendar.setTime(dateInMonth); // TODO: synchronization
int era = fCalendar.get(Calendar.ERA);
int year = fCalendar.get(Calendar.YEAR);
int month = fCalendar.get(Calendar.MONTH);
fCalendar.clear();
fCalendar.set(Calendar.ERA, era);
fCalendar.set(Calendar.YEAR, year);
fCalendar.set(Calendar.MONTH, month);
fCalendar.set(Calendar.DATE, 1);
return fCalendar.getTime();
// }
}
public void TestCoverage(){
Holiday[] h = { new EasterHoliday("Ram's Easter"),
new SimpleHoliday(2, 29, 0, "Leap year", 1900, 2100)};
@ -164,6 +258,25 @@ public class HolidayTest extends TestFmwk {
}
exerciseHoliday(h[1], Locale.getDefault());
}
public void TestEaster(){
// Verify that Easter is working. Should be April 20, 2014
final Holiday h = new EasterHoliday("Easter Sunday");
final Date beginApril = getDate(2014, Calendar.APRIL, 1);
final Date endApril = getDate(2014, Calendar.APRIL, 30);
final Date expect = getDate(2014, Calendar.APRIL, 20);
final Date actual = h.firstBetween(beginApril, endApril);
if(actual == null) {
errln("Error: Easter 2014 should be on " + expect + " but got null.");
} else {
Calendar c = Calendar.getInstance(TimeZone.GMT_ZONE, Locale.US);
c.setTime(actual);
assertEquals("Easter's year: ", 2014, c.get(Calendar.YEAR));
assertEquals("Easter's month: ", Calendar.APRIL, c.get(Calendar.MONTH));
assertEquals("Easter's date: ", 20, c.get(Calendar.DATE));
}
}
public void TestIsOn() {
// jb 1901