如何使用 Moment JS 计算范围之间的给定工作日数?

Posted

技术标签:

【中文标题】如何使用 Moment JS 计算范围之间的给定工作日数?【英文标题】:How do I calculate number of given weekday between range using Moment JS? 【发布时间】:2015-05-19 09:30:30 【问题描述】:

如何使用 Moment JS 和 jQuery 找出给定工作日(例如:星期二)中有多少在日期范围内?

我可以使用差值找到天数: http://momentjs.com/docs/#/displaying/difference/

而且我知道开始和结束日期,所以我觉得应该可以?

示例:3 月 1 日至 3 月 25 日之间有多少个星期二?

【问题讨论】:

【参考方案1】:

如果您要查找 NM两个日期之间的工作日数W(例如星期一、星期二……) >,你可以:

    N 之后查找 W 的下一个出现 N'。 求 N'M 之间的天数。 如果 N'M 之后,则中间没有 W。否则,W 天的天数应该是 1 + floor((M-N)/7)
function getWeekdaysBetweenDates(firstDate, secondDate, dayOfWeek) 
    var MILISECONDS_IN_DAY = 86400000;

    function getNextDayOfWeek(date, dayOfWeek) 
        date.setDate(date.getDate() + (7 + dayOfWeek - date.getDay()) % 7);
        return date;
    

    firstDate = getNextDayOfWeek(firstDate, dayOfWeek);
    if (firstDate > secondDate) 
        return 0;
    

    return 1 + Math.floor(((secondDate - firstDate) / MILISECONDS_IN_DAY) / 7);


var firstDate = new Date("March 1, 2015");
var secondDate = new Date("March 25, 2015");
console.log(getWeekdaysBetweenDates(firstDate, secondDate, 2));
// 4

【讨论】:

这是我发布的代码的 vanilla JS 版本,它使用了等效的 MomentJS 方法。很高兴得到验证,我的算法是正确的。【参考方案2】:

我想出了以下功能,似乎适用于我尝试过的给定少数测试用例:

function weekdaysBetween(d1, d2, isoWeekday) 
    // ensure we have valid moment instances
    d1 = moment(d1);
    d2 = moment(d2);
    // figure out how many days to advance to get to the next
    // specified weekday (might be 0 if d1 is already the 
    // specified weekday).
    var daysToAdd = ((7 + isoWeekday) - d1.isoWeekday()) % 7;
    var nextTuesday = d1.clone().add(daysToAdd, 'days');
    // if we are already passed the end date, there must not
    // be any of that day in the given period.
    if (nextTuesday.isAfter(d2)) 
        return 0;
    
    // otherwise, just return the whole number of weeks
    // difference plus one for the day we already advanced to
    var weeksBetween = d2.diff(nextTuesday, 'weeks');
    return weeksBetween + 1;

您传入isoWeekday 值,表示您要计算的那一天。例如周二,请输入2

示例调用:

var d1 = moment('2015-03-01');
var d2 = moment('2015-03-25');

console.log('result:', weekdaysBetween(d1, d2, 2)); // => result: 4

Wolfram Alpha gives the same result.

不过,您应该在完全信任之前添加自己的测试。

【讨论】:

我稍微调整并扩展了它以使其具有包容性(例如,范围从 2018 年 1 月 1 日星期一到同一个星期一,星期一将返回 1)。我还编写了一些基本测试(针对 Jest / Jasmine)——如果对某人有用,请参阅 this gist。 这对我有用。对我来说,我想简单地计算星期天,然后是星期六,它按预期工作。【参考方案3】:

https://github.com/andruhon/moment-weekday-calc 满足您的需求。 它计算范围内的特定工作日,并可选择排除特定日期(例如公共假期)

用法:

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)

【讨论】:

需要获取日期列表:-)【参考方案4】:

如果你像我一样对数学感到困惑:

var startDate = moment().startOf('month');
var endDate = moment().endOf('month');

var aDate = moment(startDate).day('Sunday');

var weekDays = 0;
while (aDate.isSameOrBefore(endDate)) 
   if (aDate.isSameOrAfter(startDate) && aDate.isSameOrBefore(endDate))
        weekDays++;
   aWeekDayDate.add(1, 'week');

【讨论】:

以上是关于如何使用 Moment JS 计算范围之间的给定工作日数?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 moment.js 获取日期范围

如何在moment js中得到N个日期之间的差异?

Moment.js - 显示选定范围内关于用户时区的历史数据

如何比较给定时间,落在特定时间范围之间 - javascript

使用 moment.js 设置可变日期值

Moment.js - 我如何获得自日期以来的年数,而不是四舍五入?