使用moment.js和moment工作日计算考虑公共假日和周末的日期



此应用程序的目的始终是指示每个月的第16个工作日(意味着要考虑工作日和公共假日(。

为此,我使用了moment-business-days,这是一个moment.js插件。它计算日期并考虑工作日和(预先配置的(公共假日。我按如下方式使用它,对于某些日期,它会给我正确的结果,但对于其中一些日期,它不会。我看不出我代码中的错误:

myHolidays = [
{ holidayDate: "2020-06-01", description: "holiday 1" },
{ holidayDate: "2020-06-02", description: "holiday 2" },
{ holidayDate: "2020-06-03", description: "holiday 3" },  
{ holidayDate: "2020-06-06", description: "weekend saturday" },
{ holidayDate: "2020-06-07", description: "weekend sunday" },
{ holidayDate: "2020-06-11", description: "holiday 6" },
{ holidayDate: "2020-06-13", description: "weekend saturday" },
{ holidayDate: "2020-06-14", description: "weekend sunday" },
{ holidayDate: "2020-06-20", description: "weekend saturday" },
{ holidayDate: "2020-06-21", description: "weekend sunday" },
{ holidayDate: "2020-06-27", description: "weekend saturday" },
{ holidayDate: "2020-06-28", description: "weekend sunday" },
];
moment.updateLocale('de', {
holidays: myHolidays.map(i => i.holidayDate),
holidayFormat: 'YYYY-MM-DD'
});
var startDate = moment("2020-01-01").startOf('month')
var endDate = moment("2020-12-01")
var eachMonthWith16 = [];
function generate16InEachMonth() {
let monthsList = []
// loop by months
while (endDate > startDate) {
monthsList.push(new Date(moment(this.startDate).businessAdd(15, 'days')))
startDate = startDate.add(1, "month").startOf('month')
}
return monthsList
}
console.log(generate16InEachMonth())
.as-console-wrapper { top: 0; max-height: 100% !important; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.27.0/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-business-days/1.2.0/index.js"></script>

在这个例子中,我得到了以下日期,有时是正确的,有时不是:

Month  Actual  Target  Correct
Jan    22      22      yes
Feb    24      21      no
March  23      20      no
April  22      22      yes
May    22      22      yes
June   25      26      no
July   22      22      yes
...

有没有一种快速的方法来解决这个问题,或者有没有类似的日期时间处理库,可以处理工作日并完美地计算它们?

代码不适用于所有月份的原因是,默认情况下,该月的第一天算作工作日。

区分第一天是否真的是工作日的条件就足够了(如果第一天本身不是工作日,则增加16个工作日(。

function generate16InEachMonth() {
let monthsList = []
// loop by months
while (endDate > startDate) {
var daysToAdd = (startDate.isBusinessDay()) ? 15 : 16
monthsList.push(new Date(moment(this.startDate).businessAdd(daysToAdd, 'days')))
startDate = startDate.add(1, "month").startOf('month')
}
return monthsList
}

相关内容

  • 没有找到相关文章