Next business day of given date in PHP

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;
}

This function should ignore weekends (6 = Saturday and 0 = Sunday).


For UK holidays you can use

https://www.gov.uk/bank-holidays#england-and-wales

The ICS format data is easy to parse. My suggestion is...

# $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;
}

Next Weekday

This finds the next weekday from a specific date (not including Saturday or Sunday):

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

You could also do it with a date variable of course:

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

UPDATE: Or, if you have access to PHP's DateTime class (very likely):

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

Want to Skip Holidays?:

Although the original poster mentioned "I don't need to consider holidays", if you DO happen to want to ignore holidays, just remember - "Holidays" is just an array of whatever dates you don't want to include and differs by country, region, company, person...etc.

Simply put the above code into a function that excludes/loops past the dates you don't want included. Something like this:

$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'));
}

I'm sure the above code can be simplified or shortened if you want. I tried to write it in an easy-to-understand way.


This function will calculate the business day in the future or past. Arguments are number of days, forward (1) or backwards(0), and a date. If no date is supplied todays date will be used:

// 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;
}

Tags:

Php

Date

Next