Index: src/java/org/quartz/impl/calendar/AnnualCalendar.java =================================================================== --- src/java/org/quartz/impl/calendar/AnnualCalendar.java (revision 811) +++ src/java/org/quartz/impl/calendar/AnnualCalendar.java (working copy) @@ -152,10 +152,56 @@ return; } - excludeDays.remove(day); + removeExcludedDay(day, true); } } + + /** + * Remove the given day from the list of excluded days + * + * @param day + * @return + */ + public void removeExcludedDay(java.util.Calendar day) { + removeExcludedDay(day, false); + } + + private void removeExcludedDay(java.util.Calendar day, boolean isChecked) { + if (! isChecked && + ! isDayExcluded(day)) { + return; + } + + // Fast way, see if excact day object was already in list + if (this.excludeDays.remove(day)) { + return; + } + + int dmonth = day.get(java.util.Calendar.MONTH); + int dday = day.get(java.util.Calendar.DAY_OF_MONTH); + + // Since there is no guarentee that the given day is in the arraylist with the excact same year + // search for the object based on month and day of month in the list and remove it + Iterator iter = excludeDays.iterator(); + while (iter.hasNext()) { + java.util.Calendar cl = (java.util.Calendar) iter.next(); + if (dmonth != cl.get(java.util.Calendar.MONTH)) { + continue; + } + + if (dday != cl.get(java.util.Calendar.DAY_OF_MONTH)) { + continue; + } + + day = cl; + break; + } + + this.excludeDays.remove(day); + + } + /** *

* Determine whether the given time (in milliseconds) is 'included' by the @@ -219,12 +265,24 @@ java.util.Calendar c1 = (java.util.Calendar) arg0; java.util.Calendar c2 = (java.util.Calendar) arg1; - if(c1.before(c2)) { - return -1; - } else if(c1.after(c2)) { - return 1; - } else { - return 0; + int month1 = c1.get(java.util.Calendar.MONTH); + int month2 = c2.get(java.util.Calendar.MONTH); + + int day1 = c1.get(java.util.Calendar.DAY_OF_MONTH); + int day2 = c2.get(java.util.Calendar.DAY_OF_MONTH); + + if (month1 < month2) { + return -1; } + if (month1 > month2) { + return 1; + } + if (day1 < day2) { + return -1; + } + if (day1 > day1) { + return 1; + } + return 0; } } Index: src/test/java/org/quartz/AnnualCalendarTest.java =================================================================== --- src/test/java/org/quartz/AnnualCalendarTest.java (revision 811) +++ src/test/java/org/quartz/AnnualCalendarTest.java (working copy) @@ -90,31 +90,75 @@ AnnualCalendar annualCalendar = new AnnualCalendar(); Calendar day = Calendar.getInstance(); - day.set(Calendar.MONTH, 10); + day.set(Calendar.MONTH, 9); // Calendar.MONTH range is 0-11 ! day.set(Calendar.DAY_OF_MONTH, 15); - annualCalendar.setDayExcluded(day, false); + annualCalendar.setDayExcluded((Calendar) day.clone(), false); assertTrue("The day 15 October is not expected to be excluded but it is", !annualCalendar.isDayExcluded(day)); - day.set(Calendar.MONTH, 10); + day.set(Calendar.MONTH, 9); // Calendar.MONTH range is 0-11 ! day.set(Calendar.DAY_OF_MONTH, 15); - annualCalendar.setDayExcluded(day, true); + annualCalendar.setDayExcluded((Calendar) day.clone(), true); - day.set(Calendar.MONTH, 11); + day.set(Calendar.MONTH, 10); // Calendar.MONTH range is 0-11 ! day.set(Calendar.DAY_OF_MONTH, 12); - annualCalendar.setDayExcluded(day, true); + annualCalendar.setDayExcluded((Calendar) day.clone(), true); - day.set(Calendar.MONTH, 9); + day.set(Calendar.MONTH, 8); // Calendar.MONTH range is 0-11 ! day.set(Calendar.DAY_OF_MONTH, 1); - annualCalendar.setDayExcluded(day, true); + annualCalendar.setDayExcluded((Calendar) day.clone(), true); assertTrue("The day 15 October is expected to be excluded but it is not", annualCalendar.isDayExcluded(day)); - day.set(Calendar.MONTH, 10); + day.set(Calendar.MONTH, 9); // Calendar.MONTH range is 0-11 ! day.set(Calendar.DAY_OF_MONTH, 15); - annualCalendar.setDayExcluded(day, false); + annualCalendar.setDayExcluded((Calendar) day.clone(), false); assertTrue("The day 15 October is not expected to be excluded but it is", !annualCalendar.isDayExcluded(day)); } + + /** + * QUARTZ-679 Test if the annualCalendar works over years + */ + public void testDaysExcludedOverTime() { + AnnualCalendar annualCalendar = new AnnualCalendar(); + Calendar day = Calendar.getInstance(); + + day.set(Calendar.MONTH, Calendar.JUNE); + day.set(Calendar.YEAR, 2005); + day.set(Calendar.DAY_OF_MONTH, 23); + + annualCalendar.setDayExcluded((Calendar) day.clone(), true); + + day.set(Calendar.YEAR, 2008); + day.set(Calendar.MONTH, Calendar.FEBRUARY); + day.set(Calendar.DAY_OF_MONTH, 1); + annualCalendar.setDayExcluded((Calendar) day.clone(), true); + assertTrue("The day 1 February is expected to be excluded but it is not", annualCalendar.isDayExcluded(day)); + } + + /** + * Part 2 of the tests of QUARTZ-679 + */ + public void testRemoveInTheFuture() { + AnnualCalendar annualCalendar = new AnnualCalendar(); + Calendar day = Calendar.getInstance(); + + day.set(Calendar.MONTH, Calendar.JUNE); + day.set(Calendar.YEAR, 2005); + day.set(Calendar.DAY_OF_MONTH, 23); + + annualCalendar.setDayExcluded((Calendar) day.clone(), true); + + // Trying to remove the 23th of June + day.set(Calendar.MONTH, Calendar.JUNE); + day.set(Calendar.YEAR, 2008); + day.set(Calendar.DAY_OF_MONTH, 23); + annualCalendar.setDayExcluded((Calendar) day.clone(), false); + + assertTrue("The day 23 June is not expected to be excluded but it is", ! annualCalendar.isDayExcluded(day)); + } + } +