我设置了当前日期两天后的默认后续日期,目前有效:
const Notify = moment().add(2, 'days').toDate();
但是,我想排除周末。所以我安装了 moment WeekDay,但我似乎无法让它在当前日期中添加天数。该文档要求:
moment().weekday(0)
但是我无法在两天后添加它。有任何想法吗?
这个解决方案很简单,易于遵循,并且对我来说效果很好:
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;
}
尝试:时刻-工作日
应该对你有帮助。
示例:
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)
您也可以不使用外部库并执行像这两个之一这样的简单功能:
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'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
它们对这篇文章进行了稍微修改,我认为它们是您必须携带/处理的外部库的一个很好的替代方案(假设这是您唯一需要的部分,而不是该库的其他功能)。
这将基于任何开始日期来执行此操作,并且没有昂贵的循环。您计算需要跳过的周末天数,然后将工作日和周末的天数一起抵消。
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;
}
const addWorkingDays = (date: Moment, days: number) => {
let newDate = date.clone();
for (let i = 0; i < days; i++) {
if (newDate.isoWeekday() !== 6 && newDate.isoWeekday() !== 7) {
newDate = newDate.add(1, "days");
} else {
newDate = newDate.add(1, "days");
i--;
}
}
return newDate.format("YYYY/MM/DD");
};
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')
}
我认为这段代码会更快:
var businessDays = 10;
var days = businessDays + Math.floor((Math.min(moment().day(),5)+businessDays)/6)*2;
moment.add(days, 'days');
// using pure JS
function addBusinessDays(originalDate, numDaysToAdd) {
const Sunday = 0;
const Saturday = 6;
let daysRemaining = numDaysToAdd;
const newDate = originalDate;
while (daysRemaining > 0) {
newDate.setDate(newDate.getDate() + 1);
if (newDate.getDay() !== 0 && newDate.getDay() !== 6) {
// skip sunday & saturday
daysRemaining--;
}
}
return newDate;
}
var dt = new Date(); // get date
var business_days = 8;
newDate = addBusinessDays(dt, business_days);
console.log(newDate.toString());
评价最高的解决方案不太冗长,但使用循环一次添加天数,而不是提前计算要添加的日历天数。
已发布的其他解决方案尝试计算,但它们要么不起作用,要么存在无法处理的边缘情况(例如,如果原始日期恰好是周末怎么办?)
如果您想处理不同地区的假期并利用库的其他功能,那么使用“时刻工作日”的建议很好,但是(IMO)如果我们只是坚持 OP 的要求,即“添加 X 天,跳过周六和周日。”
无论如何,我最近不得不在一个项目中这样做,这是我想出的解决方案:
const addBusinessDaysToDate = (date, businessDays) => {
// bit of type checking, and making sure not to mutate inputs ::
const momentDate = date instanceof moment ? date.clone() : moment(date);
if (!Number.isSafeInteger(businessDays) || businessDays <= 0) {
// handle these situations as appropriate for your program; here I'm just returning the moment instance ::
return momentDate;
} else {
// for each full set of five business days, we know we want to add 7 calendar days ::
const calendarDaysToAdd = Math.floor(businessDays / 5) * 7;
momentDate.add(calendarDaysToAdd, "days");
// ...and we calculate the additional business days that didn't fit neatly into groups of five ::
const remainingDays = businessDays % 5;
// if the date is currently on a weekend, we need to adjust it back to the most recent Friday ::
const dayOfWeekNumber = momentDate.day();
if (dayOfWeekNumber === 6) {
// Saturday -- subtract one day ::
momentDate.subtract(1, "days");
} else if (dayOfWeekNumber === 0) {
// Sunday -- subtract two days ::
momentDate.subtract(2, "days");
}
// now we need to deal with any of the remaining days calculated above ::
if ((momentDate.day() + remainingDays) > 5) {
// this means that adding the remaining days has caused us to hit another weekend;
// we must account for this by adding two extra calendar days ::
return momentDate.add(remainingDays + 2, "days");
} else {
// we can just add the remaining days ::
return momentDate.add(remainingDays, "days");
}
}
};
这是一个快速小测试脚本的结果:
_________________________________________
Original Date :: 2023-10-28
Plus 3 Business Days :: 2023-11-01
Plus 10 Business Days :: 2023-11-10
Plus 14 Business Days :: 2023-11-16
Plus 15 Business Days :: 2023-11-17
Plus 22 Business Days :: 2023-11-28
_________________________________________
Original Date :: 2023-10-29
Plus 3 Business Days :: 2023-11-01
Plus 10 Business Days :: 2023-11-10
Plus 14 Business Days :: 2023-11-16
Plus 15 Business Days :: 2023-11-17
Plus 22 Business Days :: 2023-11-28
_________________________________________
Original Date :: 2023-10-30
Plus 3 Business Days :: 2023-11-02
Plus 10 Business Days :: 2023-11-13
Plus 14 Business Days :: 2023-11-17
Plus 15 Business Days :: 2023-11-20
Plus 22 Business Days :: 2023-11-29
_________________________________________
Original Date :: 2023-10-31
Plus 3 Business Days :: 2023-11-03
Plus 10 Business Days :: 2023-11-14
Plus 14 Business Days :: 2023-11-20
Plus 15 Business Days :: 2023-11-21
Plus 22 Business Days :: 2023-11-30
_________________________________________
Original Date :: 2023-11-01
Plus 3 Business Days :: 2023-11-06
Plus 10 Business Days :: 2023-11-15
Plus 14 Business Days :: 2023-11-21
Plus 15 Business Days :: 2023-11-22
Plus 22 Business Days :: 2023-12-01
_________________________________________
Original Date :: 2023-11-02
Plus 3 Business Days :: 2023-11-07
Plus 10 Business Days :: 2023-11-16
Plus 14 Business Days :: 2023-11-22
Plus 15 Business Days :: 2023-11-23
Plus 22 Business Days :: 2023-12-04
_________________________________________
Original Date :: 2023-11-03
Plus 3 Business Days :: 2023-11-08
Plus 10 Business Days :: 2023-11-17
Plus 14 Business Days :: 2023-11-23
Plus 15 Business Days :: 2023-11-24
Plus 22 Business Days :: 2023-12-05