如何使用 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】:如果您要查找 N 和 M两个日期之间的工作日数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 - 显示选定范围内关于用户时区的历史数据