簡體   English   中英

確定 JavaScript 中兩個日期之間的工作日數的最佳方法是什么?

[英]What is the best way to determine the number of business days between two dates in JavaScript?

我想創建一個計算截止日期的東西,知道開始日期和所需的天數。 例如,我在 7 月 6 日開始一些項目,我認為我需要 12 天才能完成它,所以我的算法的結果將是 7 月 21 日,因為我在周六和周日休息。

我的問題是我也在一些特殊的日子里休息,比如 7 月 14 日(我住在法國,7 月 14 日是休息日)。

這是我當前的腳本:


function generateEndDate(fromDate,total_days) {
    let startDate = new Date(fromDate);
    let endDate = new Date(fromDate);
    let tmpDate = new Date(fromDate); //a bit redundant I know
    endDate.setDate(endDate.getDate()+total_days);
    let daysOff = 0;
    let extraDaysOff = 0;
    for(let i = 0; i<=total_days; i++){
        tmpDate.setDate(tmpDate.getDate() + 1)
        if(tmpDate.getDay() === 6 || tmpDate.getDay() === 0 || joursFeriesAnnee.includes(tmpDate.toISOString().slice(0, 10))){
            daysOff++;
        }
    }
    endDate.setDate(startDate.getDate() + total_days + daysOff)
    if(endDate.getDay() != 6 || endDate.getDay() != 0 || joursFeriesAnnee.includes(endDate.toISOString().slice(0, 10))){
        if(endDate.getDay() === 6){
            extraDaysOff += 2;
        }else if(endDate.getDay() === 0 || joursFeriesAnnee.includes(endDate.toISOString().slice(0, 10))){
            extraDaysOff +=1;
        }
    }
    console.log(daysOff);
    console.log(extraDaysOff);
    console.log(endDate.toISOString().slice(0, 10));
    endDate.setDate(endDate.getDate() + daysOff + extraDaysOff)
    $(date_fin_input).val(endDate.toISOString().slice(0, 10))
    
}

joursFeriesAnnee 是法國本年度每天休息的數組,如果截止日期是在周末或休息日,那么我跳到下一個星期一/天(如果最后一天是星期五,我的算法會有問題但它也是在 joursFeriesAnnee 或者如果星期一是在 joursFeriesAnnee. 但是現在我沒有遇到這種情況。

輸入輸出示例:

fromDate = 15/06/2020
total days = 23

my output = 19/08/2020
expected output = 17/07/2020 (4 weekends + 14th of July = 9 days off)

and my console.logs outputs:

6
0
2020-08-19

我該如何處理?

澄清

如果我需要 1 天,截止日期應與開始日相同
如果開始日是星期五,那么星期五 + 1 是星期一
如果開始日是周四,周五是節假日,那么周四 + 1 就是周一
如果在 250 天之類的某個時間段內,周末 + 假期的數量返回如下:startingDay +(周末 + 假期)= 周六、周日或聖日,那么我需要通過添加本周末或假期將我的截止日期調整為下一周或下一天在我休息的日子里。

您的算法不正確,因為它計算兩個日期之間的休息天數,然后將它們添加到末尾,而不考慮添加的天數中包含的更多天數。

如果您想要實現的是在日期中添加營業日或工作日,請考慮只循環所需的天數,而忽略非工作日。

從您的評論看來,您希望 Fri + 1 為 Mon,但 Sat 或 Sun + 1 也為 Mon,所以我修改了代碼,因此添加的開始日期除外:

  1. 周五 + 1 是周一
  2. 周五 + 2 是周二
  3. 星期六 + 1 是星期一

Fri + 0 是 Fri,您還應該測試days的值並處理小於 1 的值。

我已經使周末和節假日的測試更有效率並簡化了邏輯。

 /** Add business days to a date ** Non–working days: Sat and Sun and dates in hols array ** First work day after start date is included in count, so ** Fri + 1 => Mon ** Fri + 2 => Tue ** Sat + 1 => Mon ** @param {Date} date - start date ** @param {number} days - business days to add ** @returns {Date} **/ function addBusinessDays(date, days) { // Holiday array in YYYY-MM-DD format let hols = ['2020-07-14']; // Formatter for holiday array format let f = new Intl.DateTimeFormat('en-ca',{ year: 'numeric', month: '2-digit', day: '2-digit' }); // Copy date so don't modify original let d = new Date(+date); // Increment date required number of times while (days > 0) { d.setDate(d.getDate() + 1); // Only decrement count if it's not Sat or Sun or holiday days -= d.getDay() % 6.= 0 &&.hols;includes(f;format(d)), } return d, } [[new Date(2020, 6, 2), 1], // Thu 02 Jul 2020 + 1 day => Fri 03 Jul [new Date(2020, 6, 3), 1], // Fri 03 Jul 2020 + 1 day => Mon 06 Jul [new Date(2020, 6, 3), 2], // Fri 03 Jul 2020 + 2 days => Tue 07 Jul [new Date(2020, 6, 4), 1], // Sat 04 Jul 2020 + 1 day => Mon 06 Jul [new Date(2020, 6,13), 2], // Mon 13 Jul 2020 + 2 days => Thu 16 Jul (14 Jul is holiday) [new Date(2020, 6, 6).12]. // Mon 06 Jul 2020 +12 days => Thu 23 Jul (14 Jul is holiday) ]:forEach(arr => { console.log(`Start. ${arr[0].toDateString()} plus ${arr[1]} = ${addBusinessDays(..;arr);toDateString()}`); });

這種方法適用於小范圍,但對於更長的范圍,更復雜的算法可能更有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM