0

I am trying to add business days to a date using an invocable method. I cannot use the formula method as I need to take into account holidays as well as weekends.

 public static Date addBussinessDays(Date startDate, Integer iDays)
    {
        Date endDate = startDate.addDays(iDays);
        Integer iOffDays = daysOff(startDate, endDate);
        return endDate.addDays(iOffDays);
    }

    public static Integer daysOff(DateTime sdate, DateTime edate)
    {
        Integer iCount = 0;
        while (sdate < edate) {
            Date d = date.newInstance(sdate.year(), sdate.month(),sdate.day());
            if ((sdate.format('E') == 'Sat' | sdate.format('E') == 'Sun') | checkifItisWorkingDay(d)) {
                iCount = iCount + 1;
            }
            sdate = sdate.addDays(1);
        }
        return iCount;
    }

    public static boolean checkifItisWorkingDay(Date currentDate){
        List<Holiday> holidays=[Select h.StartTimeInMinutes, h.Name, h.ActivityDate From Holiday h];

        Date weekStart  = currentDate.toStartofWeek();
        for(Holiday hDay:holidays){
            if(currentDate.daysBetween(hDay.ActivityDate) == 0){
                return false;
            }
        }
        if(weekStart.daysBetween(currentDate) ==0 || weekStart.daysBetween(currentDate) == 6){
            return false;
        } else 
            return true;

    } 

My codes just doesn't seam to work, but I cannot see what I am doing wrong.

  • check the value of iDays and iOffDays. May be one of them is negative. – Tushar Sharma Jun 29 '16 at 9:45
2

** updated the answer after comments **

The mechanism of adding 'extra days' to the starting day does not guarantee that you end up on a non-working day. Instead of that you will need to loop through all days one by one, check if they're working days, and if not, continue the loop without adding anything.

Also you are currently doing query (for holidays) in a loop. This can be optimized to prevent Governor Limit errors when calculating with more than 100 days.

The code could look like this:

public static Date addBussinessDays(Date startDate, Integer iDays)
{
    Integer businessDaysAdded = 0;
    Date currentDate = startDate;
    while (businessDaysAdded < iDays) {
        currentDate = currentDate.addDays(1);
        Datetime d = datetime.newInstance(currentDate.year(), currentDate.month(),currentDate.day());

        if (d.format('E') != 'Sat' && d.format('E') != 'Sun' && checkifItisWorkingDay(currentDate)) {
            // it's a business day, so add 1 to the counter that works towards the amount of days to add
            businessDaysAdded = businessDaysAdded + 1;
        } 
    }       
    return currentDate;
}

public static List<Holiday> holidays {
    get {
        if(holidays == null)
            holidays=[Select h.StartTimeInMinutes, h.Name, h.ActivityDate From Holiday h];
        return holidays;
    }
    private set;
}

public static boolean checkifItisWorkingDay(Date currentDate){
    Date weekStart  = currentDate.toStartofWeek();
    for(Holiday hDay:holidays){
        if(currentDate.daysBetween(hDay.ActivityDate) == 0){
            return false;
        }
    }
    if(weekStart.daysBetween(currentDate) ==0 || weekStart.daysBetween(currentDate) == 6){
        return false;
    } else 
        return true;
} 
  • Thanks @guy I have changed my method name, and added the negative check. The code still returns an end date of Saturday if you set the Start Date as a Friday. It should return and end date of the Monday, as that is the next working day – developer__c Jun 29 '16 at 10:26
  • Yes, the mechanism of adding 'extra days' to the starting day does not guarantee that you end up on a non-working day. Instead of that you will need to loop through all days one by one, check if they're working days, and if not, continue the loop without adding anything. I will update my answer with an example. – Guy Clairbois Jun 29 '16 at 11:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.