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.
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!