Reputation: 20830
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.
Upvotes: 17
Views: 29829
Reputation: 1
Function honouring weekends and also given holiday array
var startDate = "10/18/2023";
var endDate = "11/25/2023";
function isSameDate(date1, date2) {
// Compare exact dates with miliseconds
return date1.getTime() === date2.getTime();
}
function isWeekEnd(date) {
//If Day of given date falls between Monday to Friday then return False
day = date.getDay();
if (day >= 1 && day <= 5) {
return false;
}
//Else return true
return true;
}
function isHoliday(date) {
//List of holidays provided
var usHolidays=["11/10/2023","11/23/2023","12/25/2023","01/02/2024","01/15/2024"];
//Iterate through all holidays and check if given date falls on holiday
for(i = 0; i < usHolidays.length; i++) {
holiday = usHolidays[i];
//Convert String to Date
holiday = new Date(holiday);
//normalize to beginning of the day
holiday.setHours(0,0,0,0);
if (isSameDate(date, holiday)) {
return true;
}
}
return false;
}
function calculateBusinessDays(startDate, endDate) {
// make copies we can normalize without changing passed in objects
var start = new Date(startDate);
var end = new Date(endDate);
// initial total
var totalBusinessDays = 0;
// normalize both start and end to beginning of the day
start.setHours(0,0,0,0);
end.setHours(0,0,0,0);
// start from the next day
var current = new Date(start);
current.setDate(current.getDate() + 1);
var day;
// loop through each day, checking
while (current <= end) {
//add to business day if its not weekend or holiday
if (!isWeekEnd(current) && !isHoliday(current)){
++totalBusinessDays;
}
//move one day forward
current.setDate(current.getDate() + 1);
}
return totalBusinessDays;
}
var totalBusinessDays = calculateBusinessDays(startDate, endDate);
console.log(totalBusinessDays);
Upvotes: 0
Reputation: 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>
Upvotes: -1
Reputation: 378
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)
Upvotes: 2
Reputation: 13121
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"
Upvotes: 8
Reputation: 6556
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>
Upvotes: 4
Reputation: 2689
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;
}
Upvotes: 1
Reputation: 2178
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;
}
Upvotes: 0
Reputation: 345
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);
Upvotes: 3
Reputation: 131
@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));
Upvotes: 13
Reputation: 639
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>
Upvotes: 0
Reputation: 69905
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
Upvotes: 30