Следующий рабочий день указанной даты в PHP - PullRequest
21 голосов
/ 03 апреля 2011

Есть ли у кого-нибудь фрагмент кода PHP для расчета следующего рабочего дня для данной даты?Как, например, ГГГГ-ММ-ДД необходимо преобразовать для определения следующего рабочего дня?

Пример: для 03.04.2011 (ДД-ММ-ГГГГ) следующий рабочий день - 04.04.2011,На 08.04.2011 следующий рабочий день - 11.04.2011.

Это переменная, содержащая дату, которую мне нужно знать на следующий рабочий день для

$cubeTime['time'];

Переменная содержит: 2011-04-01 результат сниппета должен быть: 2011-04-04

Ответы [ 8 ]

83 голосов
/ 03 апреля 2011

Следующий день недели

Поиск следующего дня недели с определенной даты (не включая субботу или воскресенье):

echo date('Y-m-d', strtotime('2011-04-05 +1 Weekday'));

Вы также можете сделать это спеременная даты, конечно:

$myDate = '2011-04-05';
echo date('Y-m-d', strtotime($myDate . ' +1 Weekday'));

ОБНОВЛЕНИЕ: Или, если у вас есть доступ к PHP-класс DateTime (очень вероятно):

$date = new DateTime('2018-01-27');
$date->modify('+7 weekday');
echo $date->format('Y-m-d');

Хотите пропустить праздники?:

Хотя на оригинальном плакате упоминалось: «Мне не нужно рассматривать праздники», если вы действительно хотите игнорировать праздники, простопомните - «Праздники» - это просто массив дат, которые вы не хотите включать, и отличаются в зависимости от страны, региона, компании, человека ... и т. д.

Просто поместите приведенный выше код в функцию, которая исключает/ проходит мимо дат, которые вы не хотите включать.Примерно так:

$tmpDate = '2015-06-22';
$holidays = ['2015-07-04', '2015-10-31', '2015-12-25'];
$i = 1;
$nextBusinessDay = date('Y-m-d', strtotime($tmpDate . ' +' . $i . ' Weekday'));

while (in_array($nextBusinessDay, $holidays)) {
    $i++;
    $nextBusinessDay = date('Y-m-d', strtotime($tmpDate . ' +' . $i . ' Weekday'));
}

Я уверен, что приведенный выше код можно упростить или сократить, если хотите.Я попытался написать это простым для понимания способом.

4 голосов
/ 28 июля 2014

Для британских праздников вы можете использовать

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('Y-m-d', strtotime("$date +$addDay Days"));
            $newDayOfWeek = date('w', strtotime($newDate));
            if ( $newDayOfWeek>0 && $newDayOfWeek<6 && !in_array($newDate,$holidays)) break;
        }
    }

    return $newDate;
}
1 голос
/ 04 апреля 2011
function next_business_day($date) {
  $add_day = 0;
  do {
    $add_day++;
    $new_date = date('Y-m-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 = воскресенье).

0 голосов
/ 25 февраля 2017

Вы могли бы сделать что-то вроде этого.

/**
 * @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('Y-m-d'));

Вывод:

string(10) "2017-02-27"

\NavigableDate\NavigableDateFacade::create($date, $DateTimeZone), предоставляется библиотекой php по адресу https://packagist.org/packages/ishworkh/navigable-date. Сначала необходимо включить эту библиотеку в ваш проект с помощью composer илипрямая загрузка.

0 голосов
/ 04 сентября 2014

См. Пример ниже:

$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("Y-m-d"),$holiday))
$result[] = $date->format("Y-m-d");
}
echo "<pre>";print_r($result);

Для получения дополнительной информации: http://goo.gl/YOsfPX

0 голосов
/ 08 декабря 2013

Я наткнулся на эту тему, когда работал над датским веб-сайтом, где мне нужно было написать 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 можно сделать более сжатыми, но я показываю свой код, чтобы люди могли легко понять, как он работает.

Я надеюсь, что кто-то там может использовать этот маленький фрагмент.

0 голосов
/ 28 августа 2013

Эта функция рассчитает рабочий день в будущем или в прошлом.Аргументами являются число дней, вперед (1) или назад (0) и дата.Если дата не указана, будет использоваться текущая дата:

// returned $date Y/m/d
function work_days_from_date($days, $forward, $date=NULL) 
{
    if(!$date)
    {
        $date = date('Y-m-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('Y-m-d',$day);
        if( date('N', strtotime($date)) <= 5) // if it's a weekday
        {
          $days--;
        }
    }
    return $date;
}
0 голосов
/ 03 апреля 2011

Что вам нужно сделать:

  1. Преобразовать указанную дату в метку времени.

  2. Используйте это вместе с или w или N форматеры для команды PHP date , чтобы сообщить вам, какой сегодня день недели.

  3. Если это не «рабочий день», вы можете увеличить отметку времени на день (86400 секунд) и проверять снова, пока не наступит рабочий день.

Примечание: для действительно работы вам также необходимо исключить любые праздничные и праздничные дни и т. Д.

...