JavaScript如何计算两个日期间排除周末及节假日的工作日天数
实现方案
原有逻辑已经实现了周末排除,我们只需要在原有计算结果的基础上,扣除落在日期区间内、且本身属于工作日的节假日数量即可,避免重复扣除本来就属于周末的节假日。
改造后代码
import moment from 'moment'; export const workday_count = (start: moment.Moment, end: moment.Moment, holidays: string[] = []) => { // 原有排除周末的计算逻辑 const first = start.clone().endOf('week'); const last = end.clone().startOf('week'); const days = (last.diff(first, 'days') * 5) / 7; let wfirst = first.day() - start.day(); if (start.day() === 6) --wfirst; let wlast = end.day() - last.day(); if (end.day() === 5) --wlast; const baseWorkDays = wfirst + Math.floor(days) + wlast; // 统计需要扣除的工作日节假日数量 let holidayCount = 0; // 格式化区间边界为YYYY-MM-DD避免时间部分干扰判断 const startStr = start.format('YYYY-MM-DD'); const endStr = end.format('YYYY-MM-DD'); holidays.forEach(holidayStr => { const holiday = moment(holidayStr); const holidayFormat = holiday.format('YYYY-MM-DD'); // 判断节假日是否在查询区间内 if (holidayFormat >= startStr && holidayFormat <= endStr) { // 判断是否为周一至周五(周末本就没计入基础工作日,无需重复扣除) const dayOfWeek = holiday.day(); if (dayOfWeek >= 1 && dayOfWeek <=5) { holidayCount++; } } }); return baseWorkDays - holidayCount; };
逻辑说明
- 保留原有排除周末的基础工作日计算逻辑,得到基础有效天数
baseWorkDays - 遍历传入的节假日数组,逐个校验两个条件:
- 节假日是否落在
[start, end]的闭区间内 - 节假日是否属于周一至周五
- 节假日是否落在
- 符合两个条件的节假日总数即为需要额外扣除的天数,最终返回
基础有效天数 - 扣除天数
测试验证
针对你给出的示例场景:
const holidays = ['2021-1-13','2021-1-14','2021-1-15','2021-1-16','2021-1-17','2021-1-18']; const start = moment('2021-1-10'); const end = moment('2021-1-20'); console.log(workday_count(start, end, holidays)); // 输出4
计算结果和预期完全一致。
注意事项
- 建议统一所有日期的时间部分为0点,避免因携带时分秒参数导致区间判断偏差
- 如果节假日数组的日期格式不是
YYYY-M-D,需要调整moment的解析规则,保证日期解析正确
内容的提问来源于stack exchange,提问作者Ammar ALSananni
相关产品推荐
相关产品推荐

