如何使用 moment.js 添加天数,不包括周末?

Mic*_*h C 11 javascript node.js momentjs typescript angular

我正在设置一个从当前日期开始两天的默认后续日期,目前有效:

const Notify = moment().add(2, 'days').toDate();
Run Code Online (Sandbox Code Playgroud)

但是,我想排除周末。所以我安装了 moment WeekDay,但我似乎无法让它在当前日期中添加天数。该文件要求:

moment().weekday(0)
Run Code Online (Sandbox Code Playgroud)

但是我无法在两天内添加它。有任何想法吗?

zec*_*ude 14

这个解决方案很简单,易于遵循,对我来说效果很好:

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;
}
Run Code Online (Sandbox Code Playgroud)


Har*_*hal 8

尝试:时刻-工作日

它应该可以帮助你。

例子:

var momentBusinessDays = require("moment-business-days")

momentBusinessDays('20-09-2018', 'DD-MM-YYYY').businessAdd(3)._d 
Run Code Online (Sandbox Code Playgroud)

结果:

Tue Sep 25 2018 00:00:00 GMT+0530 (IST)
Run Code Online (Sandbox Code Playgroud)


Akr*_*ion 6

您也不能使用外部库并执行以下两个之一的简单功能:

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'))
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
Run Code Online (Sandbox Code Playgroud)

它们从这篇文章中略有修改,我认为是您必须携带/处理的外部库的一个很好的替代品(假设这是您唯一需要的部分,而不是该库的其他功能)。


小智 1

评价最高的解决方案不太冗长,但使用循环一次添加天数,而不是提前计算要添加的日历天数。

已发布的其他解决方案尝试计算,但它们要么不起作用,要么存在无法处理的边缘情况(例如,如果原始日期恰好是周末怎么办?)

如果您想处理不同地区的假期并利用库的其他功能,那么使用 moment-business-days 的建议是很好的,但是(IMO)如果我们只是坚持 OP 的要求,即“添加X 天,跳过周六和周日。”

无论如何,我最近不得不在一个项目上这样做,这是我想出的解决方案:

const addBusinessDaysToDate = (date, businessDays) => {
    // bit of type checking, and making sure not to mutate inputs :: 
    const momentDate = date instanceof moment ? date.clone() : moment(date);

    if (!Number.isSafeInteger(businessDays) || businessDays <= 0) {
        // handle these situations as appropriate for your program; here I'm just returning the moment instance :: 
        return momentDate;
    } else {
        // for each full set of five business days, we know we want to add 7 calendar days :: 
        const calendarDaysToAdd = Math.floor(businessDays / 5) * 7;
        momentDate.add(calendarDaysToAdd, "days");
        
        // ...and we calculate the additional business days that didn't fit neatly into groups of five :: 
        const remainingDays = businessDays % 5;
        
        // if the date is currently on a weekend, we need to adjust it back to the most recent Friday :: 
        const dayOfWeekNumber = momentDate.day();
        if (dayOfWeekNumber === 6) {
            // Saturday -- subtract one day :: 
            momentDate.subtract(1, "days"); 
        } else if (dayOfWeekNumber === 0) {
            // Sunday -- subtract two days :: 
            momentDate.subtract(2, "days");
        }

        // now we need to deal with any of the remaining days calculated above :: 
        if ((momentDate.day() + remainingDays) > 5) {
            // this means that adding the remaining days has caused us to hit another weekend; 
            // we must account for this by adding two extra calendar days :: 
            return momentDate.add(remainingDays + 2, "days");
        } else {
            // we can just add the remaining days :: 
            return momentDate.add(remainingDays, "days");
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

这是一个快速小测试脚本的结果:

_________________________________________
Original Date ::  2023-10-28
Plus  3  Business Days ::  2023-11-01
Plus  10  Business Days ::  2023-11-10
Plus  14  Business Days ::  2023-11-16
Plus  15  Business Days ::  2023-11-17
Plus  22  Business Days ::  2023-11-28

_________________________________________
Original Date ::  2023-10-29
Plus  3  Business Days ::  2023-11-01
Plus  10  Business Days ::  2023-11-10
Plus  14  Business Days ::  2023-11-16
Plus  15  Business Days ::  2023-11-17
Plus  22  Business Days ::  2023-11-28

_________________________________________
Original Date ::  2023-10-30
Plus  3  Business Days ::  2023-11-02
Plus  10  Business Days ::  2023-11-13
Plus  14  Business Days ::  2023-11-17
Plus  15  Business Days ::  2023-11-20
Plus  22  Business Days ::  2023-11-29

_________________________________________
Original Date ::  2023-10-31
Plus  3  Business Days ::  2023-11-03
Plus  10  Business Days ::  2023-11-14
Plus  14  Business Days ::  2023-11-20
Plus  15  Business Days ::  2023-11-21
Plus  22  Business Days ::  2023-11-30

_________________________________________
Original Date ::  2023-11-01
Plus  3  Business Days ::  2023-11-06
Plus  10  Business Days ::  2023-11-15
Plus  14  Business Days ::  2023-11-21
Plus  15  Business Days ::  2023-11-22
Plus  22  Business Days ::  2023-12-01

_________________________________________
Original Date ::  2023-11-02
Plus  3  Business Days ::  2023-11-07
Plus  10  Business Days ::  2023-11-16
Plus  14  Business Days ::  2023-11-22
Plus  15  Business Days ::  2023-11-23
Plus  22  Business Days ::  2023-12-04

_________________________________________
Original Date ::  2023-11-03
Plus  3  Business Days ::  2023-11-08
Plus  10  Business Days ::  2023-11-17
Plus  14  Business Days ::  2023-11-23
Plus  15  Business Days ::  2023-11-24
Plus  22  Business Days ::  2023-12-05
Run Code Online (Sandbox Code Playgroud)