Justin Paul Silva

Calculating Business Days in PHP

Posted on

For one of my client’s projects, The Superdups Self-Service Quoter, I had to write an algorithm to estimate due date of each order based on a selected turn around time in business days. This would probably be a simply task in Ruby on Rails, but unfortunately, that wasn’t an option.

The Code

class DateHelper { // Holidays must be in order var $holidays = array("2010-07-04", "2010-09-06", "2010-09-23", "2010-10-11", "2010-11-01", "2010-11-11", "2010-11-25", "2010-12-25"); const oneday = 86400; // 86400 seconds = 1 Day const weekend = 172800; // 172800 seconds = 2 Days function addBusinessDays($start_date, $business_days) { // If $start_date is on the weekend, start on following Monday if (date('N', $start_date) == 6) { // If start date is on Saturday $new_start_date = $start_date + self::weekend; } elseif (date('N', $start_date) == 7) { // If start date is on Sunday $new_start_date = $start_date + self::oneday; } else { $new_start_date = $start_date; } // Add business days to the start date $due_date = $new_start_date + $business_days * self::oneday; // For every 5 business days, add 2 more for the weekend $due_date += floor($business_days / 5) * self::weekend; // If remainder of business days causes due date to land on or after the weekend if (($business_days % 5) + date('N', $new_start_date) >= 6) { $due_date += self::weekend; // Add 2 days to compensate for the weekend } foreach($this->holidays as $holiday){ $time_stamp = strtotime($holiday); // If the holiday falls between the start date and end date // and is on a weekday // Or if $new_start_date is on a holiday if (($start_date <= $time_stamp && $time_stamp <= $due_date && date("N", $time_stamp) < 6) || date("Y-m-d", $new_start_date) == $holiday) { $due_date += self::oneday; if (date('N', $due_date) >= 6) { // If due date on Saturday or Sunday $due_date += self::weekend; } } } return $due_date; } }

Usage

addBusinessDays ( int $start_date , int $business_days )

$date = new DateHelper; $start = time(); echo date("l, M d, Y", $start); echo "\n+ 0 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 0)); echo "\n+ 1 Day = " . date("l, M d, Y", $date->addBusinessDays($start, 1)); echo "\n+ 2 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 2)); echo "\n+ 3 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 3)); echo "\n+ 4 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 4)); echo "\n+ 5 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 5)); echo "\n+ 6 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 6)); echo "\n+ 7 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 7)); echo "\n+ 8 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 8)); echo "\n+ 9 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 9)); echo "\n+ 10 Days = " . date("l, M d, Y", $date->addBusinessDays($start, 10));

Result

Friday, Jun 04, 2010 + 0 Days = Friday, Jun 04, 2010 + 1 Day = Monday, Jun 07, 2010 + 2 Days = Tuesday, Jun 08, 2010 + 3 Days = Wednesday, Jun 09, 2010 + 4 Days = Thursday, Jun 10, 2010 + 5 Days = Friday, Jun 11, 2010 + 6 Days = Monday, Jun 14, 2010 + 7 Days = Tuesday, Jun 15, 2010 + 8 Days = Wednesday, Jun 16, 2010 + 9 Days = Thursday, Jun 17, 2010 + 10 Days = Friday, Jun 18, 2010

Usage Notes