Calculate business days in java without saturdays, sunday and public holiday

Several issues:

You are not checking if the first 3 days you skip contain weekend days.

Also you are skipping strange amounts of days and skipping for weekdays as well (which are business days and therefore should not be skipped).

I assume the method DiaFestivoDTO.obtenerDiasFestivos() calculates the number of national holidays in a certain date range but what is the start date? Is it initialized to the current date when DiaFestivoDTO is created?

When there is a national holiday in your date range you increase the date range but never check if this new daterange includes new national holidays or weekend days.

If what you are trying to do is calculate a date ‘3 business days from now’ here’s roughly what I would do:

// get all the holidays as java.util.Date
DiaFestivoDTO dia = new DiaFestivoDTO();
List<Date> holidays = dia.getAllNationalHolidays();

// get the current date without the hours, minutes, seconds and millis
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);

// iterate over the dates from now and check if each day is a business day
int businessDayCounter = 0
while (businessDayCounter < 3) {
    int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
    if (dayOfWeek != Calendar.SATURDAY && dayOfWeek != Calendar.SUNDAY && !holidays.contains(cal.getTime())) {
        businessDayCounter++;
    }
    cal.add(Calendar.DAY_OF_YEAR, 1);
}
Date threeBusinessDaysFromNow = cal.getTime();

For this to work I would advise you to add a new method ‘getAllNationalHolidays’ to list al the holidays because it is more efficient to store twelve dates in memory than to access the database multiple times to check for them.

If you cannot change/add database methods then you could do this

while (businessDayCounter < 3) {

    // determine if this day is a holiday
    DiaFestivoDTO dia = new DiaFestivoDTO();
    dia.setFechaInitial(cal.getTime());
    dia.setFechaLimite(cal.getTime());
    boolean isHoliday = seleccionPagoBO.obtenerDiasFestivos(dia) > 0;

    int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
    if (dayOfWeek != Calendar.SATURDAY && dayOfWeek != Calendar.SUNDAY && !isHoliday) {
        businessDayCounter++;
    }
    cal.add(Calendar.DAY_OF_YEAR, 1);
}

Here I assumed you can set the ‘from’ date in your DiaFestivoDTO using ‘setFechaInitial’ or something like that. But in this way you would be calling the database at least three times which is inefficient.

Leave a Comment