Business Days – The Missing Salesforce Function

Developer Samruddhi Patil recently asked the Twitter community about calculating business days in Salesforce. For example, if a case needs to be closed within 10 business days, what is the date does it needs to be closed? Much to our surprise, there does not appear to be any built-in functionality for handling such things.

At Internet Creations, calculating business hours is one of the critical functions for our Case Flags app, so we are familiar with querying the BusinessHours object in SOQL and then utilizing the methods in the BusinessHour class in Apex. Your organization’s business hours settings can be found in Setup -> Administration Setup -> Company Profile -> Business Hours.

salesforce business days

In our example here, our business is open from 9-5 Monday / Wednesday / Friday, opened 24 hours on Tuesday, and closed on Sunday / Thursday / Saturday. Yes, these are very odd hours, but we want to show that companies are not necessarily open for just 8 hours a day.

Because of this, we cannot simply calculate business days by dividing the business hours by 8 or 24, and thus, the BusinessHour class provided by Salesforce will not be enough to calculate business days. We will have to create our own BusinessDays class to handle our problem.

To calculate business days, we need to look at our example and see that the company is opened every day of the week expect for Sunday, Thursday, and Saturday. It doesn’t matter the number of hours assigned to each day. As long as it has any hours assigned to it, it is considered a business day. This is made even easier when querying the BusinessHours object in SOQL because the StartTime fields (SundayStartTime, MondayStartTime, etc.) will always return with a value of the day has any hours, and null on days with no hours.

If we were to put the week into an array of boolean values where true equals a business day, false equals a day off, and the week starts with Sunday as the first index, we can express the work week as {false, true, true, true, false, true, false}. Once we have this array, we can just walk through the week to see what days are business days and what days are not.

Here is our own BusinessDays class, where we create this critical array in the constructor. I have also included two public functions, nextBusinessDay() and addBusinessDays().

public class BusinessDays {

    private List<Boolean> businessDay = new Boolean[7];
    private Date knownSunday = date.newInstance(2012, 7, 1);

    // Constructor creates businessDay array
    public BusinessDays(String businessHourId){
        BusinessHours bh = [SELECT FridayStartTime,MondayStartTime,SaturdayStartTime,SundayStartTime,ThursdayStartTime,TuesdayStartTime,WednesdayStartTime FROM BusinessHours WHERE id =: businessHourId];
        businessDay[0] = (bh.SundayStartTime != null);
        businessDay[1] = (bh.MondayStartTime != null);
        businessDay[2] = (bh.TuesdayStartTime != null);
        businessDay[3] = (bh.WednesdayStartTime != null);
        businessDay[4] = (bh.ThursdayStartTime != null);
        businessDay[5] = (bh.FridayStartTime != null);
        businessDay[6] = (bh.SaturdayStartTime != null);
    }

    // Returns back the next available business day
    public Date nextBusinessDay(Date d){
        integer i = Math.mod(this.knownSunday.daysBetween(d),7);

        Date returnDate = d;

        do {
            returnDate = returnDate.addDays(1);
            i++;
        } while (!businessDay[Math.mod(i, 7)]);

        return returnDate;
    }

    // returns back date in numberOfDays business days
    public Date addBusinessDays (Date startDate, integer numberOfDays){
        Date returnDate = startDate;

        for (integer x = 0; x < numberOfDays; x++)
            returnDate = nextBusinessDay(returnDate);

        return returnDate;
    }
}

And that should provide the function that is missing from Salesforce.

However, this class is not complete yet. We have not taken holidays into consideration, and that makes the calculation far more complicated. But this is a good start for now and we will save complexity for a future blog post.

If you have any questions about our BusinessDays class or have any suggestions on how to improve it, contact us by adding a comment below, or @ reply us on Twitter. We’re on Facebook too!

Tags: , , , , , , , , , , , , , ,

  • AJAY KUMAR SINGH

    Thanks for sharing your code But I wanted how to calculate business hours in salesforce.

  • Jim

    How do I call this class from within a trigger?

    • benortiz21

      Hi Jim, you’d need to instantiate our BusinessDays class with an existing BusinessHours object id. You can then call either of the class methods. As as example, the code below selects the default hours and then performs some basic calculations.

      BusinessHours bh = [Select id From BusinessHours where IsDefault = true];

      BusinessDays BizDays = new BusinessDays(bh.id);

      //retrieve the next business day after today
      System.debug(BizDays.nextBusinessDay(System.Now().date()));

      //calculate 8 business days from now
      System.debug(BizDays.addBusinessDays(System.Now().date(), 8));

      • Amit Jaiswal

        The problem with above code is, it only gives the exact business “date” and not exact business “datetime”