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).

Share:
13,988
Micah C
Author by

Micah C

Updated on June 06, 2022

Comments

  • Micah C
    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
    Micah C over 5 years
    I will have to try it later, in cmd it says that it does not contain a package.json file and errors out.
  • Micah C
    Micah C over 5 years
    npm 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
    Harshal Yeole over 5 years
    Check if you are in project directory, what machine you are using, Linux/Mac/Windows?
  • Micah C
    Micah C over 5 years
    I am -- I installed a couple other packages after that error and they worked fine
  • Micah C
    Micah C over 5 years
    I'm using Windows
  • Harshal Yeole
    Harshal Yeole over 5 years
    hit dir and see if you see package.json file
  • Emanuele Benedetti
    Emanuele Benedetti over 3 years
    Unfortunately 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
    Tazaf about 3 years
    You say "not use external lib", and yet, both your examples use moment... Am I missing something?
  • Akrion
    Akrion about 3 years
    The accepted solution uses moment-business-days vs just moment was my point.
  • Nebulosar
    Nebulosar about 2 years
    Is 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.