To find the next work day
Asked Answered
S

5

6

Let's say I have stored a bunch of holidays in my database.

What I need to do is find out which is next work day excluding Saturdays and the public holidays defined in the database.

eg.

Let's say today is the Friday the 15th Feb and the 17th and the 18th are public holidays as defined in the database as datetime. So now when I press a button that says next work day, it should return 19th Feb.

Which is the most efficient way to to get it?

Stertorous answered 9/2, 2012 at 9:20 Comment(7)
I don't understand why you want to find next working day in such scenario... I believe you are not going to tell your employee that XYZ is your next working day... Just asking... if there are reason, could you please share?Peraza
Depends heavily on your database layout. By the way, this question has more to do with SQL than java, I'd say.Scheffler
@Sapan : Why tag of eclipse-rcp here?? can you explain??Peraza
@FahimParkar I didn't tag it as eclipse-rcp. stackoverflow.com/posts/9208126/revisionsNumeral
@FahimParkar - some companies have policies like 'respond to the customer within 2 working days'. Such a function would be useful then.Askwith
ohhk Hans.. Gotcha :) I thought you added as I see your name in edited... It was not there earlier... If u didn't added then its ok...Peraza
Are Sundays working days in your scenario?Stupendous
U
13

Simplest.

Step 1: Get holidays from DB and format to your format, keep it in a List<String>

Step 2: Create a method that adds day.

public static Date addDays(Date d, int days) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(d);
    cal.add(Calendar.DATE, days);
    return cal.getTime();
}

Step 3: Create a method to find holiday.

public boolean isBankHoliday(java.util.Date d) {
    Calendar c = new GregorianCalendar();
    c.setTime(d);
    if((Calendar.SATURDAY == c.get(c.DAY_OF_WEEK)) || (Calendar.SUNDAY == c.get(c.DAY_OF_WEEK)) || bankHolidays.contains(dString)) {
        return (true);
    } else {
        return false;
    }
} 

Step 4: Get your input date. Check with bank holiday, loop until you find a working day.

while (isBankHoliday(myDate)) {
    myDate = addDays(myDate, 1);
}
Undressed answered 9/2, 2012 at 9:48 Comment(2)
Where is dString declared?Truism
@vaandu shouldn't step 4 be while(isBankHoliday(myDate)) instead of while(!isBankHoliday(myDate)) (the "!" shouldn't be there), as you want to find the next working-day, not the next holiday.Marchioness
A
3

You can use DateCalculator and Joda (optional) to achieve this. In the example below the holidays are stored in a Set and the moveByBusinessDays-method is used.

import java.util.HashSet;

import junit.framework.Assert;

import net.objectlab.kit.datecalc.common.DateCalculator;
import net.objectlab.kit.datecalc.common.DefaultHolidayCalendar;
import net.objectlab.kit.datecalc.common.HolidayHandlerType;
import net.objectlab.kit.datecalc.joda.LocalDateKitCalculatorsFactory;

import org.joda.time.LocalDate;
import org.testng.annotations.BeforeSuite;
import org.testng.annotations.Test;

public class NextBusinessDayTest {

    private DateCalculator<LocalDate> dateCalculator;
    private final LocalDate startDate = new LocalDate(2012, 2, 9); // Thursday


    @BeforeSuite
    public void setUp() {
        HashSet<LocalDate> holidays = new HashSet<LocalDate>();
        holidays.add(new LocalDate(2012, 2, 10));  // Friday
        holidays.add(new LocalDate(2012, 2, 14));  // Tuesday

        DefaultHolidayCalendar<LocalDate> holidayCalendar = new DefaultHolidayCalendar<LocalDate>(holidays);

        LocalDateKitCalculatorsFactory.getDefaultInstance().registerHolidays("holidays", holidayCalendar);
        dateCalculator = LocalDateKitCalculatorsFactory.getDefaultInstance().getDateCalculator("holidays", HolidayHandlerType.FORWARD);
    }


    @Test
    public void testNextBusinessDay() {
        dateCalculator.setStartDate(startDate);
        Assert.assertEquals(dateCalculator.moveByBusinessDays(1).getCurrentBusinessDate(),
        new LocalDate(2012, 2, 13)); // skips the 10th (holiday), 11th and 12th (weekend)

        dateCalculator.setStartDate(startDate);
        Assert.assertEquals(dateCalculator.moveByBusinessDays(2).getCurrentBusinessDate(),
        new LocalDate(2012, 2, 15)); // also skips the 14th (holiday)
    }
}

EDIT:

  1. There is an alternative version of the Date calculator library, that doesn't require Joda.
  2. Check, if the library provides other functionality, that would be useful in your application. If finding the next work day is the only use case, writing the method yourself would be the better choice. Vanathi described the basic approach very well.
Agronomy answered 9/2, 2012 at 10:18 Comment(0)
S
3

Just to throw a pure SQL solution into the mixer:

DECLARE @InDate DATETIME
SET @InDate = '25/12/2011'

;WITH CTE ([Date]) AS
(   SELECT  DATEADD(DAY, 1, CAST(@InDate AS DATE)) [Date]
    UNION ALL
    SELECT  DATEADD(DAY, 1, [Date])
    FROM    CTE
    WHERE   [Date] IN (SELECT [Date] FROM YourHolidayTable)
    OR      DATENAME(WEEKDAY, [Date]) IN ('Saturday', 'Sunday')
)

SELECT  MAX([Date]) [NextWorkingDay]
FROM    CTE
Suitable answered 9/2, 2012 at 10:52 Comment(0)
O
0

I do not know whether you have built in functions in Java that can do this but in case you don't:

Off the top of my head -

Easiest would probably be to store which days are weekends as well as public holidays? Or if you have a reference point (say Jan 1st 2012) then you can store which day of the week it is then and use mod 7 arithmetic when you are calculating your new value?

Openwork answered 9/2, 2012 at 9:31 Comment(0)
D
0

Maybe this version will be useful too. Note that it uses the date-time API which was added in Java 8 which was released two years after the original question was posted.

 public static String GetNextWorkingDayDate(String baseDate, int daysAfter) {
    DateTimeFormatter f = DateTimeFormatter.ofPattern("dd/MM/yyyy");
    LocalDate date = LocalDate.parse(baseDate, f).plusDays(daysAfter);
    if (date.getDayOfWeek().equals(DayOfWeek.SATURDAY)) {
        return date.plusDays(2).format(f);
    } else if (date.getDayOfWeek().equals(DayOfWeek.SUNDAY)) {
        return date.plusDays(1).format(f);
    } else {
        return date.format(f);
    }
}
Decompose answered 10/10, 2024 at 13:26 Comment(1)
Unless I missed something, the posted question does not state that Sunday is not a work day.Typewrite

© 2022 - 2025 — McMap. All rights reserved.