Monday 28 September 2015

Business Day Calculation in Apex Salesforce

        Here is the utility method to calculate various business day calculation such as getting next business days, business hours, validating date is business day or not, total business days between two dates, etc.


  1. public class BusinessDays {
  2. private List<Boolean> businessDay = new Boolean[7];
  3. private List<Time> startHours = new Time [7];
  4. private List<Time> endHours = new Time [7];
  5. private Date knownSunday = date.newInstance(201316);
  6. private String businessHourId;
  7. private Boolean considerHolidays = false;
  8.    
  9.   // Constructor creates businessDay array
  10.    public BusinessDays(String businessHourName, Boolean considerHolidays) {
  11.      
  12.      BusinessHours bh;
  13.      
  14.      this.considerHolidays = considerHolidays;
  15.      
  16.      if(businessHourName == null) {
  17.          bh = [SELECT SundayStartTime, MondayStartTime, TuesdayStartTime,WednesdayStartTime, ThursdayStartTime, FridayStartTime,SaturdayStartTime, SundayEndTime, MondayEndTime,TuesdayEndTime,WednesdayEndTime, ThursdayEndTime, FridayEndTime,SaturdayEndTime
  18.                             FROM BusinessHours
  19.                                 WHERE IsDefault = true ];
  20.      }else {
  21.          bh = [SELECT SundayStartTime, MondayStartTime, TuesdayStartTime,WednesdayStartTime, ThursdayStartTime, FridayStartTime,SaturdayStartTime, SundayEndTime, MondayEndTime,TuesdayEndTime,WednesdayEndTime, ThursdayEndTime, FridayEndTime,SaturdayEndTime
  22.                             FROM BusinessHours
  23.                                 WHERE Name =: businessHourName ];
  24.      }
  25.      
  26.      businessHourId = bh.Id;
  27.      
  28.      businessDay[0] = (bh.SundayStartTime != null);
  29.      businessDay[1] = (bh.MondayStartTime != null);
  30.      businessDay[2] = (bh.TuesdayStartTime != null);
  31.      businessDay[3] = (bh.WednesdayStartTime != null);
  32.      businessDay[4] = (bh.ThursdayStartTime != null);
  33.      businessDay[5] = (bh.FridayStartTime != null);
  34.      businessDay[6] = (bh.SaturdayStartTime != null);
  35.      startHours[0] = bh.SundayStartTime;
  36.      startHours[1] = bh.MondayStartTime;
  37.      startHours[2] = bh.TuesdayStartTime;
  38.      startHours[3] = bh.WednesdayStartTime;
  39.      startHours[4] = bh.ThursdayStartTime;
  40.      startHours[5] = bh.FridayStartTime;
  41.      startHours[6] = bh.SaturdayStartTime;
  42.      endHours[0] = bh.SundayEndTime;
  43.      endHours[1] = bh.MondayEndTime;
  44.      endHours[2] = bh.TuesdayEndTime;
  45.      endHours[3] = bh.WednesdayEndTime;
  46.      endHours[4] = bh.ThursdayEndTime;
  47.      endHours[5] = bh.FridayEndTime;
  48.      endHours[6] = bh.SaturdayEndTime;
  49.    }
  50.    // Check if today is a business day - Date
  51.    public Boolean isBusinessDay(Date inputDate) {
  52.      // index i is index into the businessDay array based on inputDate
  53.      Integer i = Math.mod(Math.abs(this.knownSunday.daysBetween(inputDate)),7);
  54.      Boolean isBusinessDay = businessDay[i];
  55.      
  56.      if(considerHolidays) {
  57.          isBusinessDay = (isBusinessDay && BusinessHours.isWithin(businessHourId , datetime.newInstance(inputDate.year(), inputDate.month(),inputDate.day())));
  58.      }
  59.      
  60.      return (isBusinessDay);
  61.     }
  62.    
  63.     // Check if today is a business day - DateTime
  64.    public Boolean isBusinessDay(DateTime inputDateTime) {
  65.      
  66.      Date businessDate = inputDateTime.date();
  67.      Time businessTime = inputDateTime.Time();
  68.      
  69.      // index i is index into the businessDay array based on inputDate
  70.      Integer i = Math.mod(Math.abs(this.knownSunday.daysBetween(businessDate)),7);
  71.      Boolean isBusinessDay = isBusinessDay(businessDate);
  72.      Boolean isBusinessHour = false;
  73.      
  74.      if(isBusinessDay){
  75.          isBusinessHour = ( businessTime > getStartTime(businessDate) && businessTime < getEndTime(businessDate) );
  76.      }
  77.      
  78.      return (isBusinessHour);
  79.     }
  80.    // Get the start time
  81.    public Time getStartTime(Date inputDate) {
  82.      Integer i = Math.mod(Math.abs(this.knownSunday.daysBetween(inputDate)),7);
  83.      return (startHours[i]);
  84.    }
  85.    
  86.    // Get the End time
  87.    public Time getEndTime(Date inputDate) {
  88.      Integer i = Math.mod(Math.abs(this.knownSunday.daysBetween(inputDate)),7);
  89.      return (endHours[i]);
  90.    }
  91.    // Gets next business day, skipping non business days
  92.    public Date nextBusinessDay(Date inputDate) {
  93.      Integer i = Math.mod(Math.abs(this.knownSunday.daysBetween(inputDate)),7);
  94.      Date returnDate = inputDate;
  95.      
  96.      do {
  97.          returnDate = returnDate.addDays(1);
  98.          i++;
  99.      } while (!businessDay[Math.mod(i, 7)]);
  100.        
  101.      if(considerHolidays) {
  102.          if(!BusinessHours.isWithin(businessHourId , datetime.newInstance(returnDate.year(), returnDate.month(),returnDate.day() ))) {
  103.              returnDate = nextBusinessDay(returnDate);
  104.          }
  105.      }
  106.      
  107.      return returnDate;
  108.    }
  109.    
  110.    // returns back date in numberOfDays business days
  111.    public Date addBusinessDays (Date startDate, integer numberOfDays) {
  112.         Date returnDate = startDate;
  113.         Integer holidayCount = 0;
  114.         for (integer x = 0; x < numberOfDays; x++) {
  115.             returnDate = nextBusinessDay(returnDate);
  116.            
  117.             if(considerHolidays){
  118.                 if(!BusinessHours.isWithin(businessHourId , datetime.newInstance( returnDate.year(), returnDate.month(), returnDate.day() ))){
  119.                     holidayCount++;
  120.                 }
  121.             }
  122.         }
  123.        
  124.         if(holidayCount > 0) {
  125.             returnDate.addDays(holidayCount);  
  126.         }
  127.         return returnDate;
  128.    }
  129.    
  130.    //get the total business days between two dates
  131.    public Integer getTotalBusinessDays(Date inputDateStart, Date inputDateEnd) {
  132.        Integer totalDays = 0;
  133.        Date returnDate = inputDateStart;
  134.        
  135.        do {
  136.            returnDate = returnDate.addDays(1);
  137.            if(isBusinessDay(returnDate)) {
  138.                totalDays++;
  139.                
  140.                if(considerHolidays){
  141.                    if(!BusinessHours.isWithin(businessHourId , datetime.newInstance( returnDate.year(), returnDate.month(), returnDate.day()))) {
  142.                        totalDays--;
  143.                    }
  144.                }
  145.            }  
  146.        } while (returnDate != inputDateEnd);
  147.        
  148.        return totalDays;
  149.    }
  150.  }



Thanks to my dear friend Purushothaman Annamalai, who shared this code.

Blog: Salesforce Quest

1 comment:

  1. man thanks for the help..i have been banging my head for a month,tomorrow is my release.Thanks for the help.You wiill be remembered

    ReplyDelete

Activities: Assign Tasks to a Queue Salesforce Lightning

Salesforce announced to assign Tasks to a Queue beginning from Spring'20 release. How does it work? In Setup, enter Queues in th...