Tools.php
public static function secondsBetweenWorkingDays($dateFrom, $dateTo, $workDayFrom, $workDayTo, $weekends = false, $holidays = false, $timeZone = 'Europe/Prague')
    {
        $timeZoneObj = new \DateTimeZone($timeZone);
        $dateFromObj = new DateTime($dateFrom, $timeZoneObj);
        $dateToObj = new DateTime($dateTo, $timeZoneObj);
        $workDayFromObj = new DateTime($workDayFrom, $timeZoneObj);
        $workDayToObj = new DateTime($workDayTo, $timeZoneObj);
        $workDayLength = self::secondsBetweenDates($workDayFrom, $workDayTo, true, $timeZone);

        $period = new \DatePeriod(
            new DateTime($dateFromObj->format('Y-m-d 00:00:00'), $timeZoneObj),
            new \DateInterval('P1D'),
            new DateTime($dateToObj->format('Y-m-d 23:59:59'), $timeZoneObj)
        );

        $workedTime = 0;
        foreach ($period as $date) {
            /** @var DateTime $date */
            if ((!$weekends && (int)$date->format('N') > 5) || (!$holidays && self::isCzechHoliday($date))) {
                continue;
            }

            if ($date->format('Y-m-d') === $dateFromObj->format('Y-m-d')) {
                //First day
                $endOfDay = new DateTime($date->format('Y-m-d ' . $workDayToObj->format('H:i:s')), $timeZoneObj);

                if ($dateFromObj < $endOfDay && $dateFromObj->format('Y-m-d') === $dateToObj->format('Y-m-d')) {
                    //Only one day - before workday end
                    $diff = $dateToObj->diff($dateFromObj)->format('%H:%I:%S');
                } else {
                    $diff = $endOfDay->diff($dateFromObj)->format('%H:%I:%S');
                }
                $diff = explode(':', $diff);
                $diff = $diff[0] * 3600 + $diff[1] * 60 + $diff[0];
                $workedTime += $diff;
            } elseif ($date->format('Y-m-d') === $dateToObj->format('Y-m-d')) {
                //Last day
                $startOfDay = new DateTime($date->format('Y-m-d ' . $workDayFromObj->format('H:i:s')), $timeZoneObj);
                if ($dateToObj > $startOfDay) {
                    $diff = $startOfDay->diff($dateToObj)->format('%H:%I:%S');
                    $diff = explode(':', $diff);
                    $diff = $diff[0] * 3600 + $diff[1] * 60 + $diff[0];
                    $workedTime += $diff;
                }
            } else {
                //Full day
                $workedTime += $workDayLength;
            }
        }

        return $workedTime;
    }
public static function secondsBetweenWorkingDays($dateFrom, $dateTo, $workDayFrom, $workDayTo, $weekends = false, $holidays = false, $timeZone = 'Europe/Prague')
    {
        $timeZoneObj = new \DateTimeZone($timeZone);
        $dateFromObj = new DateTime($dateFrom, $timeZoneObj);
        $dateToObj = new DateTime($dateTo, $timeZoneObj);
        $workDayFromObj = new DateTime($workDayFrom, $timeZoneObj);
        $workDayToObj = new DateTime($workDayTo, $timeZoneObj);
        $workDayLength = self::secondsBetweenDates($workDayFrom, $workDayTo, true, $timeZone);

        $period = new \DatePeriod(
            new DateTime($dateFromObj->format('Y-m-d 00:00:00'), $timeZoneObj),
            new \DateInterval('P1D'),
            new DateTime($dateToObj->format('Y-m-d 23:59:59'), $timeZoneObj)
        );

        $workedTime = 0;
        foreach ($period as $date) {
            /** @var DateTime $date */
            if ((!$weekends && (int)$date->format('N') > 5) || (!$holidays && self::isCzechHoliday($date))) {
                continue;
            }

            if ($date->format('Y-m-d') === $dateFromObj->format('Y-m-d')) {
                //First day
                $endOfDay = new DateTime($date->format('Y-m-d ' . $workDayToObj->format('H:i:s')), $timeZoneObj);

                if ($dateFromObj < $endOfDay && $dateFromObj->format('Y-m-d') === $dateToObj->format('Y-m-d')) {
                    //Only one day - before workday end
                    $diff = $dateToObj->diff($dateFromObj)->format('%H:%I:%S');
                } else {
                    $diff = $endOfDay->diff($dateFromObj)->format('%H:%I:%S');
                }
                $diff = explode(':', $diff);
                $diff = $diff[0] * 3600 + $diff[1] * 60 + $diff[0];
                $workedTime += $diff;
            } elseif ($date->format('Y-m-d') === $dateToObj->format('Y-m-d')) {
                //Last day
                $startOfDay = new DateTime($date->format('Y-m-d ' . $workDayFromObj->format('H:i:s')), $timeZoneObj);
                if ($dateToObj > $startOfDay) {
                    $diff = $startOfDay->diff($dateToObj)->format('%H:%I:%S');
                    $diff = explode(':', $diff);
                    $diff = $diff[0] * 3600 + $diff[1] * 60 + $diff[0];
                    $workedTime += $diff;
                }
            } else {
                //Full day
                $workedTime += $workDayLength;
            }
        }

        return $workedTime;
    }
Counts number of seconds between two dates taking into account only working days

@param string $dateFrom Start date in DateTime compatible syntax
@param string $dateTo End date in DateTime compatible syntax
@param string $workDayFrom Working hours start time in DateTime compatible syntax
@param string $workDayTo Working hours end time in DateTime compatible syntax
@param bool $weekends Whether to count weekends as a working days
@param bool $holidays Whether to count holidays as a working days
@param string $timeZone Timezone @see http://php.net/manual/en/timezones.php
@return int Difference in seconds

@throws \Exception
@throws RuntimeException