How can I use moment.js to add days, excluding weekends?
13,988
Solution 1
Try: moment-business-days
It should help you.
Example:
var momentBusinessDays = require("moment-business-days")
momentBusinessDays('20-09-2018', 'DD-MM-YYYY').businessAdd(3)._d
Result:
Tue Sep 25 2018 00:00:00 GMT+0530 (IST)
Solution 2
This solution is simple, easy to follow, and works well for me:
function addBusinessDays(originalDate, numDaysToAdd) {
const Sunday = 0;
const Saturday = 6;
let daysRemaining = numDaysToAdd;
const newDate = originalDate.clone();
while (daysRemaining > 0) {
newDate.add(1, 'days');
if (newDate.day() !== Sunday && newDate.day() !== Saturday) {
daysRemaining--;
}
}
return newDate;
}
Solution 3
You could also not use external lib and do a simple function like one of these two:
const WEEKEND = [moment().day("Saturday").weekday(), moment().day("Sunday").weekday()]
const addBusinessDays1 = (date, daysToAdd) => {
var daysAdded = 0,
momentDate = moment(new Date(date));
while (daysAdded < daysToAdd) {
momentDate = momentDate.add(1, 'days');
if (!WEEKEND.includes(momentDate.weekday())) {
daysAdded++
}
}
return momentDate;
}
console.log(addBusinessDays1(new Date(), 7).format('MM/DD/YYYY'))
console.log(addBusinessDays1('09-20-2018', 3).format('MM/DD/YYYY'))
// This is the somewhat faster version
const addBusinessDays2 = (date, days) => {
var d = moment(new Date(date)).add(Math.floor(days / 5) * 7, 'd');
var remaining = days % 5;
while (remaining) {
d.add(1, 'd');
if (d.day() !== 0 && d.day() !== 6)
remaining--;
}
return d;
};
console.log(addBusinessDays2(new Date(), 7).format('MM/DD/YYYY'))
console.log(addBusinessDays2('09-20-2018', 3).format('MM/DD/YYYY'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
They are slightly modified from this post and I think are a good alternative to external library you have to carry/deal with (assuming this is the only part you need and not other features of that lib).
Author by
Micah C
Updated on June 06, 2022Comments
-
Micah C almost 2 years
I'm setting a default follow-up date two days from current date, which currently works:
const Notify = moment().add(2, 'days').toDate();
However, I would like to exclude weekends. So I installed moment WeekDay, but I can't seem to get it to work with adding days to the current date. The documentation calls for:
moment().weekday(0)
But I can't get that to work with adding in two days forward. Any ideas?
-
Micah C over 5 yearsI will have to try it later, in cmd it says that it does not contain a package.json file and errors out.
-
Micah C over 5 yearsnpm ERR! code ENOLOCAL npm ERR! Could not install from ">my directory<" as it does not contain a package.json file. E: I installed a couple other packages and they worked fine
-
Harshal Yeole over 5 yearsCheck if you are in project directory, what machine you are using, Linux/Mac/Windows?
-
Micah C over 5 yearsI am -- I installed a couple other packages after that error and they worked fine
-
Micah C over 5 yearsI'm using Windows
-
Harshal Yeole over 5 yearshit
dir
and see if you see package.json file -
Emanuele Benedetti over 3 yearsUnfortunately this code doesn't works. For example if on Monday 28/09/2020 I add 15 working days I'll end up to 17 Oct that is Saturday.
-
Tazaf about 3 yearsYou say "not use external lib", and yet, both your examples use
moment
... Am I missing something? -
Akrion about 3 yearsThe accepted solution uses
moment-business-days
vs justmoment
was my point. -
Nebulosar about 2 yearsIs this code faster? How? Shorter notated? Runtime wise? Someone who would read this in your code will not always understand what is going on here, so he needs time to think it out or being explained about. Also, how would I debug this when it has an unforeseen error? So with that in mind, I would not say this code is faster, merely that it would execute faster.