16

I have an date, i need to add no. of days to get future date but weekends should be excluded. i.e

input date = "9-DEC-2011";
No. of days to add  = '13';

next date should be "28-Dec-2011"

Here weekends(sat/sun) are not counted.

Harish Ambady
  • 12,525
  • 4
  • 29
  • 54
Nishu Tayal
  • 20,106
  • 8
  • 49
  • 101
  • 1
    possible duplicate of [add/subtract business days in Javascript](http://stackoverflow.com/questions/6499944/add-subtract-business-days-in-javascript) – Daniel A. White Dec 09 '11 at 20:19

10 Answers10

29

Try this

var startDate = "9-DEC-2011";
startDate = new Date(startDate.replace(/-/g, "/"));
var endDate = "", noOfDaysToAdd = 13, count = 0;
while(count < noOfDaysToAdd){
    endDate = new Date(startDate.setDate(startDate.getDate() + 1));
    if(endDate.getDay() != 0 && endDate.getDay() != 6){
       //Date.getDay() gives weekday starting from 0(Sunday) to 6(Saturday)
       count++;
    }
}
alert(endDate);//You can format this date as per your requirement

Working Demo

ShankarSangoli
  • 69,612
  • 13
  • 93
  • 124
  • @Nishu - did you get a chance to take a look at this? – ShankarSangoli Dec 10 '11 at 17:01
  • Thank Shanker... yeah i did.... i also implemented this logic as well, but main concern was to optimize the logic. Since if no. of days is like 30,40,50 and so on....., loop will execute that no. of times, do you think of any optimized solution?? – Nishu Tayal Dec 10 '11 at 18:48
  • I think we can optimize this let me give it a try whenever I get time. – ShankarSangoli Dec 12 '11 at 02:08
  • @ShankarSangoli Thank you this work for me. But i have custom weekend like 26Jan national holiday i want to exclude that also is there any solution – amol challawar Apr 20 '17 at 10:08
  • lets say I need to add weeks or months to the startDate then how can we do that? Considering the fact that a month can be of 28, 29, 30 or 31 days long. – Sushmit Sagar Jan 15 '19 at 11:24
13

@ShankarSangoli

Here's a newer version which avoid recreating a Date object on each loop, note that it's wrapped in a function now.

function calcWorkingDays(fromDate, days) {
    var count = 0;
    while (count < days) {
        fromDate.setDate(fromDate.getDate() + 1);
        if (fromDate.getDay() != 0 && fromDate.getDay() != 6) // Skip weekends
            count++;
    }
    return fromDate;
}
alert(calcWorkingDays(new Date("9/DEC/2011"), 13));
user3091762
  • 131
  • 1
  • 2
6

Here is an elegant solution without any looping or external library:

function addBusinessDaysToDate(date, days) {
  var day = date.getDay();

  date = new Date(date.getTime());
  date.setDate(date.getDate() + days + (day === 6 ? 2 : +!day) + (Math.floor((days - 1 + (day % 6 || 1)) / 5) * 2));
  return date;
}

var date = "9-DEC-2011";
var newDate = addBusinessDaysToDate(new Date(date.replace(/-/g, "/")), 13);
console.log(newDate.toString().replace(/\S+\s(\S+)\s(\d+)\s(\d+)\s.*/, '$2-$1-$3')); // alerts "28-Dec-2011"
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Harish Ambady
  • 12,525
  • 4
  • 29
  • 54
3

or you can be like this

function addWeekdays(date, weekdays) {
    var newDate = new Date(date.getTime());
    var i = 0;
    while (i < weekdays) {
        newDate.setDate(newDate.getDate() + 1);
        var day = newDate.getDay();
        if (day > 1 && day < 7) {
            i++;
        }
    }
    return newDate;
}
var currentDate = new Date('10/31/2014');
var targetDate = addWeekdays(currentDate, 45);
alert(targetDate);
lamer lamer
  • 315
  • 6
  • 14
3

Using moment.js:

const DATE_FORMAT = 'D-MMM-YYYY';
const SUNDAY = 0; // moment day index
const SATURDAY = 6; // moment day index
const WEEKENDS = [SATURDAY, SUNDAY];

function addBusinessDays(stringDate, numberOfDays, dateFormat = DATE_FORMAT) {
  const date = moment(stringDate, dateFormat);
    
  let count = 0;
        
  while (count < numberOfDays) {
    date.add(1, 'day');

    // Skip weekends
    if (WEEKENDS.includes(date.day())) {
      continue;
    }

    // Increment count
    count++;
  }
    
  return date.format(dateFormat);
}

// Test cases
console.log(addBusinessDays('3-Mar-2021', 1)); // 4-Mar-2021
console.log(addBusinessDays('3-Mar-2021', 2)); // 5-Mar-2021
console.log(addBusinessDays('3-Mar-2021', 3)); // 8-Mar-2021
console.log(addBusinessDays('3-Mar-2021', 4)); // 9-Mar-2021
console.log(addBusinessDays('3-Mar-2021', 5)); // 10-Mar-2021
console.log(addBusinessDays('9-Dec-2011', 13)); // 28-Dec-2011
console.log(addBusinessDays('10-Dec-2011', 13)); // 28-Dec-2011 (Saturday, so remain on Friday)
console.log(addBusinessDays('11-Dec-2011', 13)); // 28-Dec-2011 (Sunday, so remain on Friday)
console.log(addBusinessDays('12-Dec-2011', 13)); // 29-Dec-2011
console.log(addBusinessDays('13-Dec-2011', 13)); // 30-Dec-2011
console.log(addBusinessDays('14-Dec-2011', 13)); // 2-Jan-2012
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
Jee Mok
  • 6,157
  • 8
  • 47
  • 80
2

This question is quite old, but all the previous answers are iterating over the days one by one. That could be inefficient for a large number of days. This works for me, assuming days is a positive int and the startDate is a working day:

function addWorkingDates(startDate, days) {
  const current_day = startDate.getDay() - 1; // Week day, starting on Monday
  const weekend_days = 2 * parseInt((current_day + days) / 5);
  startDate.setDate(changed_to.getDate() + days + weekend_days);
}

addWorkingDates(new Date(),5)
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Moisés Hiraldo
  • 378
  • 1
  • 4
  • 13
1

For some reason it was more intuitive to me to try this recursively. This version doesn't account for holidays, but you could change the isValid function to check whatever.

function addWeekdaysToDate(date, numberToAdd) {
  var isValid = function(d) { return d.getDay() !== 0 && d.getDay() !== 6 }
  if(Math.abs(numberToAdd) > 1) {
    return addWeekdaysToDate(
      addWeekdaysToDate(date, Math.sign(numberToAdd)),
      numberToAdd - Math.sign(numberToAdd)
    )
  } else if(Math.abs(numberToAdd) === 1) {
    var result = new Date(date)
    result.setDate(result.getDate() + Math.sign(numberToAdd))
    if(isValid(result)) {
      return result
    } else {
      return addWeekdaysToDate(result, Math.sign(numberToAdd))
    }
  } else if(numberToAdd === 0) {
    return date
  }
  return false
}

console.log(addWeekdaysToDate(new Date(), 1))
console.log(addWeekdaysToDate(new Date(), 5))
console.log(addWeekdaysToDate(new Date(), -7))

In certain browsers you may need a polyfill for Math.sign:

Math.sign = Math.sign || function(x) {
  x = +x; // convert to a number
  if (x === 0 || isNaN(x)) {
    return Number(x);
  }
  return x > 0 ? 1 : -1;
}
Toph
  • 2,561
  • 2
  • 24
  • 28
0

If you want to get the next working day, from a specific date, use the following code...

function getNextWorkingDay(originalDate) {
    var nextWorkingDayFound = false;
    var nextWorkingDate = new Date();
    var dateCounter = 1;

    while (!nextWorkingDayFound) {
        nextWorkingDate.setDate(originalDate.getDate() + dateCounter);
        dateCounter++;

        if (!isDateOnWeekend(nextWorkingDate)) {
            nextWorkingDayFound = true;
        } 
    }

    return nextWorkingDate;
}

function isDateOnWeekend(date) {
    if (date.getDay() === 6 || date.getDay() === 0)
        return true;
    else
        return false;
}
Greg Quinn
  • 1,927
  • 1
  • 23
  • 26
0

try this solution

<script language="javascript">

function getDateExcludeWeekends(startDay, startMonth, startYear, daysToAdd) {
var sdate = new Date();
var edate = new Date();
var dayMilliseconds = 1000 * 60 * 60 * 24;
sdate.setFullYear(startYear,startMonth,startDay);
edate.setFullYear(startYear,startMonth,startDay+daysToAdd);
var weekendDays = 0;
while (sdate <= edate) {
    var day = sdate.getDay()
    if (day == 0 || day == 6) {
        weekendDays++;
    }
    sdate = new Date(+sdate + dayMilliseconds);
} 
sdate.setFullYear(startYear,startMonth,startDay + weekendDays+daysToAdd);
return sdate;
}

</script>
SaQiB
  • 639
  • 8
  • 18
-1

Try this

function calculate() {
  var noOfDaysToAdd = 13;
  var startDate = "9-DEC-2011";
  startDate = new Date(startDate.replace(/-/g, "/"));
  var endDate = "";
  count = 0;
  while (count < noOfDaysToAdd) {
    endDate = new Date(startDate.setDate(startDate.getDate() + 1));
    if (endDate.getDay() != 0 && endDate.getDay() != 6) {
      count++;
    }
  }
  document.getElementById("result").innerHTML = endDate;
}
<div>
  Date of book delivery: <span id="result"></span><br /><br />
  <input type="button" onclick="calculate();" value="Calculate" />
  <br>
  <br>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Tejswita
  • 1
  • 2
  • Please add some context to your answer, explaining what you are showing and why this is solving the OP's problem. See https://stackoverflow.com/help/how-to-answer – PVitt Mar 21 '18 at 10:41