比如今天是2021.06.20,调用的时候返回2021.06.18?
不考虑节假日,只考虑周六周日作为休息日的情况很简单,就是根据当前是星期几来处理个日期计算就好
function lastWorkday(d) {
const date = new Date(d);
const day = date.getDay();
// 0,星期天,往前 2 天(迈过当天和周六)
// 1 往前 3 天(万过当天,周日和周六
// 其他往前 1 天
const diff = day == 0 ? -2 : day == 1 ? -3 : -1;
date.setDate(date.getDate() + diff);
return date;
}
如果要考虑节假日的情况,因为节假日没办法计算出来,只能事件定义作为参数传入。
而判断方法其实就可以查表,查到了就往前推一天继续查,直到找到不是周末也不在假日表里的为止。这是一个循环,但是需要考虑一个容错处理,万一表配错了,会存在死循环的情况。考虑到目前节假日含周末最长周期只有 7 天,所以可以将循环限制在 7 次以内。
function lastWorkday(d, holidays) {
// 假设 holidays 中的日期是按标准的 yyyy-MM-dd 格式提供的
const date = new Date(d);
for (let i = 0; i < 7; i++) {
// 先往前挪一天
date.setDate(date.getDate() - 1);
// 如果是周末,继续找
if (date.getDay() === 0 || date.getDay() === 6) { continue; }
// 如果是节假日,继续找
if (holidays.includes(format(date))) { continue; }
// 都不是,那就说明已经找到了
break;
}
return date;
function format(date) {
return [
date.getFullYear(),
`${date.getMonth() + 1}`.padStart(2, "0"),
`${date.getDate()}`.padStart(2, "0"),
].join("-");
}
}
// 测试
[
"2022-06-08", // 2022-06-07
"2022-06-07", // 2022-06-06
"2022-06-06", // 2022-05-31,6-5 是周日,6-1~3 设置为节日
"2022-06-05", // 2022-05-31
"2022-06-04", // 2022-05-31
].map(d => lastWorkday(d, ["2022-06-03", "2022-06-02", "2022-06-01"]))
.forEach(d => console.log(d));
已参与了 SegmentFault 思否社区 10 周年「问答」打卡 ,欢迎正在阅读的你也加入。
10 回答11.1k 阅读
6 回答3k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3k 阅读✓ 已解决
2 回答2.6k 阅读✓ 已解决
3 回答5.1k 阅读✓ 已解决
3 回答1.8k 阅读✓ 已解决
如果不考虑特殊节假日,
Date
对象的getDay()
方法可以返回星期中的第几天,值为 0 - 6 分别对应周日 - 周六,因此可以简单处理:当然如果引入诸如
moment.js
这类的时间库,处理这类问题会更加简单