Calculating Business Hours in Javascript

Time is money, especially when that time is spent handling things like calculating hours worked and filling out time-sheets.

Recently, a user on the forums posed a question about how to go about calculating the number of hours worked between two specified dates. The request required that it must be handled through Javascript and that it must be as “exact as possible” down to the minute. So I wrote up the following quick solution and thought I would post it here on the off-chance that anyone encounters the same issue.

Let’s take a look at what information we need:

  • Define the work hours during the day (e.g between 9AM and 5PM).
  • Define a starting and ending date to calculate between.
  • Determine if weekends are counted.

Using this information I threw together the following annotated example:

  1. // Simple function that accepts two parameters and calculates  
  2. // the number of hours worked within that range  
  3. functionworkingHoursBetweenDates(startDate, endDate) {  
  4.     // Store minutes worked  
  5.     varminutesWorked = 0;  
  6.   
  7.     // Validate input  
  8.     if (endDate < startDate) {  
  9.         return0;  
  10.     }  
  11.   
  12.     // Loop from your Start to End dates (by hour)  
  13.     var current = startDate;  
  14.   
  15.     // Define work range  
  16.     varworkHoursStart = 9;  
  17.     varworkHoursEnd = 18;  
  18.     varincludeWeekends = false;  
  19.   
  20.     // Loop while currentDate is less than end Date (by minutes)  
  21.     while (current <= endDate) {  
  22.         // Is the current time within a work day (and if it   
  23.         // occurs on a weekend or not)   
  24.         if (current.getHours() >= workHoursStart && current.getHours() <= workHoursEnd && (includeWeekends ? current.getDay() !== 0 && current.getDay() !== 6 : true)) {  
  25.             minutesWorked++;  
  26.         }  
  27.   
  28.         // Increment current time  
  29.         current.setTime(current.getTime() + 1000 * 60);  
  30.     }  
  31.   
  32.     // Return the number of hours  
  33.     returnminutesWorked / 60;  
  34. }  
Or if you would prefer to pass in all of your variables as parameters, you could use:
  1. // Simple function that accepts two parameters and calculates  
  2. // the number of hours worked within that range  
  3. functionworkingHoursBetweenDates(startDate, endDate, dayStart, dayEnd, includeWeekends)   
  4. {  
  5.     // Store minutes worked  
  6.     varminutesWorked = 0;  
  7.   
  8.     // Validate input  
  9.     if (endDate < startDate)   
  10.     {  
  11.         return0;  
  12.     }  
  13.   
  14.     // Loop from your Start to End dates (by hour)  
  15.     var current = startDate;  
  16.   
  17.     // Define work range  
  18.     varworkHoursStart = dayStart;  
  19.     varworkHoursEnd = dayEnd;  
  20.   
  21.     // Loop while currentDate is less than end Date (by minutes)  
  22.     while (current <= endDate)   
  23.     {  
  24.         // Store the current time (with minutes adjusted)  
  25.         varcurrentTime = current.getHours() + (current.getMinutes() / 60);  
  26.   
  27.         // Is the current time within a work day (and if it  
  28.         // occurs on a weekend or not)   
  29.         if (currentTime >= workHoursStart && currentTime < workHoursEnd && (includeWeekends ? current.getDay() !== 0 && current.getDay() !== 6 : true))   
  30.         {  
  31.             minutesWorked++;  
  32.         }  
  33.   
  34.         // Increment current time  
  35.         current.setTime(current.getTime() + 1000 * 60);  
  36.     }  
  37.   
  38.     // Return the number of hours  
  39.     return (minutesWorked / 60).toFixed(2);  
  40. }  
Or if you want a minified version thanks to Google’s Online Closure Compiler:
  1. functionworkingHoursBetweenDates(a, b, e, f, g)   
  2. {  
  3.     var c = 0;  
  4.     if (b < a) return0;  
  5.     for (; a <= b;)   
  6.     {  
  7.         var d = a.getHours() + a.getMinutes() / 60;  
  8.         d >= e && d < f && (g ? 0 !== a.getDay() && 6 !== a.getDay() : 1) && c++;  
  9.         a.setTime(a.getTime() + 6E4)  
  10.     }  
  11.     return (c / 60).toFixed(2)  
  12. };  
Basically, it simply starts at the beginning time and iterates until the end (while monitoring the number of minutes worked during this period). By no means is this optimal, but it should serve as a very basic example of how to calculate such a value within Javascript. Please feel free to post any improvements or optimizations within the comments section as this was just a hastily thrown together solution to solve the issue at hand.
You can find a working example here and demonstrated below:

example

 

Up Next
    Ebook Download
    View all
    Learn
    View all