Расчет рабочих часов

Я пытаюсь рассчитать часы для кого-то, исходя из количества отработанных часов и периода времени, в котором они работали.

Например:

Смена шаблонов с 07:00 до 15:00 – «утро», с 15:00 до 23:00 – «после обеда», а с 23:00 до 07:00 – «ночи».

Поэтому, если бы я начал в 08:00 и закончил в 17:30, это означало бы, что мне платят 7 'утренних часов и 2,5' дневных часов.

Я адаптировал фрагмент кода из проекта, который я разработал некоторое время назад.

Функция «пересечение» вычисляет количество времени, которое перекрывается между двумя диапазонами s1-e1 и s2-e2.

Обратите внимание, что все время находится в секундах, и мы добавляем 3600 * 24 секунды, когда время на следующий день.

<?php function intersection($s1, $e1, $s2, $e2) { if ($e1 < $s2) return 0; if ($s1 > $e2) return 0; if ($s1 < $s2) $s1 = $s2; if ($e1 > $e2) $e1 = $e2; return $e1 - $s1; } $start = strtotime("07:00"); $end = strtotime("17:30"); // $end = strtotime("05:30") + 3600*24; // the work ended at 05:30 morning of the next day $morning_start = strtotime("07:00"); $morning_end = strtotime("15:00"); $afternoon_start = strtotime("15:00"); $afternoon_end = strtotime("23:00"); $night_start = strtotime("23:00"); $night_end = strtotime("07:00") + 3600*24; // 07:00 of next day, add 3600*24 seconds echo "morning: " . intersection( $start, $end, $morning_start, $morning_end ) / 3600 . " hours\n"; echo "afternoon: " . intersection( $start, $end, $afternoon_start, $afternoon_end ) / 3600 . " hours\n"; echo "night: " . intersection( $start, $end, $night_start, $night_end ) / 3600 . " hours\n"; 

У вас может быть 3 счетчика, по одному на каждую смену. Тогда вам понадобится способ увеличения по часам и за каждый час, который вы увеличиваете. Вы проверяете, находится ли он в пределах каждой смены, и если он находится в пределах определенного, то вы увеличиваете этот счетчик.

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

Это то, что я просто бросил вместе для удовольствия.

Существует много возможностей для улучшения, и его можно легко расширить, чтобы обеспечить еще больше расчетов, ваше воображение – это предел.

Массив сдвигов может быть задан с помощью названных клавиш для удобства чтения, но я решил удалить их, так как «night1» и «night2» не имеют для меня никакого смысла 🙂

 <?php $shift_data = array( array( 'rate' => 12.5, 'start' => strtotime('00:00:00'), 'end' => strtotime('07:00:00'), ), array( 'rate' => 7.55, 'start' => strtotime('07:00:00'), 'end' => strtotime('15:00:00'), ), array( 'rate' => 10, 'start' => strtotime('15:00:00'), 'end' => strtotime('23:00:00'), ), array( 'rate' => 12.5, 'start' => strtotime('23:00:00'), 'end' => strtotime('07:00:00') + 86400, // next morning ), ); function calculateWage($start, $end, $rate) { $result = array(); $result['time']['seconds'] = $end - $start; $result['time']['minutes'] = $result['time']['seconds'] / 60; $result['time']['hours'] = $result['time']['minutes'] / 60; $result['wages'] = $result['time']['hours'] * $rate; //print_r($result); return $result; } $shift_start = strtotime('08:00'); $shift_end = strtotime('17:30'); $shift_wages = 0; foreach ($shift_data as $shift) { if ($shift['start'] <= $shift_end) { $start = ($shift_start <= $shift['start']) ? $shift['start'] : $shift_start; $end = ($shift_end <= $shift['end']) ? $shift_end : $shift['end']; $shift_wage = calculateWage($start, $end, $shift['rate']); $shift_wages = $shift_wages + $shift_wage['wages']; } } echo "\nTotal wages for today: $" . number_format($shift_wages, 2, '.', ',') . "\n\n"; ?> 

Вот еще один способ: (я предполагаю начало и конец часов в timestamp unix)

  • Получить начальный и конечный день сотрудника
  • Получить рабочие часы по простой формуле: $ end_hour – $ start_hour
    • Если рабочее время составляет более 8 часов, работнику следует заплатить дополнительно.
    • Чтобы рассчитать дополнительные часы следующей смены: $ end_hour – $ next_shifts_starting_hour

Мое время переключения проще: 22:00 -> 07:00 = ночная работа, 07:00 -> 22:00 = дневная работа

Но я получил неправильный ответ с версией Javi R, если смены похожи на 22:30 -> 08:00 (Результат: день = 0 часов, ночь = 8:30 часов) и 20:00 -> 10:00 (Результат: день = 2 часа, ночь = 9 часов), но правильный ответ со временем сдвига, как 23:00 -> 07:00 (Результат: день = 0 часов, ночь = 7 часов).

Извините за этот ответ. Мне не хватает репутации, но мне нужно заставить ее работать.