I created some nice work week-related functions in PHP that will calculate and return the next available work day, based on any particular date and number days from that date. These were helpful for me in scheduling,appointments, or deadlines for users and clients that are open only Monday-Friday for a 5 day work week.

My latest usage of these functions was to assign tasks to users of the application and give them one full work week to complete the task.

Therefore, I needed my PHP code to calculate one full work week and return the date that would be their deadline.

This script counts through days, ignoring weekends and US holidays (optional). My database holds both federal and banking holidays (we have a lot of banking clients), but other users may just want federal holidays or not at all.

Therefore, the holiday function is separate. If you do not wish to include holidays in your calculations, simply remove all the dates from the array down at the bottom.

Using this script

This script is a single PHP class that uses public static functions, meaning that they can be called directly from anywhere, without having to instantiate an object. This PHP code has been tested in both PHP 5.2.0 and PHP 5.3.9.

Download this script: WorkDays.class.php

Some Useful Examples

All methods count today! If today is Wednesday and not a holiday, then WorkDays::getNextWorkDay() will return today’s date.

 
// Get next available work day from now, as a timestamp
WorkDays::getNextWorkDay();
 
// Get next available work day from now, as a formatted date
WorkDays::getNextWorkDay(NULL,"Y-m-d");
 
// Get next available work day from a specific day, as a formatted date
WorkDays::getNextWorkDay("Wednesday July 4th, 2012","Y-m-d");  // returns '2012-07-05'
 
// Get one extra work week from now, as a timestamp
WorkDays::getExtraWorkWeek();
 
// Get one extra work week from a specific day, as a formatted date
WorkDays::getExtraWorkWeek("2013-06-07","D M d, Y"); // returns 'Thu Jun 13, 2013'
 
// Get 3 extra work days from now, as a formatted date
WorkDays::getExtraWorkWeek(NULL,"Y-m-d");
 
// Get 6 extra work days from Christmas Day 2012, as a formatted date
WorkDays::getExtraWorkDays("2012-12-25","D M d, Y",6); // returns 'Thu Jan 03, 2013'

The Script

<?php
 
class WorkDays
{
	/**
	* @static getNextWorkDay()
	* @param string|int $date OPTIONAL a date string or Unix timestamp 
	* @param string $format OPTIONAL desired format of return value
	* @return int|string either a Unix timestamp or formatted date
	*
	* Gets next available work date (COULD BE SAME DAY)
	**/
 
	public static function getNextWorkDay($date=false,$format=false)
	{ 	
		$time = is_string($date) ? strtotime($date) : (is_int($date) ? $date : time());
		$holidays = self::getHolidays();
 
		for ($i=0; $i<5; $i++, $time+=86400)
		{ 
			if (in_array(date('w', $time), array(0, 6))) continue;
			foreach ($holidays as $h)
			{
				if ($time>=$h && $time<$h+86400) continue 2;			
			}
			break;
		}
		return ($format) ? date($format,$time) : $time;
	} 
 
	/**
	* @static getExtraWorkWeek()
	* @param string|int $date OPTIONAL a date string or Unix timestamp 
	* @param string $format OPTIONAL desired format of return value
	* @return int|string either a Unix timestamp or formatted date
	*
	* A shortcut to call getExtraWorkDays() with 5 days as a param 
	**/
 
	public static function getExtraWorkWeek($date=false,$format=false)
	{ 	
		return self::getExtraWorkDays($date,$format,5);
	}
 
	/**
	* @static getExtraWorkDays()
	* @param string|int $date OPTIONAL a date string or Unix timestamp 
	* @param string $format OPTIONAL desired format of return value
	* @param int $numdays OPTIONAL number of additional work days to add to date
	* @return int|string either a Unix timestamp or formatted date
	*
	* Gets the date after a specific number of work days. accounts for weekends and holidays 
	* Includes today by default
	* If you want to skip today, provide tomorrow's date as the argument
	**/
 
	public static function getExtraWorkDays($date=false,$format=false,$numdays=1)
	{
		$time = is_string($date) ? strtotime($date) : (is_int($date) ? $date : time());
		$count = 0;
		$finaldate = "";
 
		$holidays = self::getHolidays();
 
		$range = ($numdays > 5) ? ($numdays * 2) : 10;
 
		for($i=0; $i<$range; $i++, $time+=86400)
		{
			if (in_array(date('w', $time), array(0, 6))) continue;
			foreach ($holidays as $h)
			{
				if ($time>=$h && $time<$h+86400) continue 2;
			}
			$count++; 
			if($count == $numdays)
			{
				$finaldate = $time;
				break;
			}
		}
		return ($format) ? date($format,$finaldate) : $finaldate;
	}
 
	/**
	* @return mixed
	*
	* Returns an array of holiday dates
	**/	
 
	public static function getHolidays()
	{
		$holidays = array();
		$harr = array(
		"2012-01-02","2012-01-16","2012-02-20","2012-05-28","2012-07-04","2012-09-03",
		"2012-10-08","2012-11-12","2012-11-22","2012-12-25","2013-01-01","2013-01-21",
		"2013-02-18","2013-05-27","2013-07-04","2013-09-02","2013-10-14","2013-11-11",
		"2013-11-28","2013-12-25","2014-01-01","2014-01-20","2014-02-17","2014-05-26",
		"2014-07-04","2014-09-01","2014-10-13","2014-11-11","2014-11-27","2014-12-25");
 
		// OPTIONALLY fill $harr from your own database table.
 
		foreach ($harr as $hitem) {
			$h = explode('-', $hitem);        
			$htime = mktime(0, 0, 0, $h[1], $h[2], $h[0]);
			$weekday = date('w', $htime);
			$htime += $weekday==0 ? 86400 : ($weekday==6 ? -86400 : 0);
			$holidays[] = $htime;
		}
		return $holidays;
	}
}
 
?>

If you have any questions about using these methods or want to see an addition for your needs, leave a comment below.