Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
617 views
in Technique[技术] by (71.8m points)

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

i have a table in oracle where I saved the twelve public days in Mexico and I need to calculate a limit day since you registered

public Date calcularFechaLimite() {
    try {
        DiaFestivoDTO dia = new DiaFestivoDTO();

        // Calendar fechaActual = Calendar.getInstance();
        Calendar fechaL = Calendar.getInstance();
        fechaL.add(Calendar.DATE, 3);

        switch (fechaL.get(Calendar.DAY_OF_WEEK)) {
        case Calendar.SATURDAY:
            fechaL.add(Calendar.DATE, 2);
            break;
        case Calendar.SUNDAY:
            fechaL.add(Calendar.DATE, 2);
            break;
        case Calendar.MONDAY:
            fechaL.add(Calendar.DATE, 2);
            break;
        case Calendar.TUESDAY:
            fechaL.add(Calendar.DATE, 1);
        default:
            break;
        }
        dia.setFechaLimite(fechaL.getTime());
        Integer numeroDiasFest = seleccionPagoBO.obtenerDiasFestivos(dia);
        if (numeroDiasFest != 0) {
            fechaL.add(Calendar.DATE, numeroDiasFest);
            dia.setFechaLimite(fechaL.getTime());
        }

        fechaLimite = fechaL.getTime();
    } catch (Exception e) {
        e.printStackTrace();
    }

    return fechaLimite;

}

This is what i have but March 28 and 29 are public days and it is not working, any idea??

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...