Нужно рассчитать рабочее время с учетом временных рамок

112
03 февраля 2021, 13:20

Есть рабочее время, например с 9:00 до 18:00. Есть данные, когда рабочий приступил к работе (например 30 числа в 10:00) и когда он закончил работу (например 2 числа в 16:30). Нужно рассчитать сколько часов он проработал.

Изначально думал просто брать второе число, отнимать от первого, если разница один день, то просто считать от первой точки до конца рабочего дня плюс начало рабочего дня до второй точки. Если разница 2 дня и больше, то прибавлять полный рабочий день. Но тут нюанс, что начинает он в конце месяца, а заканчивает в начале, то-есть еще нужно высчитывать разницу месяцев, сколько дней в предыдущем месяце и тд ...

Возможно есть вариант попроще.

Answer 1

Используйте DateTime и даже 29 февраля не станет сюрпризом, а если понадобится ещё и часовые пояса есть.

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

const WORKDAY_BEGIN = [9, 0]; // 9:00
const WORKDAY_END = [18, 0]; // 18:00
function hoursDelta(\DateTime $begin, \DateTime $end): float
{
    $workDayBegin = (clone $begin)->setTime(...WORKDAY_BEGIN);
    $flawBegin = $begin->diff($workDayBegin);
    $workDayEnd = (clone $end)->setTime(...WORKDAY_END);
    $flawEnd = $workDayEnd->diff($end);
    // полных дней, на количество рабочих часов
    $hoursDelta = $end->diff($begin, true)->days * ($workDayEnd->diff($workDayBegin)->h);
    // вычитаем недоработку часов
    $hoursDelta -= (float) $flawBegin->h + $flawEnd->h;
    // и если нужно минут
    $hoursDelta -= ($flawBegin->i + $flawEnd->i) / 60;
    return $hoursDelta;
}
$result = hoursDelta(
    new \DateTime('30-05-2019 10:00'),
    new \DateTime('02-06-2019 16:30')
);
echo $result; // 24.5
Answer 2

Вот как то так набросал -

$start = strtotime('31.01.2009 9:00:00');
$end = strtotime('31.01.2009 10:00:00');
$hours = (($end - strtotime("midnight",$end)) + (strtotime("tomorrow",$start) - $start) + (strtotime("midnight",$end) - strtotime("tomorrow",$start)) - 15*60*60*round(($end - $start) / (60 * 60 * 24)))/3600;

PS: Добавлю, что данный код считает часы с учетом 9 часового рабочего дня без проверки времени начала и конца рабочего дня. Т.е. может быть использован для подсчета рабочих часов для рабочего дня с 8 до 17, с 9 до 18, с 10 до 19 и т.д. Начальные параметры нужно контролировать на входе.

READ ALSO
Не могу получить значение переменной из класса

Не могу получить значение переменной из класса

$akk - ответ мускула на запросОтвет верный, num_rows выдает 1

111
Как добавить 2 разных класса в <div>?

Как добавить 2 разных класса в <div>?

Помогите пожалуйстаЕсть код

137
Покупка в кредит от Тинькофф банка интеграция curl

Покупка в кредит от Тинькофф банка интеграция curl

Делаю интеграцию покупки в кредит от ТиньковаЧерез form post все работает идеально

112
php экспорт в excel изображений

php экспорт в excel изображений

подскажите, как в ячейку закинуть несколько изображение? сейчас только 1-но вставляет, а нужно из папки все фото

121