用js和jquery 如何获取上一个工作日?

比如今天是2021.06.20,调用的时候返回2021.06.18?

阅读 3.2k
2 个回答

如果不考虑特殊节假日,Date 对象的 getDay() 方法可以返回星期中的第几天,值为 0 - 6 分别对应周日 - 周六,因此可以简单处理:

var today = new Date()
// 调整到本地时间 0 时,如果你的精度只需要到日,那么可略过
today.setHours(0, 0, 0, 0)

var minus = 0;
if (today.getDay() === 6) {
    minus = 86400000; // 周六 - 1 天
} else if (today.getDay() === 0) {
    minus = 86400000 * 2; // 周日 - 2 天
}
var lastWeekDay = new Date(today.getTime() - minus);

console.log(today.toLocaleDateString())
console.log(lastWeekDay.toLocaleDateString());

当然如果引入诸如 moment.js 这类的时间库,处理这类问题会更加简单

不考虑节假日,只考虑周六周日作为休息日的情况很简单,就是根据当前是星期几来处理个日期计算就好

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 周年「问答」打卡 ,欢迎正在阅读的你也加入。
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题