AlexIL AlexIL - 7 months ago 26
Javascript Question

Calculate working days between two dates in Javascript excepts holidays

I have a javascript function which is calculating working days between 2 dates, it works, but the problem is that it not consider holidays. How can I modify this function, for example by adding holidays in exception array?

Searched in internet about this question, but haven't find about holidays exception.

For example holidays array:

var holidays = ['2016-05-03','2016-05-05'];


And I have a functions to calculate this:

function workingDaysBetweenDates(d0, d1) {
var startDate = parseDate(d0);
var endDate = parseDate(d1);
// Validate input
if (endDate < startDate)
return 0;

// Calculate days between dates
var millisecondsPerDay = 86400 * 1000; // Day in milliseconds
startDate.setHours(0,0,0,1); // Start just after midnight
endDate.setHours(23,59,59,999); // End just before midnight
var diff = endDate - startDate; // Milliseconds between datetime objects
var days = Math.ceil(diff / millisecondsPerDay);

// Subtract two weekend days for every week in between
var weeks = Math.floor(days / 7);
days = days - (weeks * 2);

// Handle special cases
var startDay = startDate.getDay();
var endDay = endDate.getDay();

// Remove weekend not previously removed.
if (startDay - endDay > 1)
days = days - 2;

// Remove start day if span starts on Sunday but ends before Saturday
if (startDay == 0 && endDay != 6)
days = days - 1

// Remove end day if span ends on Saturday but starts after Sunday
if (endDay == 6 && startDay != 0)
days = days - 1

return days;
}
function parseDate(input) {
// Transform date from text to date
var parts = input.match(/(\d+)/g);
// new Date(year, month [, date [, hours[, minutes[, seconds[, ms]]]]])
return new Date(parts[0], parts[1]-1, parts[2]); // months are 0-based
}


Have made an example in jsfiddle:

JSFiddle example

Maybe there are some other functions which can easy use in Jquery?

Answer

The easiest way to achieve it is looking for these days between your begin and end date.

$(document).ready(function(){
	$('#calc').click(function(){
  var d1 = $('#d1').val();
  var d2 = $('#d2').val();
		$('#dif').text(workingDaysBetweenDates(d1,d2));
	});
});

function workingDaysBetweenDates(d0, d1) {
	var holidays = ['2016-05-03','2016-05-05'];
    var startDate = parseDate(d0);
    var endDate = parseDate(d1);  
    // Validate input
    if (endDate < startDate) {
        return 0;
    }
    // Calculate days between dates
    var millisecondsPerDay = 86400 * 1000; // Day in milliseconds
    startDate.setHours(0,0,0,1);  // Start just after midnight
    endDate.setHours(23,59,59,999);  // End just before midnight
    var diff = endDate - startDate;  // Milliseconds between datetime objects    
    var days = Math.ceil(diff / millisecondsPerDay);
    
    // Subtract two weekend days for every week in between
    var weeks = Math.floor(days / 7);
    days -= weeks * 2;

    // Handle special cases
    var startDay = startDate.getDay();
    var endDay = endDate.getDay();
    
    // Remove weekend not previously removed.   
    if (startDay - endDay > 1) {
        days -= 2;
    }
    // Remove start day if span starts on Sunday but ends before Saturday
    if (startDay == 0 && endDay != 6) {
        days--;  
    }
    // Remove end day if span ends on Saturday but starts after Sunday
    if (endDay == 6 && startDay != 0) {
        days--;
    }
    /* Here is the code */
    for (var i in holidays) {
      if ((holidays[i] >= d0) && (holidays[i] <= d1)) {
      	days--;
      }
    }
    return days;
}
           
function parseDate(input) {
	// Transform date from text to date
  var parts = input.match(/(\d+)/g);
  // new Date(year, month [, date [, hours[, minutes[, seconds[, ms]]]]])
  return new Date(parts[0], parts[1]-1, parts[2]); // months are 0-based
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="d1" value="2016-05-02"><br>
<input type="text" id="d2" value="2016-05-08">

<p>Working days count: <span id="dif"></span></p>
<button id="calc">Calc</button>

<p>
Now it shows 5 days, but I need for example add holidays 
3 and 5 May (2016-05-03 and 2016-05-05) so the result will be 3 working days
</p>