0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>Представим: за час до конца рабочего дня, 29 декабря 2017 года, вам поручили срочное двухчасовое задание - рассчитать на PHP время его окончания. Казалось бы, что тут сложного? Добавить 2*3600 секунд к текущему времени и всё!</p>
1
<p>Представим: за час до конца рабочего дня, 29 декабря 2017 года, вам поручили срочное двухчасовое задание - рассчитать на PHP время его окончания. Казалось бы, что тут сложного? Добавить 2*3600 секунд к текущему времени и всё!</p>
2
<p>Вот так:</p>
2
<p>Вот так:</p>
3
class WorkHours { public function addHours ($date, $hours) { $time = strtotime ($date); // переводим дату в секунды for ($j = 0; $j < $hours; $j ++) // в цикле добавляем по часу $time = $this -> addHour ($time); return date ("Y-m-d H:i:s", $time); // конвертируем в дату } function addHour ($time) { return $time + 3600; // добавляем один час } }<h2>Но в преддверии Нового года не всё так просто...</h2>
3
class WorkHours { public function addHours ($date, $hours) { $time = strtotime ($date); // переводим дату в секунды for ($j = 0; $j < $hours; $j ++) // в цикле добавляем по часу $time = $this -> addHour ($time); return date ("Y-m-d H:i:s", $time); // конвертируем в дату } function addHour ($time) { return $time + 3600; // добавляем один час } }<h2>Но в преддверии Нового года не всё так просто...</h2>
4
<p>Для решения задачи нужно учитывать время начала и окончания рабочего дня, обеденный перерыв, а также выходные и праздничные дни. То есть функция<strong>addHour ()</strong>должна добавлять по одному часу до тех пор, пока выпадает нерабочий час, выходной день или праздник.</p>
4
<p>Для решения задачи нужно учитывать время начала и окончания рабочего дня, обеденный перерыв, а также выходные и праздничные дни. То есть функция<strong>addHour ()</strong>должна добавлять по одному часу до тех пор, пока выпадает нерабочий час, выходной день или праздник.</p>
5
<h2>Начнём с рабочих часов</h2>
5
<h2>Начнём с рабочих часов</h2>
6
<p>Будем считать, что фирма работает с 9:00 до 18:00 с перерывом на обед с 13:00 до 14:00. Создадим массив, в котором перечислим все нерабочие часы в течение суток:</p>
6
<p>Будем считать, что фирма работает с 9:00 до 18:00 с перерывом на обед с 13:00 до 14:00. Создадим массив, в котором перечислим все нерабочие часы в течение суток:</p>
7
private $offtimes = array ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // утром 13, // обед 19, 20, 21, 22, 23); // вечером function isOfftime ($time) { return in_array (date ("G", $time), // час без ведущего нуля $this -> offtimes); // список нерабочих часов }<h2>Теперь разберёмся с выходными днями</h2>
7
private $offtimes = array ( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, // утром 13, // обед 19, 20, 21, 22, 23); // вечером function isOfftime ($time) { return in_array (date ("G", $time), // час без ведущего нуля $this -> offtimes); // список нерабочих часов }<h2>Теперь разберёмся с выходными днями</h2>
8
<p>Составим список и напишем функцию проверки:</p>
8
<p>Составим список и напишем функцию проверки:</p>
9
private $weekends = array ("Sat", "Sun"); function isWeekend ($time) { return in_array (date ("D", $time), // буквенный код дня недели $this -> weekends); // список выходных дней недели }<h2>Сложнее всего с праздничными днями</h2>
9
private $weekends = array ("Sat", "Sun"); function isWeekend ($time) { return in_array (date ("D", $time), // буквенный код дня недели $this -> weekends); // список выходных дней недели }<h2>Сложнее всего с праздничными днями</h2>
10
<p>На каждый год для заданной страны их нужно перечислять отдельно, либо подключиться к базе, откуда можно их получать. В рамках этой статьи мы перечислим их прямо в коде:</p>
10
<p>На каждый год для заданной страны их нужно перечислять отдельно, либо подключиться к базе, откуда можно их получать. В рамках этой статьи мы перечислим их прямо в коде:</p>
11
private $holydays = array ( "2018-01-01", "2018-01-02", "2018-01-03", "2018-01-04", "2018-01-05", "2018-01-06", "2018-01-07", "2018-01-08", "2018-02-23", … ); function isHolyday ($time) { return in_array (date ("Y-m-d", $time), // конвертируем в дату $this -> holydays); // ищем в списке праздников }<h2>Вот теперь можно переписать функцию добавления одного часа</h2>
11
private $holydays = array ( "2018-01-01", "2018-01-02", "2018-01-03", "2018-01-04", "2018-01-05", "2018-01-06", "2018-01-07", "2018-01-08", "2018-02-23", … ); function isHolyday ($time) { return in_array (date ("Y-m-d", $time), // конвертируем в дату $this -> holydays); // ищем в списке праздников }<h2>Вот теперь можно переписать функцию добавления одного часа</h2>
12
<p>Будем добавлять 3600 секунд, пока выполняются условия: - данный час попадает на выходной день; - данный час выпадает на праздничный день; - данный час является нерабочим.</p>
12
<p>Будем добавлять 3600 секунд, пока выполняются условия: - данный час попадает на выходной день; - данный час выпадает на праздничный день; - данный час является нерабочим.</p>
13
function addHour ($time) { do $time += 3600; while ($this -> isWeekend ($time) // выходной || $this -> isHolyday ($time) // праздник || $this -> isOfftime ($time)); // нерабочий час return $time; }<p>Проверка часа на выполнение данных условий производится ранее рассмотренными функциями: -<strong>isWeekend ($time)</strong>- проверка на выходной, -<strong>isHolyday ($time)</strong>- проверка на праздничный день, - <strong>isOfftime ($time)</strong>- проверка на нерабочее время.</p>
13
function addHour ($time) { do $time += 3600; while ($this -> isWeekend ($time) // выходной || $this -> isHolyday ($time) // праздник || $this -> isOfftime ($time)); // нерабочий час return $time; }<p>Проверка часа на выполнение данных условий производится ранее рассмотренными функциями: -<strong>isWeekend ($time)</strong>- проверка на выходной, -<strong>isHolyday ($time)</strong>- проверка на праздничный день, - <strong>isOfftime ($time)</strong>- проверка на нерабочее время.</p>
14
<h2>Теперь мы можем решить поставленную задачу:</h2>
14
<h2>Теперь мы можем решить поставленную задачу:</h2>
15
<?php $wh = new WorkHours (); $date_from = "2017-12-29 17:00:00"; $date_till = $wh -> addHours ($date_from, 2); echo $date_from . "\n" . $date_till; ?> 2017-12-29 17:00:00 2018-01-09 10:00:00<p>У нас ещё есть Время!</p>
15
<?php $wh = new WorkHours (); $date_from = "2017-12-29 17:00:00"; $date_till = $wh -> addHours ($date_from, 2); echo $date_from . "\n" . $date_till; ?> 2017-12-29 17:00:00 2018-01-09 10:00:00<p>У нас ещё есть Время!</p>
16
<p><em>Есть вопрос? Напишите в комментариях!</em></p>
16
<p><em>Есть вопрос? Напишите в комментариях!</em></p>
17
17