Hello Everyone, In this tutorial, I provide an Apex class that contains code to calculate Business days of your Salesforce organization. Hope this example helps you lot to do the calculation of Bussiness days.
After completing this tutorial, you'll able to:
- Calculate Business days in Salesforce
So let's begin,
In Salesforce, you can configure Business hours using Business Hour's object. This object easily accessible under the Setup menu, Navigate to Setup>Business Hours.
In your Salesforce organization by default, a Business hour is declared, but you can create a new one by clicking on "New Business Hours" button.
So here are default created business hours
Create an apex class and replace the following code.
Apex Controller:
/** *CalcBusinessDays Class *easily skip weekends and holidays from your logic **/ public class CalcBusinessDays{ public BusinessHours bHours; //Constructor to set business hour name public CalcBusinessDays(String businessHoursName){ bHours = [SELECT Id FROM BusinessHours WHERE Name =: businessHoursName]; } // if business hour name not provided in paramaterized constructor, return default hours public CalcBusinessDays(){ bHours = [SELECT Id FROM BusinessHours WHERE IsDefault = true]; } public Datetime AddDays(Datetime dSartDate, Integer iDays){ dSartDate = BusinessHours.nextStartDate(bHours.Id, dSartDate); for (Integer i = 0; i < iDays; i++){ dSartDate = dSartDate.addDays(1); if (!BusinessHours.isWithin(bHours.Id, dSartDate)){ dSartDate = BusinessHours.nextStartDate(bHours.Id, dSartDate); } } return dSartDate; } public Datetime SubtractDays(Datetime dStartDate, Integer iDays){ dStartDate = getPreviousWorkingDay(dStartDate); for (Integer i = 0; i < iDays; i++){ dStartDate = dStartDate.addDays(-1); if (!BusinessHours.isWithin(bHours.Id, dStartDate)){ dStartDate = getPreviousWorkingDay(dStartDate); } } return dStartDate; } /** * Recursive function to get previous working day * If date passed to this function is on a working day, this will return same date otherwise previous working day * ********************* * For Example, * if passed day is Monday, this will return Monday * else if passed day is Sunday,then this will return Friday * ********************* **/ public Datetime getPreviousWorkingDay(Datetime d){ //Check if new date is within working days if (!BusinessHours.isWithin(bHours.Id, d)){ d = d.addDays(-1); return getPreviousWorkingDay(d); } else{ return d; } } /** * Function to get next working day * If date passed to this function is on a working day, this will return same date otherwise return next working day * ********************* * For Example, * if passed day is Monday, this will return Monday * else if passed day is Sunday, then this will return Monday * ********************* **/ public Datetime getNextWorkingDay(Datetime d){ return BusinessHours.nextStartDate(bHours.Id, d); } //Check if provided date is working day or not public Boolean isWorkingDay(Datetime d){ return BusinessHours.isWithin(bHours.Id, d); } //Get numbe of business days between two dates public Integer getNoOfBusinessDaysBetweenDates(DateTime dStartDate, DateTime dEndDate){ Integer count = 0; while(dStartDate <= dEndDate){ if(BusinessHours.isWithin(bHours.Id, dStartDate)){ count++; } dStartDate = dStartDate.addDays(1); } return count; } }
See also:
- Pagination without Standard Controller in Visualforce page
- Print number in text format using Visualforce and Apex
- Delete checked value in Pagination in Visualforce Page
Conclusion:
Hope you like this tutorial, for any query please feel free to comment.
Thank you.
5 Comments
The addDays() method. I'd add one tweak. Until it skips a day, it appears to give back the same time of day. If you want from the adding 1, always get the start of the business day, I used --
ReplyDeletedSartDate = dSartDate.addDays(1);
dSartDate = DateTime.newInstance(dSartDate.Date(), Time.newInstance(0,0,0,0));
Anonymous code I wrote to demonstrate...
ReplyDeleteBusinessHours bHours = [ SELECT Id FROM BusinessHours WHERE IsDefault=true];
Datetime addDays(Datetime dSartDate, Integer iDays){
dSartDate = BusinessHours.nextStartDate(bHours.Id, dSartDate);
for (Integer i = 0; i < iDays; i++){
dSartDate = dSartDate.addDays(1);
dSartDate = DateTime.newInstance(dSartDate.Date(), Time.newInstance(0,0,0,0));
if (!BusinessHours.isWithin(bHours.Id, dSartDate)){
dSartDate = BusinessHours.nextStartDate(bHours.Id, dSartDate);
}
}
return dSartDate;
}
Datetime targetDateTime = Datetime.newInstance(2013,11, 20, 11, 0, 0);
for (Integer i=0; i<12; i++) {
Datetime nextStartDateTime = addDays(targetDateTime,i);
System.debug (i + ' --> ' + nextStartDateTime.format());
}
Example output --
ReplyDelete16:54:18.0 (10157309)|USER_DEBUG|[19]|DEBUG|0 --> 11/20/2013, 11:00 AM
16:54:18.0 (10188262)|SYSTEM_MODE_ENTER|false
16:54:18.0 (10946237)|SYSTEM_MODE_EXIT|false
16:54:18.0 (10996994)|USER_DEBUG|[19]|DEBUG|1 --> 11/21/2013, 8:00 AM
16:54:18.0 (11014370)|SYSTEM_MODE_ENTER|false
16:54:18.0 (11723698)|SYSTEM_MODE_EXIT|false
16:54:18.0 (11765293)|USER_DEBUG|[19]|DEBUG|2 --> 11/22/2013, 8:00 AM
16:54:18.0 (11780222)|SYSTEM_MODE_ENTER|false
16:54:18.0 (12767365)|SYSTEM_MODE_EXIT|false
16:54:18.0 (12836135)|USER_DEBUG|[19]|DEBUG|3 --> 11/25/2013, 8:00 AM
16:54:18.0 (12853106)|SYSTEM_MODE_ENTER|false
16:54:18.0 (15126345)|SYSTEM_MODE_EXIT|false
16:54:18.0 (15209680)|USER_DEBUG|[19]|DEBUG|4 --> 11/26/2013, 8:00 AM
16:54:18.0 (15235518)|SYSTEM_MODE_ENTER|false
16:54:18.0 (17456613)|SYSTEM_MODE_EXIT|false
16:54:18.0 (17508614)|USER_DEBUG|[19]|DEBUG|5 --> 11/27/2013, 8:00 AM
16:54:18.0 (17526339)|SYSTEM_MODE_ENTER|false
16:54:18.0 (19189136)|SYSTEM_MODE_EXIT|false
16:54:18.0 (19233383)|USER_DEBUG|[19]|DEBUG|6 --> 11/28/2013, 8:00 AM
16:54:18.0 (19248770)|SYSTEM_MODE_ENTER|false
16:54:18.0 (21120765)|SYSTEM_MODE_EXIT|false
16:54:18.0 (21164405)|USER_DEBUG|[19]|DEBUG|7 --> 11/29/2013, 8:00 AM
16:54:18.0 (21179639)|SYSTEM_MODE_ENTER|false
Without that extra line I get --
ReplyDelete16:57:36.1 (10425793)|SYSTEM_MODE_EXIT|false
16:57:36.1 (10627454)|USER_DEBUG|[18]|DEBUG|0 --> 11/20/2013, 11:00 AM
16:57:36.1 (10655279)|SYSTEM_MODE_ENTER|false
16:57:36.1 (11099121)|SYSTEM_MODE_EXIT|false
16:57:36.1 (11142628)|USER_DEBUG|[18]|DEBUG|1 --> 11/21/2013, 11:00 AM
16:57:36.1 (11158004)|SYSTEM_MODE_ENTER|false
16:57:36.1 (11569982)|SYSTEM_MODE_EXIT|false
16:57:36.1 (11605598)|USER_DEBUG|[18]|DEBUG|2 --> 11/22/2013, 11:00 AM
16:57:36.1 (11618620)|SYSTEM_MODE_ENTER|false
16:57:36.1 (12164529)|SYSTEM_MODE_EXIT|false
16:57:36.1 (12200135)|USER_DEBUG|[18]|DEBUG|3 --> 11/25/2013, 8:00 AM
16:57:36.1 (12212989)|SYSTEM_MODE_ENTER|false
16:57:36.1 (12863462)|SYSTEM_MODE_EXIT|false
16:57:36.1 (12897218)|USER_DEBUG|[18]|DEBUG|4 --> 11/26/2013, 8:00 AM
16:57:36.1 (12909544)|SYSTEM_MODE_ENTER|false
16:57:36.1 (13615086)|SYSTEM_MODE_EXIT|false
16:57:36.1 (13650092)|USER_DEBUG|[18]|DEBUG|5 --> 11/27/2013, 8:00 AM
16:57:36.1 (13662712)|SYSTEM_MODE_ENTER|false
16:57:36.1 (14460735)|SYSTEM_MODE_EXIT|false
16:57:36.1 (14494544)|USER_DEBUG|[18]|DEBUG|6 --> 11/28/2013, 8:00 AM
16:57:36.1 (14507161)|SYSTEM_MODE_ENTER|false
16:57:36.1 (15407898)|SYSTEM_MODE_EXIT|false
16:57:36.1 (15441854)|USER_DEBUG|[18]|DEBUG|7 --> 11/29/2013, 8:00 AM
16:57:36.1 (15454681)|SYSTEM_MODE_ENTER|false
Hope you like this idea -- learn2turn@yahoo.com aka kkoellner@engageware.com
ReplyDeletePost a Comment