如何使用 Moment.js 排除两个日期之间的周末

IT技术 javascript jquery momentjs
2021-02-10 10:19:15

我试图在我的 JavaScript 代码中排除周末。我使用 moment.js 并且难以为“天”选择正确的变量。

到目前为止,我认为我需要通过将工作日变量更改为仅从第 1 天计数到第 5 天来排除第 6 天(星期六)和第 0 天(星期日)。但不确定它是如何变化的。

我的 jsfiddle 显示在这里:FIDDLE

HTML :

<div id="myContent">
<input type="radio" value="types" class="syncTypes" name="syncTypes"> <td><label for="xshipping.xshipping1">Free Shipping: (<span id="fsv1" value="5">5</span> to <span id="fsv2" value="10">10</span> working days)</label> </td><br>
    <div id="contacts" style="display:none;border:1px #666 solid;padding:3px;top:15px;position:relative;margin-bottom:25px;">     
    Contacts
</div>
<input type="radio" value="groups" class="syncTypes" name="syncTypes"> <td><label for="xshipping.xshipping2">Express Shipping: (<span id="esv1" value="3">3</span> to <span id="esv2" value="4">4</span> working days)</label> </td>    
<div id="groups" style="display:none;border:1px #666 solid;padding:3px;top:15px;position:relative">     
    Groups
</div>
</div>

JavaScript :

var a = 5; //Free shipping between a
var b = 10;//and b
var c = 3;//Express shipping between c
var d = 4;//and d    
var now = moment();    
var f = "Your item will be delivered between " + now.add("days",a).format("Do MMMM") + " and " + now.add("days",b).format("Do MMMM");
var g = "Your item will be delivered between " + now.add("days".c).format("Do MMMM") + " and " + now.add("days",d).format("Do MMMM");

var h = document.getElementById('contacts');
h.innerHTML = g

var i = document.getElementById('groups');
i.innerHTML = f

$(function() {
    $types = $('.syncTypes');
    $contacts = $('#contacts');
    $groups = $('#groups');
    $types.change(function() {
        $this = $(this).val();
        if ($this == "types") {
            $groups.slideUp(300);
            $contacts.delay(200).slideDown(300);
        }
        else if ($this == "groups") {
            $contacts.slideUp(300);
            $groups.delay(200).slideDown(300);
        }
    });
});
6个回答

干得好!

function addWeekdays(date, days) {
  date = moment(date); // use a clone
  while (days > 0) {
    date = date.add(1, 'days');
    // decrease "days" only if it's a weekday.
    if (date.isoWeekday() !== 6 && date.isoWeekday() !== 7) {
      days -= 1;
    }
  }
  return date;
}

你这样称呼

var date = addWeekdays(moment(), 5);

我使用.isoWeekday而不是.weekday因为它不依赖于语言环境(.weekday(0)可以是星期一或星期日)。

不要减去工作日,addWeekdays(moment(), -3)否则这个简单的函数将永远循环!

更新了 JSFiddle http://jsfiddle.net/Xt2e6/39/(使用不同的 momentjs cdn)

巧妙地使用while循环
2021-03-15 10:19:15
问题在于它使用了一个循环,所以它不会扩展
2021-04-03 10:19:15
好的。我现在使用这个版本。但我已经修改为:var inc = days / Math.abs(days);将 while 条件更新为days != 0并更改了1to的出现次数inc这样我就可以“添加”一个负数的工作日。
2021-04-05 10:19:15
不错的片段,谢谢!date = date.add(1, 'days');可能就像date.add(1, 'days');Moment 实例是可变的
2021-04-11 10:19:15

那些迭代循环解决方案不适合我的需求。他们对于大量的人来说太慢了。所以我做了我自己的版本:

https://github.com/leonardosantos/momentjs-business

希望你觉得它有用。

那么......我如何添加两个矩对象并且只使用它获得工作日?
2021-03-16 10:19:15
@BillyTom moment-business-days现在有 businessDiff
2021-03-23 10:19:15
@ppumkin:还有moment-business-days,但它没有 diff 功能。
2021-04-13 10:19:15

https://github.com/andruhon/moment-weekday-calc插件momentJS 可能对类似任务有帮助

它不能解决确切的问题,但可以计算范围内的特定工作日。

用法:

moment().isoWeekdayCalc({  
  rangeStart: '1 Apr 2015',  
  rangeEnd: '31 Mar 2016',  
  weekdays: [1,2,3,4,5], //weekdays Mon to Fri
  exclusions: ['6 Apr 2015','7 Apr 2015']  //public holidays
}) //returns 260 (260 workdays excluding two public holidays)

如果你想要一个纯 JavaScript 版本(不依赖于 Moment.js)试试这个......

function addWeekdays(date, days) {
    date.setDate(date.getDate());
    var counter = 0;
        if(days > 0 ){
            while (counter < days) {
                date.setDate(date.getDate() + 1 ); // Add a day to get the date tomorrow
                var check = date.getDay(); // turns the date into a number (0 to 6)
                    if (check == 0 || check == 6) {
                        // Do nothing it's the weekend (0=Sun & 6=Sat)
                    }
                    else{
                        counter++;  // It's a weekday so increase the counter
                    }
            }
        }
    return date;
}

你这样叫...

var date = addWeekdays(new Date(), 3);

此函数在接下来的每一天检查它是在星期六(第 6 天)还是星期日(第 0 天)。如果为真,则计数器不会增加,但日期会增加。这个脚本适用于像一个月或更短的小日期增量。

我建议在 moment 原型中添加一个函数。

也许像这样的东西?(未经测试)

    nextWeekday : function () {
        var day = this.clone(this);
        day = day.add('days', 1);
        while(day.weekday() == 0 || day.weekday() == 6){
          day = day.add("days", 1);              
        }
        return day;
    },
    nthWeekday : function (n) {
        var day = this.clone(this);
        for (var i=0;i<n;i++) {
          day = day.nextWeekday();
        }
        return day;
    },

当您完成并编写了一些测试后,发送请求以获取奖励积分。