Рассчитать рабочие дни между датами

Я хочу рассчитать количество рабочих дней.

Используя углерод, я могу подсчитывать дни и сокращать выходные.

$num_days = $to_date->diffInWeekdays($from_date) + 1;

И у меня есть множество праздников, и я хочу уменьшить количество дней, если между днями есть праздник.

Есть какой-либо способ сделать это.

Спасибо


person Muhsin VeeVees    schedule 04.01.2017    source источник
comment
Являются ли даты в вашем массиве праздников просто строками или Carbon экземплярами? Если это строки, как они отформатированы?   -  person Rwd    schedule 04.01.2017


Ответы (4)


Вы можете использовать diffInDaysFiltered для достижения того, что вам нужно.

Предполагая, что ваши праздники представляют собой массив экземпляров Carbon, вы можете сделать что-то вроде:

$start = Carbon::now()->setDate(2014, 1, 1);
$end = Carbon::now()->setDate(2015, 1, 1);

$holidays = [
    Carbon::create(2014, 2, 2),
    Carbon::create(2014, 4, 17),
    Carbon::create(2014, 5, 19),
    Carbon::create(2014, 7, 3),
];

$days = $start->diffInDaysFiltered(function (Carbon $date) use ($holidays) {

    return $date->isWeekday() && !in_array($date, $holidays);

}, $end);

Если это просто массив строк, вы можете сделать что-то вроде:

!in_array($date->format('[the-format-of-your-dates]'), $holidays)

Надеюсь это поможет!

person Rwd    schedule 04.01.2017

Вот небольшая полезная функция для расчета рабочих дней:

function getWorkingDaysCount($from, $to) {
    $workingDays = [1, 2, 3, 4, 5];         // Working days (week days)
    $holidayDays = ['*-12-25', '*-01-01'];  // Holidays array, add desired dates to this array 

    $from = new DateTime($from);
    $to = new DateTime($to);
    $to->modify('+1 day');
    $interval = new DateInterval('P1D');
    $periods = new DatePeriod($from, $interval, $to);

    $days = 0;
    foreach ($periods as $period) {
      if (!in_array($period->format('N'), $workingDays)) continue;
      if (in_array($period->format('Y-m-d'), $holidayDays)) continue;
      if (in_array($period->format('*-m-d'), $holidayDays)) continue;
      $days++;
  }
  return $days;
}

Вы можете передать дату начала и окончания, чтобы получить количество дней.

person Thamilhan    schedule 04.01.2017

Вы можете получить это, следуя коду

<?php
    function workdays($start,$end,$holidays){
        $end = strtotime($end);
        $start = strtotime($start);
        $days = ($end - $start) / 86400 + 1;

        $no_full_weeks = floor($days / 7);
        $no_remaining_days = fmod($days, 7);

        $the_first_day_of_week = date("N", $start);
        $the_last_day_of_week = date("N", $end);

        if ($the_first_day_of_week <= $the_last_day_of_week) {
            if ($the_first_day_of_week <= 6 && 6 <= $the_last_day_of_week) $no_remaining_days--;
            if ($the_first_day_of_week <= 7 && 7 <= $the_last_day_of_week) $no_remaining_days--;
        }
        else {
            if ($the_first_day_of_week == 7) {
                $no_remaining_days--;

                if ($the_last_day_of_week == 6) {
                    $no_remaining_days--;
                }
            }
            else {
                $no_remaining_days -= 2;
            }
        }

       $workingDays = $no_full_weeks * 5;
        if ($no_remaining_days > 0 )
        {
          $workingDays += $no_remaining_days;
        }

        foreach($holidays as $holiday){
            $time_stamp=strtotime($holiday);
            if ($start <= $time_stamp && $time_stamp <= $end && date("N",$time_stamp) != 6 && date("N",$time_stamp) != 7)
                $workingDays--;
        }

        return $workingDays;
    }



    echo workdays("2016-01-04","2016-01-30",array("2016-01-25","2016-01-26","2016-01-27"))

    ?>
person Matin malek    schedule 04.01.2017

Вы можете воспользоваться методами Carbon diffInDaysFiltered() и isWeekend(). Ниже приведен модифицированный код из документации Carbon.

$daysForExtraCoding = $dt->diffInDaysFiltered(function(Carbon $date) {
   return !$date->isWeekend();
}, $dt2);

echo $daysForExtraCoding;      // 260
person aphoe    schedule 18.10.2020