Here is finally the Calendar API based solution:
public enum Holidays { FRANCE { @Override protected void addFixedHolidays(Set<Holiday> holidays) { holidays.add(new Holiday(Calendar.JANUARY, 1)); holidays.add(new Holiday(Calendar.MAY, 1)); holidays.add(new Holiday(Calendar.MAY, 8)); holidays.add(new Holiday(Calendar.JULY, 14)); holidays.add(new Holiday(Calendar.AUGUST, 15)); holidays.add(new Holiday(Calendar.NOVEMBER, 1)); holidays.add(new Holiday(Calendar.NOVEMBER, 11)); holidays.add(new Holiday(Calendar.DECEMBER, 25)); } @Override protected void addVariableHolidays(int year, Set<Holiday> holidays) { Date easterSunday = getEasterSunday(year); holidays.add(new Holiday(getEasterMonday(easterSunday))); holidays.add(new Holiday(getAscensionThursday(easterSunday))); holidays.add(new Holiday(getPentecostMonday(easterSunday))); } }, ENGLAND { @Override protected void addFixedHolidays(Set<Holiday> holidays) { holidays.add(new Holiday(Calendar.JANUARY, 1)); holidays.add(new Holiday(Calendar.DECEMBER, 25)); holidays.add(new Holiday(Calendar.DECEMBER, 26)); } @Override protected void addVariableHolidays(int year, Set<Holiday> holidays) { Date easterSunday = getEasterSunday(year); holidays.add(new Holiday(getGoodFriday(easterSunday))); holidays.add(new Holiday(getEasterMonday(easterSunday))); holidays.add(new Holiday(get(WeekdayIndex.FIRST, Calendar.MONDAY, Calendar.MAY, year))); holidays.add(new Holiday(get(WeekdayIndex.LAST, Calendar.MONDAY, Calendar.MAY, year))); holidays.add(new Holiday(get(WeekdayIndex.LAST, Calendar.MONDAY, Calendar.AUGUST, year))); Holiday christmasDay = new Holiday(Calendar.DECEMBER, 25); if (christmasDay.isWeekend(year)) { holidays.add(new Holiday(Calendar.DECEMBER, 27)); } Holiday boxingDay = new Holiday(Calendar.DECEMBER, 26); if (boxingDay.isWeekend(year)) { holidays.add(new Holiday(Calendar.DECEMBER, 28)); } } }; public class HolidayException extends Exception { private static final long serialVersionUID = 1L; private HolidayException(String message) { super(message); } } private class Holiday { private final int day; private final int month; public Holiday(Date date) { Calendar calendar = Calendar.getInstance(); calendar.setTime(date); month = calendar.get(Calendar.MONTH); day = calendar.get(Calendar.DAY_OF_MONTH); } public Holiday(int month, int day) { this.month = month; this.day = day; } public Date toDate(int year) { Calendar calendar = Calendar.getInstance(); calendar.set(year, month, day); return calendar.getTime(); } public boolean isWeekend(int year) { Calendar calendar = Calendar.getInstance(); calendar.setTime(toDate(year)); int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); return dayOfWeek == Calendar.SATURDAY || dayOfWeek == Calendar.SUNDAY; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } else if (!(obj instanceof Holiday)) { return false; } else { Holiday holiday = (Holiday) obj; return holiday.month == month && holiday.day == day; } } @Override public int hashCode() { return Arrays.hashCode(new int[] { month, day }); } } public enum WeekdayIndex { FIRST(1), SECOND(2), THIRD(3), FOURTH(4), LAST(null); private final Integer index; private WeekdayIndex(Integer index) { this.index = index; } private boolean is(int count) { return index != null && index == count; } } private final Set<Holiday> fixedHolidays = new HashSet<Holiday>(); private final Map<Integer, Set<Holiday>> variableHolidays = new HashMap<Integer, Set<Holiday>>(); private Holidays() { addFixedHolidays(fixedHolidays); } protected abstract void addFixedHolidays(Set<Holiday> holidays); protected abstract void addVariableHolidays(int year, Set<Holiday> holidays); public int getBusinessDayCount(Date d1, Date d2) throws HolidayException { Calendar calendar = Calendar.getInstance(); DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); try { d1 = formatter.parse(formatter.format(d1)); d2 = formatter.parse(formatter.format(d2)); } catch (ParseException ignore) {
Call using:
Holidays.FRANCE.getBusinessDayCount(d1, d2);