【问题标题】:How can I use moment.js to add days, excluding weekends?如何使用 moment.js 添加天数,不包括周末?
【发布时间】:2019-02-24 22:32:55
【问题描述】:

我正在设置一个默认的跟进日期,距当前日期两天,目前有效:

const Notify = moment().add(2, 'days').toDate();

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

moment().weekday(0)

但是我不能让它在两天后添加。有任何想法吗?

【问题讨论】:

    标签: javascript node.js angular typescript momentjs


    【解决方案1】:
    var moment = require("moment")
    function addWorkingDay(date, days){
        let daysToAdd = days
        const today = moment(date);
        const nextWeekStart = today.clone().add(1, 'week').weekday(1);
        const weekEnd = today.clone().weekday(5);
    
        const daysTillWeekEnd = Math.max(0, weekEnd.diff(today, 'days'));
        if(daysTillWeekEnd >= daysToAdd) return today.clone().add(daysToAdd, 'days');
        
        daysToAdd = daysToAdd - daysTillWeekEnd - 1;
        
        return nextWeekStart.add(Math.floor(daysToAdd/5), 'week').add(daysToAdd % 5, 'days')
    }
    

    【讨论】:

      【解决方案2】:

      这将根据任何开始日期进行,并且没有代价高昂的循环。您计算出您需要跳过的周末天数,然后只用工作日和周末的天数来抵消。

      function addWeekdays(year, month, day, numberOfWeekdays) {
          var originalDate = year + '-' + month + '-' + day;
          var futureDate = moment(originalDate);
          var currentDayOfWeek = futureDate.day();            // 0 = Sunday, 1 = Monday, ..., 6 = Saturday
          var numberOfWeekends = Math.floor((currentDayOfWeek + numberOfWeekdays - 1) / 5);   // calculate the number of weekends to skip over
      
          futureDate.add(numberOfWeekdays + numberOfWeekends * 2, 'days');    // account for the 2 days per weekend
      
          return futureDate;
      }
      

      【讨论】:

        【解决方案3】:

        我认为这段代码会更快:

        var businessDays = 10;
        var days = businessDays + Math.floor((Math.min(moment().day(),5)+businessDays)/6)*2;
        moment.add(days, 'days');
        

        【讨论】:

        • 不幸的是,这段代码不起作用。例如,如果在 2020 年 9 月 28 日星期一添加 15 个工作日,我将在 10 月 17 日(星期六)结束。
        【解决方案4】:

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

        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;
        }
        

        【讨论】:

          【解决方案5】:

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

          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'))
          &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"&gt;&lt;/script&gt;

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

          【讨论】:

          • 你说“不使用外部库”,然而,你的两个例子都使用moment...我错过了什么吗?
          • 接受的解决方案使用 moment-business-days 而不是 moment 是我的观点。
          【解决方案6】:

          试试:moment-business-days

          它应该对你有帮助。

          例子:

          var momentBusinessDays = require("moment-business-days")
          
          momentBusinessDays('20-09-2018', 'DD-MM-YYYY').businessAdd(3)._d 
          

          结果:

          Tue Sep 25 2018 00:00:00 GMT+0530 (IST)
          

          【讨论】:

          • 稍后我将不得不尝试它,在 cmd 中它说它不包含 package.json 文件并出现错误。
          • npm 错误!代码 ENOLOCAL npm 错误!无法从“>我的目录
          • 检查你是否在项目目录下,你使用的是什么机器,Linux/Mac/Windows?
          • 我是——我在那个错误之后安装了其他几个包,它们工作正常
          • 我使用的是 Windows
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-04-26
          • 1970-01-01
          • 2017-05-21
          相关资源
          最近更新 更多