PHP посчитать количество секунд рабочего времени между двумя датами, с учетом рабочего графика и праздничных дней

Может у кого есть готовое решение как это реализовать? Допустим есть рабочий график:

  1. Понедельник - пятница с 8 до 20
  2. Суббота с 8 до 17

И есть две даты, нужно посчитать сколько секунд рабочего времени прошло между ними, с учетом графика рабочего времени: 25-12-2020 07:00:00 и 30-12-2020 18:02:01

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

function work_hours_diff($date1, $date2)
{
    if ($date1 > $date2)
    {
        $tmp = $date1;
        $date1 = $date2;
        $date2 = $tmp;
        unset($tmp);
        $sign = - 1;
    }
    else return 0;
    if ($date1 == $date2) return 0;

    $days = 0;
    $working_days = array(
        1,
        2,
        3,
        4,
        5,
        6
    );
    $working_hours = array(
        8,
        20
    );
    $current_date = $date1;
    $beg_h = floor($working_hours[0]);
    $beg_m = ($working_hours[0] * 60) % 60;
    $end_h = floor($working_hours[1]);
    $end_m = ($working_hours[1] * 60) % 60;


    if (!in_array(date('w', $current_date) , $working_days))
    {

        $current_date = mktime($beg_h, $beg_m, 0, date('n', $current_date) , date('j', $current_date) , date('Y', $current_date));
            
        while (!in_array(date('w', $current_date) , $working_days))
        {
            $current_date += 24 * 3600;
        }
    }
    else
    {
        $date0 = mktime($beg_h, $beg_m, 0, date('n', $current_date) , date('j', $current_date) , date('Y', $current_date));

        if ($current_date < $date0) $current_date = $date0;

        $date3 = mktime($end_h, $end_m, 0, date('n', $current_date) , date('j', $current_date) , date('Y', $current_date));
        if ($date3 < $current_date)
        {

            $current_date += 24 * 3600;

            $current_date = mktime($beg_h, $beg_m, 0, date('n', $current_date) , date('j', $current_date) , date('Y', $current_date));
            while (!in_array(date('w', $current_date) , $working_days))
            {
                $current_date += 24 * 3600;
            }
        }
    }

    $date0 = mktime($end_h, $end_m, 0, date('n', $current_date) , date('j', $current_date) , date('Y', $current_date));
    $seconds = $date0 - $current_date;

    $date3 = mktime($beg_h, $beg_m, 0, date('n', $date2) , date('j', $date2) , date('Y', $date2));
    while ($current_date < $date3)
    {
        $current_date += 24 * 3600;
        if (in_array(date('w', $current_date) , $working_days)) $days++;
    }

    $days--;

    $date0 = mktime($beg_h, 0, 0, date('n', $date2) , date('j', $date2) , date('Y', $date2));
    if ($date2 < $date0)
    {

    }
    else
    {

        $date3 = mktime($end_h, $end_m, 0, date('n', $date2) , date('j', $date2) , date('Y', $date2));
        if ($date2 > $date3) $date2 = $date3;

        $tmp = $date2 - $date0;
        $seconds += $tmp;

    }


    $seconds += 3600 * ($working_hours[1] - $working_hours[0]) * $days;

    return $seconds;
}

date_default_timezone_set("Europe/Kaliningrad");
$dt2 = strtotime("25-12-2020 07:00:00");
$dt1 = strtotime("30-12-2020 18:02:01");
$seconds = work_hours_diff($dt1, $dt2);
var_dump($seconds);

Делал ещё один вариант, но там каждую секунду приходится проверять соответствует ли она условию, и добавлять в счетчик, что очень не правильно как я думаю, хотя этот вариант и работает...

<?php
date_default_timezone_set('Europe/Kaliningrad');

$start = '2020-12-24 07:00:00';
$end = '2020-12-25 08:40:00';

$startDate = new DateTime($start);
$endDate = new DateTime($end);
$periodInterval = new DateInterval("PT1S");

$period = new DatePeriod($startDate, $periodInterval, $endDate);

$count = 0;

foreach ($period as $date)
    {
        
        if($date->format('N') != 7){ //Исключим воскресенье
        
            if($date->format('N') == 6){ //Пятница
               
               $time_work = ['08','09','10','11','12','13','14','15','16','17'];
               
               
            }else{//Остальные дни
                
                $time_work = ['08','09','10','11','12','13','14','15','16','17','18','19','20'];
            }
            
            
            if(in_array($date->format('H') ,$time_work)){
                $count++;
            }
            

        
            
        }

       


    }

echo 'Прошло часов всего: '.floor($count / 3600).PHP_EOL;
echo 'Прошло минут всего: '.($count / 60).PHP_EOL;
echo 'Прошло секунд всего: '.$count.PHP_EOL;

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