Помогите разобраться с добавлением рабочих дней к дате

function addWorkingDays(startDate, daysToAdd) {
    console.log("Start date: " + startDate);
    console.log("Days to add: " + daysToAdd);
    let date = startDate;

    for (let i = 1; i <= daysToAdd; i++) {
        // добавляем 1 день
        date = new Date(date).setDate(new Date(date).getDate() + 1);
        // после добавления, если получается суббота - еще добавляем 1 день
        // воскресение - еще добавляем 1 день
        while ( new Date(date).getDay() === 6 || new Date(date).getDay() === 0 ) {
            date = new Date(date).setDate(new Date(date).getDate() + 1);
        }
        // получаем понедельник - выходим из WHILE и итерируем в FOR
    }
    
    let result = new Date(date).toISOString().split('T')[0];
    console.log("Result date: " + result);
    return result;
}

let startDate = new Date(year, month, day);
let endDate = addWorkingDays(startDate, 10);

Что не так с этим кодом? В цикле WHILE можно использовать логическое OR? Аналогичная функция на PHP отрабатывает без проблем... Нерабочими считаем только субботу и воскресенье


Ответы (1 шт):

Автор решения: Дмитрий Тюльпа

Прошу прощения, но похоже сказываются отключения света и сбитый график на внимательности... Всё работает как надо

на PHP

function addWorkingDays(string $startDate, int $daysToAdd): string
{
    $holidays = [ "2023-01-06", "2023-01-10" ];

    echo "From: ".$startDate."<br>";
    echo "Working days to add: ".$daysToAdd."<br>";
    $day = new DateTime($startDate);

    for ($i = 1; $i < $daysToAdd; $i++) {
       $day->modify('+1 day');
       while ( $day->format('w') === "6" || $day->format('w') === "0"
               || ( $day->format('w') !== "6" && $day->format('w') !== "0" && in_array($day->format('Y-m-d'), $holidays))
             ) {
           $day->modify('+1 day');
       }
    }
    echo "New date: ".$day->format('Y-m-d');
}

addWorkingDays('2023-01-02', 10);

Результат

From: 2023-01-02
Working days to add: 11
New date: 2023-01-18

на JS

function addWorkingDaysJS(startDate, daysToAdd) {
    let holidays = [];
    holidays.push( new Date("2023-01-06").getTime() );
    holidays.push( new Date("2023-01-10").getTime() );

    console.log("Start date: " + startDate);
    console.log("Days to add: " + daysToAdd);
    let date = new Date(startDate);

    for (let i = 1; i < daysToAdd; i++) {
        date = new Date(date).setDate(new Date(date).getDate() + 1);
        while ( new Date(date).getDay() === 6
                || new Date(date).getDay() === 0
                || ( new Date(date).getDay() !== 6 && new Date(date).getDay() !== 0 && holidays.includes( new Date(date).getTime() ) )
              ) {
            date = new Date(date).setDate(new Date(date).getDate() + 1);
        }
                                }

         let result = new Date(date).toISOString().split('T')[0];
         console.log("Result date: " + result);
}

addWorkingDaysJS('2023-01-02', 11);

Результат

Start date: 2023-01-02
Days to add: 11
Result date: 2023-01-18
→ Ссылка