You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaScript计算符合工作日规则的结束日期?

计算排除周末的工作结束日期

需求说明

  • 输入:起始日期、工作时长(小时数)
  • 输出:实际工作日的结束日期(排除周六和周日)
  • 规则:
    • 工作周为周一至周五,共5天
    • 每日工作时长8小时

现有问题

当前实现仅能正确处理整周的情况,非整周场景计算结果有误,代码如下:

function formatDate(date) {
    var d = new Date(date),
        month = '' + (d.getMonth() + 1),
        day = '' + d.getDate(),
        year = d.getFullYear();

    if (month.length < 2) month = '0' + month;
    if (day.length < 2) day = '0' + day;
    return [year, month, day].join('-');
}

$('#startTimeProject,#doTimeProject').change(function() {
    var startTime = $('#startTimeProject').val();
    var doTime = $('#doTimeProject').val();

    if (doTime == null) {
        return;
    }

    const d = new Date(startTime);
    var currentDay = d.getDay();
    startTime = new Date(startTime);

    if (currentDay == 0) {
        startTime.setDate(startTime.getDate() + 1);
    }
    if (currentDay == 6) {
        startTime.setDate(startTime.getDate() + 2);
    }

    startTime = Date.parse(startTime);
    $('#startTimeProject').val(formatDate(startTime));
    var numberWeek = Math.floor(doTime / 40);

    if (numberWeek >= 1) {
        doTime = Number(doTime) + numberWeek * 16;
    }

    var dayTime = Math.ceil(doTime / 8);
    var endTime = new Date(startTime);
    endTime.setDate(endTime.getDate() + dayTime);
    endTime = Date.parse(endTime);
    $('#endTimeProject').val(formatDate(endTime));
})

解决方案

核心思路是逐天迭代,跳过周末,累计工作日天数,直到达到所需的工作日总数,能覆盖所有整周/非整周场景。

修正后的代码

function formatDate(date) {
    const d = new Date(date);
    const month = String(d.getMonth() + 1).padStart(2, '0');
    const day = String(d.getDate()).padStart(2, '0');
    const year = d.getFullYear();
    return `${year}-${month}-${day}`;
}

function getEndWorkDate(startDate, workHours) {
    const dailyHours = 8;
    const workDaysNeeded = Math.ceil(workHours / dailyHours);
    const currentDate = new Date(startDate);
    
    // 将起始日期调整为工作日
    const dayOfWeek = currentDate.getDay();
    if (dayOfWeek === 0) { // 周日调整到周一
        currentDate.setDate(currentDate.getDate() + 1);
    } else if (dayOfWeek === 6) { // 周六调整到周一
        currentDate.setDate(currentDate.getDate() + 2);
    }
    
    let workDaysCounted = 0;
    // 循环累计工作日,跳过周末
    while (workDaysCounted < workDaysNeeded) {
        const currentDay = currentDate.getDay();
        // 仅统计周一至周五
        if (currentDay !== 0 && currentDay !== 6) {
            workDaysCounted++;
            // 达到目标天数时停止循环
            if (workDaysCounted === workDaysNeeded) break;
        }
        currentDate.setDate(currentDate.getDate() + 1);
    }
    
    return currentDate;
}

$('#startTimeProject,#doTimeProject').change(function() {
    const startTime = $('#startTimeProject').val();
    const doTime = $('#doTimeProject').val();

    if (!doTime) return;

    // 调整起始日期为工作日并更新输入框
    const adjustedStartDate = new Date(startTime);
    const dayOfWeek = adjustedStartDate.getDay();
    if (dayOfWeek === 0) {
        adjustedStartDate.setDate(adjustedStartDate.getDate() + 1);
    } else if (dayOfWeek === 6) {
        adjustedStartDate.setDate(adjustedStartDate.getDate() + 2);
    }
    $('#startTimeProject').val(formatDate(adjustedStartDate));

    // 计算并设置结束日期
    const endDate = getEndWorkDate(adjustedStartDate, Number(doTime));
    $('#endTimeProject').val(formatDate(endDate));
})

关键说明

  1. 日期格式化优化:使用padStart简化补零逻辑,代码更简洁。
  2. 核心计算逻辑:
    • 先将起始日期调整为工作日,避免从周末开始计算的误差。
    • 通过循环逐天检查日期类型,仅统计周一至周五的工作日,直到累计够所需天数,彻底解决非整周场景的计算问题。
  3. 事件处理拆分:将日期调整和结束日期计算逻辑拆分,代码可读性更强。

内容的提问来源于stack exchange,提问作者unLimit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 12:10:25