Есть ли у кого-нибудь PHP-фрагмент для вычисления следующего рабочего дня на заданную дату? Как, например, нужно преобразовать ГГГГ-ММ-ДД, чтобы узнать следующий рабочий день?
Пример: на 03.04.2011 (DD-MM-YYYY) следующий рабочий день – 04.04.2011. На 08.04.2011 следующий рабочий день – 11.04.2011.
Это переменная, содержащая дату, которую мне нужно знать на следующий рабочий день для
$cubeTime['time'];
Переменная содержит: 2011-04-01 результат фрагмента должен быть: 2011-04-04
Следующий будний день
Это находит следующий будний день с определенной даты (не включая субботу или воскресенье):
echo date('Ym-d', strtotime('2011-04-05 +1 Weekday'));
Вы также можете сделать это с переменной даты, конечно:
$myDate = '2011-04-05'; echo date('Ym-d', strtotime($myDate . ' +1 Weekday'));
Хотите пропустить каникулы ?:
Хотя оригинальный плакат упоминал «Мне не нужно рассматривать праздники», если вы НЕ хотите игнорировать праздники, просто помните – «Праздники» – это всего лишь множество любых дат, которые вы не хотите включать, и отличается по странам , регион, фирма, человек … и т.п.
Просто добавьте вышеуказанный код в функцию, которая исключает / петли мимо дат, которые вы не хотите включать. Что-то вроде этого:
$tmpDate = '2015-06-22'; $holidays = ['2015-07-04', '2015-10-31', '2015-12-25']; $i = 1; $nextBusinessDay = date('Ym-d', strtotime($tmpDate . ' +' . $i . ' Weekday')); while (in_array($nextBusinessDay, $holidays)) { $i++; $nextBusinessDay = date('Ym-d', strtotime($tmpDate . ' +' . $i . ' Weekday')); }
Я уверен, что вышеуказанный код можно упростить или сократить, если хотите. Я попытался написать его в удобном для понимания способом.
В выходные дни в Великобритании вы можете использовать
https://www.gov.uk/bank-holidays#england-and-wales
Данные формата ICS легко анализируются. Мое предложение …
# $date must be in YYYY-MM-DD format # You can pass in either an array of holidays in YYYYMMDD format # OR a URL for a .ics file containing holidays # this defaults to the UK government holiday data for England and Wales function addBusinessDays($date,$numDays=1,$holidays='') { if ($holidays==='') $holidays = 'https://www.gov.uk/bank-holidays/england-and-wales.ics'; if (!is_array($holidays)) { $ch = curl_init($holidays); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); $ics = curl_exec($ch); curl_close($ch); $ics = explode("\n",$ics); $ics = preg_grep('/^DTSTART;/',$ics); $holidays = preg_replace('/^DTSTART;VALUE=DATE:(\\d{4})(\\d{2})(\\d{2}).*/s','$1-$2-$3',$ics); } $addDay = 0; while ($numDays--) { while (true) { $addDay++; $newDate = date('Ym-d', strtotime("$date +$addDay Days")); $newDayOfWeek = date('w', strtotime($newDate)); if ( $newDayOfWeek>0 && $newDayOfWeek<6 && !in_array($newDate,$holidays)) break; } } return $newDate; }
function next_business_day($date) { $add_day = 0; do { $add_day++; $new_date = date('Ym-d', strtotime("$date +$add_day Days")); $new_day_of_week = date('w', strtotime($new_date)); } while($new_day_of_week == 6 || $new_day_of_week == 0); return $new_date; }
Эта функция должна игнорировать выходные (6 = суббота и 0 = воскресенье).
Что вам нужно сделать:
Преобразуйте предоставленную дату в метку времени.
Используйте это вместе с форматировщиками или w
или N
для команды даты PHP, чтобы сообщить вам, в какой именно день недели.
Если это не «рабочий день», вы можете увеличить отметку времени на один день (86400 секунд) и снова проверить, пока не нажмете на рабочий день.
NB: для этого действительно работа, вам также необходимо исключить любые банковские или праздничные дни и т. Д.
Эта функция рассчитает рабочий день в будущем или в прошлом. Аргументы – это количество дней, вперед (1) или назад (0) и дата. Если дата не указана на сегодняшний день, будет использоваться:
// returned $date Y/m/d function work_days_from_date($days, $forward, $date=NULL) { if(!$date) { $date = date('Ym-d'); // if no date given, use todays date } while ($days != 0) { $forward == 1 ? $day = strtotime($date.' +1 day') : $day = strtotime($date.' -1 day'); $date = date('Ym-d',$day); if( date('N', strtotime($date)) <= 5) // if it's a weekday { $days--; } } return $date; }
Я наткнулся на эту тему, когда я работал на датском веб-сайте, где мне нужно было написать скрипт PHP «На следующий день».
Вот что я придумал (это покажет название следующего рабочего дня на датском языке, а следующая рабочая + 1, если текущее время больше заданного предела)
$day["Mon"] = "Mandag"; $day["Tue"] = "Tirsdag"; $day["Wed"] = "Onsdag"; $day["Thu"] = "Torsdag"; $day["Fri"] = "Fredag"; $day["Sat"] = "Lørdag"; $day["Sun"] = "Søndag"; date_default_timezone_set('Europe/Copenhagen'); $date = date('l'); $checkTime = '1400'; $date2 = date(strtotime($date.' +1 Weekday')); if( date( 'Hi' ) >= $checkTime) { $date2 = date(strtotime($date.' +2 Weekday')); } if (date('l') == 'Saturday'){ $date2 = date(strtotime($date.' +2 Weekday')); } if (date('l') == 'Sunday') { $date2 = date(strtotime($date.' +2 Weekday')); } echo '<p>Næste levering: <span>'.$day[date("D", $date2)].'</span></p>';
Как вы можете видеть в примерном коде $ checkTime, я устанавливаю лимит времени, который определяет, будет ли доставка на следующий день +1 рабочим днем или +2 рабочими днями.
'1400' = 14:00 часов
Я знаю, что инструкции if можно сделать более сжатыми, но я показываю свой код, чтобы люди могли легко понять, как это работает.
Я надеюсь, что кто-то там может использовать этот маленький фрагмент.
См. Пример ниже:
$startDate = new DateTime( '2013-04-01' ); //intialize start date $endDate = new DateTime( '2013-04-30' ); //initialize end date $holiday = array('2013-04-11','2013-04-25'); //this is assumed list of holiday $interval = new DateInterval('P1D'); // set the interval as 1 day $daterange = new DatePeriod($startDate, $interval ,$endDate); foreach($daterange as $date){ if($date->format("N") <6 AND !in_array($date->format("Ymd"),$holiday)) $result[] = $date->format("Ymd"); } echo "<pre>";print_r($result);
Для получения дополнительной информации: http://goo.gl/YOsfPX
Вы могли бы сделать что-то подобное.
/** * @param string $date * @param DateTimeZone|null|null $DateTimeZone * @return \NavigableDate\NavigableDateInterface */ function getNextBusinessDay(string $date, ? DateTimeZone $DateTimeZone = null):\NavigableDate\NavigableDateInterface { $Date = \NavigableDate\NavigableDateFacade::create($date, $DateTimeZone); $NextDay = $Date->nextDay(); while(true) { $nextDayIndexInTheWeek = (int) $NextDay->format('N'); // check if the day is between Monday and Friday. In DateTime class php, Monday is 1 and Friday is 5 if ($nextDayIndexInTheWeek >= 1 && $nextDayIndexInTheWeek <= 5) { break; } $NextDay = $NextDay->nextDay(); } return $NextDay; } $date = '2017-02-24'; $NextBussinessDay = getNextBusinessDay($date); var_dump($NextBussinessDay->format('Ym-d'));
в/** * @param string $date * @param DateTimeZone|null|null $DateTimeZone * @return \NavigableDate\NavigableDateInterface */ function getNextBusinessDay(string $date, ? DateTimeZone $DateTimeZone = null):\NavigableDate\NavigableDateInterface { $Date = \NavigableDate\NavigableDateFacade::create($date, $DateTimeZone); $NextDay = $Date->nextDay(); while(true) { $nextDayIndexInTheWeek = (int) $NextDay->format('N'); // check if the day is between Monday and Friday. In DateTime class php, Monday is 1 and Friday is 5 if ($nextDayIndexInTheWeek >= 1 && $nextDayIndexInTheWeek <= 5) { break; } $NextDay = $NextDay->nextDay(); } return $NextDay; } $date = '2017-02-24'; $NextBussinessDay = getNextBusinessDay($date); var_dump($NextBussinessDay->format('Ym-d'));
Вывод:
string(10) "2017-02-27"
\NavigableDate\NavigableDateFacade::create($date, $DateTimeZone)
предоставляется библиотекой php, доступной по адресу https://packagist.org/packages/ishworkh/navigable-date . Вы должны сначала включить эту библиотеку в свой проект с помощью композитора или прямой загрузки.