Skip to content

Instantly share code, notes, and snippets.

@leonid-shevtsov
Created March 23, 2020 06:39
Show Gist options
  • Save leonid-shevtsov/fbf2e61a1d410a8e04e89152a507fe45 to your computer and use it in GitHub Desktop.
Save leonid-shevtsov/fbf2e61a1d410a8e04e89152a507fe45 to your computer and use it in GitHub Desktop.
<?
// расчет числа рабочих дней в промежутке дат
// $start_day = 1 марта 2020, $total_days = 12
function workday_count($start_day_as_timestamp,$total_days)
{
//$weekday 0 = Sun 1 = Mon ...
$weekday = date('w',$start_day_as_timestamp);
// $weekday = 0: 1 марта 2020 - воскресенье
// Замечу, что недели считаем от воскресенья до воскресенья, поскольку так их отдает функция date()
// Теперь делим промежуток дат на 3 отрезка:
// - первая, возможно, неполная неделя, в которую входит дата начала
// - несколько полных недель
// - последняя, возможно, неполная неделя, в которую входит дата конца
// отрезаем первую неделю:
$days_without_1st_incomplete_week = $total_days — (7-$weekday);
// 12 - (7 - 0 ) = 5: столько дней остается без первой недели
// $workdays_in_1st_incomplete_week = 6 — $weekday;
// считаем, сколько рабочих дней остается в первой неделе с ее начала по конец (6 день)
// ТУТ БАГ: если день начала - воскресенье - то получится 6 рабочих дней, а должно было 5
// для остальных дней недели все правильно, так что можно добавить проверку на воскресенье
// правильная строчка такая:
$workdays_in_1st_incomplete_week = $weekday == 0 ? 6 — $weekday : 5;
// $workdays_in_1st_incomplete_week = 5
// отрезаем полные недели:
$workdays_in_complete_weeks = floor($days_without_1st_incomplete_week / 7) * 5;
// в каждой полной неделе точно 5 рабочих дней, поэтому берем их число и умножаем на 5
// в нашем случае, полных недель нет (кроме первой, которую посчитали раньше)
// $workdays_in_complete_weeks = floor(5 / 7) * 5 = 0
// находим остаток последней недели:
$days_in_last_week = $days_without_1st_incomplete_week % 7;
// $days_in_last_week = 5 % 7 = 5
$workdays_in_last_week = $days_in_last_week ? $days_in_last_week — 1: 0;
// считаем, сколько в последней неделе рабочих дней
// раз неделя начинается с воскресенья, то рабочих дней на один меньше, чем всего дней
// $workdays_in_last_week = 5 - 1 = 4
return $workdays_in_1st_incomplete_week + $workdays_in_complete_weeks + $workdays_in_last_week;
// наконец, складываем рабочие дних во всех трех отрезках
// 5 + 0 + 4 = 9
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment