# 计算工作日

``<?php //The function returns the no. of business days between two dates and it skips the holidays function getWorkingDays(\$startDate,\$endDate,\$holidays){ // do strtotime calculations just once \$endDate = strtotime(\$endDate); \$startDate = strtotime(\$startDate); //The total number of days between the two dates. We compute the no. of seconds and divide it to 60*60*24 //We add one to inlude both dates in the interval. \$days = (\$endDate - \$startDate) / 86400 + 1; \$no_full_weeks = floor(\$days / 7); \$no_remaining_days = fmod(\$days, 7); //It will return 1 if it's Monday,.. ,7 for Sunday \$the_first_day_of_week = date("N", \$startDate); \$the_last_day_of_week = date("N", \$endDate); //---->The two can be equal in leap years when february has 29 days, the equal sign is added here //In the first case the whole interval is within a week, in the second case the interval falls in two weeks. if (\$the_first_day_of_week <= \$the_last_day_of_week) { if (\$the_first_day_of_week <= 6 && 6 <= \$the_last_day_of_week) \$no_remaining_days--; if (\$the_first_day_of_week <= 7 && 7 <= \$the_last_day_of_week) \$no_remaining_days--; } else { // (edit by Tokes to fix an edge case where the start day was a Sunday // and the end day was NOT a Saturday) // the day of the week for start is later than the day of the week for end if (\$the_first_day_of_week == 7) { // if the start date is a Sunday, then we definitely subtract 1 day \$no_remaining_days--; if (\$the_last_day_of_week == 6) { // if the end date is a Saturday, then we subtract another day \$no_remaining_days--; } } else { // the start date was a Saturday (or earlier), and the end date was (Mon..Fri) // so we skip an entire weekend and subtract 2 days \$no_remaining_days -= 2; } } //The no. of business days is: (number of weeks between the two dates) * (5 working days) + the remainder //---->february in none leap years gave a remainder of 0 but still calculated weekends between first and last day, this is one way to fix it \$workingDays = \$no_full_weeks * 5; if (\$no_remaining_days > 0 ) { \$workingDays += \$no_remaining_days; } //We subtract the holidays foreach(\$holidays as \$holiday){ \$time_stamp=strtotime(\$holiday); //If the holiday doesn't fall in weekend if (\$startDate <= \$time_stamp && \$time_stamp <= \$endDate && date("N",\$time_stamp) != 6 && date("N",\$time_stamp) != 7) \$workingDays--; } return \$workingDays; } //Example: \$holidays=array("2008-12-25","2008-12-26","2009-01-01"); echo getWorkingDays("2008-12-22","2009-01-02",\$holidays) // => will return 7 ?>` `

### 使用示例：

` `echo number_of_working_days('2013-12-23', '2013-12-29');` `

### 输出：

` `3` `

### 功能：

` `function number_of_working_days(\$from, \$to) { \$workingDays = [1, 2, 3, 4, 5]; # date format = N (1 = Monday, ...) \$holidayDays = ['*-12-25', '*-01-01', '2013-12-23']; # variable and fixed holidays \$from = new DateTime(\$from); \$to = new DateTime(\$to); \$to->modify('+1 day'); \$interval = new DateInterval('P1D'); \$periods = new DatePeriod(\$from, \$interval, \$to); \$days = 0; foreach (\$periods as \$period) { if (!in_array(\$period->format('N'), \$workingDays)) continue; if (in_array(\$period->format('Ym-d'), \$holidayDays)) continue; if (in_array(\$period->format('*-m-d'), \$holidayDays)) continue; \$days++; } return \$days; }` `

date（）函数有一些参数应该有帮助。 如果你检查日期（“W”），它会给你一个星期几的数字，从星期天的0到星期六的6。 所以..也许就像..

` `\$busDays = 3; \$day = date("w"); if( \$day > 2 && \$day <= 5 ) { /* if between Wed and Fri */ \$day += 2; /* add 2 more days for weekend */ } \$day += \$busDays;` `

` `/** * National American Holidays * @param string \$year * @return array */ public static function getNationalAmericanHolidays(\$year) { // January 1 - New Year's Day (Observed) // Calc Last Monday in May - Memorial Day strtotime("last Monday of May 2011"); // July 4 Independence Day // First monday in september - Labor Day strtotime("first Monday of September 2011") // November 11 - Veterans' Day (Observed) // Fourth Thursday in November Thanksgiving strtotime("fourth Thursday of November 2011"); // December 25 - Christmas Day \$bankHolidays = array( \$year . "-01-01" // New Years , "". date("Ymd",strtotime("last Monday of May " . \$year) ) // Memorial Day , \$year . "-07-04" // Independence Day (corrected) , "". date("Ymd",strtotime("first Monday of September " . \$year) ) // Labor Day , \$year . "-11-11" // Veterans Day , "". date("Ymd",strtotime("fourth Thursday of November " . \$year) ) // Thanksgiving , \$year . "-12-25" // XMAS ); return \$bankHolidays; }` `

` ` function add_business_days(\$startdate,\$buisnessdays,\$holidays,\$dateformat){ \$i=1; \$dayx = strtotime(\$startdate); while(\$i < \$buisnessdays){ \$day = date('N',\$dayx); \$date = date('Ym-d',\$dayx); if(\$day < 6 && !in_array(\$date,\$holidays))\$i++; \$dayx = strtotime(\$date.' +1 day'); } return date(\$dateformat,\$dayx); } //Example date_default_timezone_set('Europe\London'); \$startdate = '2012-01-08'; \$holidays=array("2012-01-10"); echo '<p>Start date: '.date('r',strtotime( \$startdate)); echo '<p>'.add_business_days(\$startdate,7,\$holidays,'r');` `

` ` date_default_timezone_set('Europe\London'); //Example: \$holidays = array('2012-01-10'); \$startDate = '2012-01-08'; \$endDate = '2012-01-13'; echo getWorkingDays( \$startDate,\$endDate,\$holidays);` `

` `Sun, 08 Jan 2012 00:00:00 +0000 weekend Mon, 09 Jan 2012 00:00:00 +0000 Tue, 10 Jan 2012 00:00:00 +0000 holiday Wed, 11 Jan 2012 00:00:00 +0000 Thu, 12 Jan 2012 00:00:00 +0000 Fri, 13 Jan 2012 00:00:00 +0000` `

` ` function get_working_days(\$startDate,\$endDate,\$holidays){ \$debug = true; \$work = 0; \$nowork = 0; \$dayx = strtotime(\$startDate); \$endx = strtotime(\$endDate); if(\$debug){ echo '<h1>get_working_days</h1>'; echo 'startDate: '.date('r',strtotime( \$startDate)).'<br>'; echo 'endDate: '.date('r',strtotime( \$endDate)).'<br>'; var_dump(\$holidays); echo '<p>Go to work...'; } while(\$dayx <= \$endx){ \$day = date('N',\$dayx); \$date = date('Ym-d',\$dayx); if(\$debug)echo '<br />'.date('r',\$dayx).' '; if(\$day > 5 || in_array(\$date,\$holidays)){ \$nowork++; if(\$debug){ if(\$day > 5)echo 'weekend'; else echo 'holiday'; } } else \$work++; \$dayx = strtotime(\$date.' +1 day'); } if(\$debug){ echo '<p>No work: '.\$nowork.'<br>'; echo 'Work: '.\$work.'<br>'; echo 'Work + no work: '.(\$nowork+\$work).'<br>'; echo 'All seconds / seconds in a day: '.floatval(strtotime(\$endDate)-strtotime(\$startDate))/floatval(24*60*60); } return \$work; } date_default_timezone_set('Europe\London'); //Example: \$holidays=array("2012-01-10"); \$startDate = '2012-01-08'; \$endDate = '2012-01-13'; //broken echo getWorkingDays( \$startDate,\$endDate,\$holidays); //works echo get_working_days( \$startDate,\$endDate,\$holidays);` `

` `\$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);` `

` `function dateFromBusinessDays(\$days, \$dateTime=null) { \$dateTime = is_null(\$dateTime) ? time() : \$dateTime; \$_day = 0; \$_direction = \$days == 0 ? 0 : intval(\$days/abs(\$days)); \$_day_value = (60 * 60 * 24); while(\$_day !== \$days) { \$dateTime += \$_direction * \$_day_value; \$_day_w = date("w", \$dateTime); if (\$_day_w > 0 && \$_day_w < 6) { \$_day += \$_direction * 1; } } return \$dateTime; }` `

` `echo date("m/d/Y", dateFromBusinessDays(-7)); echo date("m/d/Y", dateFromBusinessDays(3, time() + 3*60*60*24));` `

` `function business_days_add(\$start_date, \$business_days, \$holidays = array()) { \$current_date = strtotime(\$start_date); \$business_days = intval(\$business_days); // Decrement does not work on strings while (\$business_days > 0) { if (date('N', \$current_date) < 6 && !in_array(date('Ym-d', \$current_date), \$holidays)) { \$business_days--; } if (\$business_days > 0) { \$current_date = strtotime('+1 day', \$current_date); } } return \$current_date; }` `

` `function business_days_diff(\$start_date, \$end_date, \$holidays = array()) { \$business_days = 0; \$current_date = strtotime(\$start_date); \$end_date = strtotime(\$end_date); while (\$current_date <= \$end_date) { if (date('N', \$current_date) < 6 && !in_array(date('Ym-d', \$current_date), \$holidays)) { \$business_days++; } if (\$current_date <= \$end_date) { \$current_date = strtotime('+1 day', \$current_date); } } return \$business_days; }` `

` `if (date('N')<6 && date('G')>8 && date('G')<16) { // we have a working time (or check for holidays) }` `

` `function getWorkingDays(\$startDate, \$endDate) { \$begin = strtotime(\$startDate); \$end = strtotime(\$endDate); if (\$begin > \$end) { return 0; } else { \$no_days = 0; while (\$begin <= \$end) { \$what_day = date("N", \$begin); if (!in_array(\$what_day, [6,7]) ) // 6 and 7 are weekend \$no_days++; \$begin += 86400; // +1 day }; return \$no_days; } }` `

` `// I know, these aren't holidays \$holidays = array( 'Jan 2', 'Feb 3', 'Mar 5', 'Apr 7', // ... );` `

` `\$day_of_year = date('M j', \$timestamp); \$is_holiday = in_array(\$day_of_year, \$holidays);` `

` ` function add_business_days(\$startdate,\$buisnessdays,\$holidays=array(),\$dateformat){ \$enddate = strtotime(\$startdate); \$day = date('N',\$enddate); while(\$buisnessdays > 1){ \$enddate = strtotime(date('Ym-d',\$enddate).' +1 day'); \$day = date('N',\$enddate); if(\$day < 6 && !in_array(\$enddate,\$holidays))\$buisnessdays--; } return date(\$dateformat,\$enddate); }` `

` `<?php /* * Does not count current day, the date returned is the last business day * Requires PHP 5.1 (Using ISO-8601 week) */ function businessDays(\$timestamp = false, \$bDays = 2) { if(\$timestamp === false) \$timestamp = time(); while (\$bDays>0) { \$timestamp += 86400; if (date('N', \$timestamp)<6) \$bDays--; } return \$timestamp; }` `

` `<?php /* * Does not count current day, the date returned is a business day * following the last business day * Requires PHP 5.1 (Using ISO-8601 week) */ function businessDays(\$timestamp = false, \$bDays = 2) { if(\$timestamp === false) \$timestamp = time(); while (\$bDays+1>0) { \$timestamp += 86400; if (date('N', \$timestamp)<6) \$bDays--; } return \$timestamp; }` `

` `<?php /* * Does not count current day, the date returned is * a date following the last business day (can be weekend or not. * See above for alternatives) * Requires PHP 5.1 (Using ISO-8601 week) */ function businessDays(\$timestamp = false, \$bDays = 2) { if(\$timestamp === false) \$timestamp = time(); while (\$bDays>0) { \$timestamp += 86400; if (date('N', \$timestamp)<6) \$bDays--; } return \$timestamp += 86400; }` `

` `\$holidays = array_flip(strtotime('2011-01-01'),strtotime('2011-12-25'));` `

` `if (date('N', \$timestamp)<6) \$bDays--;` `

` `if (date('N', \$timestamp)<6 && !isset(\$holidays[\$timestamp])) \$bDays--;` `

` `<?php /* * Does not count current day, the date returned is the last business day * Requires PHP 5.1 (Using ISO-8601 week) */ function businessDays(\$timestamp = false, \$bDays = 2) { if(\$timestamp === false) \$timestamp = strtotime(date('Ym-d',time())); \$holidays = array_flip(strtotime('2011-01-01'),strtotime('2011-12-25')); while (\$bDays>0) { \$timestamp += 86400; if (date('N', \$timestamp)<6 && !isset(\$holidays[\$timestamp])) \$bDays--; } return \$timestamp; }` `
` `<?php function AddWorkDays(){ \$i = 0; \$d = 5; // Number of days to add while(\$i <= \$d) { \$i++; if(date('N', mktime(0, 0, 0, date(m), date(d)+\$i, date(Y))) < 5) { \$d++; } } return date(Y).','.date(m).','.(date(d)+\$d); } ?>` `

` `// Returns a \$numBusDays-sized array of all business dates, // starting from and including \$currentDate. // Any date in \$holidays will be skipped over. function getWorkingDays(\$currentDate, \$numBusDays, \$holidays = array(), \$resultDates = array()) { // exit when we have collected the required number of business days if (\$numBusDays === 0) { return \$resultDates; } // add current date to return array, if not a weekend or holiday \$date = date("w", strtotime(\$currentDate)); if ( \$date != 0 && \$date != 6 && !in_array(\$currentDate, \$holidays) ) { \$resultDates[] = \$currentDate; \$numBusDays -= 1; } // set up the next date to test \$currentDate = new DateTime("\$currentDate + 1 day"); \$currentDate = \$currentDate->format('Ym-d'); return getWorkingDays(\$currentDate, \$numBusDays, \$holidays, \$resultDates); } // test \$days = getWorkingDays('2008-12-05', 4); print_r(\$days);` `
` `date_default_timezone_set('America/New_York'); /** Given a number days out, what day is that when counting by 'business' days * get the next business day. by default it looks for next business day * ie calling \$date = get_next_busines_day(); on monday will return tuesday * \$date = get_next_busines_day(2); on monday will return wednesday * \$date = get_next_busines_day(2); on friday will return tuesday * * @param \$number_of_business_days (integer) how many business days out do you want * @param \$start_date (string) strtotime parseable time value * @param \$ignore_holidays (boolean) true/false to ignore holidays * @param \$return_format (string) as specified in php.net/date */ function get_next_business_day(\$number_of_business_days=1,\$start_date='today',\$ignore_holidays=false,\$return_format='m/d/y') { // get the start date as a string to time \$result = strtotime(\$start_date); // now keep adding to today's date until number of business days is 0 and we land on a business day while (\$number_of_business_days > 0) { // add one day to the start date \$result = strtotime(date('Ym-d',\$result) . " + 1 day"); // this day counts if it's a weekend and not a holiday, or if we choose to ignore holidays if (is_weekday(date('Ym-d',\$result)) && (!(is_holiday(date('Ym-d',\$result))) || \$ignore_holidays) ) \$number_of_business_days--; } // when my \$number of business days is exausted I have my final date return(date(\$return_format,\$result)); } function is_weekend(\$date) { // return if this is a weekend date or not. return (date('N', strtotime(\$date)) >= 6); } function is_weekday(\$date) { // return if this is a weekend date or not. return (date('N', strtotime(\$date)) < 6); } function is_holiday(\$date) { // return if this is a holiday or not. // what are my holidays for this year \$holidays = array("New Year's Day 2011" => "12/31/10", "Good Friday" => "04/06/12", "Memorial Day" => "05/28/12", "Independence Day" => "07/04/12", "Floating Holiday" => "12/31/12", "Labor Day" => "09/03/12", "Thanksgiving Day" => "11/22/12", "Day After Thanksgiving Day" => "11/23/12", "Christmas Eve" => "12/24/12", "Christmas Day" => "12/25/12", "New Year's Day 2012" => "01/02/12", "New Year's Day 2013" => "01/01/13" ); return(in_array(date('m/d/y', strtotime(\$date)),\$holidays)); } print get_next_business_day(1) . "\n";` `
` `<?php // \$today is the UNIX timestamp for today's date \$today = time(); echo "<strong>Today is (ORDER DATE): " . '<font color="red">' . date('l, F j, Y', \$today) . "</font></strong><br/><br/>"; //The numerical representation for day of week (Ex. 01 for Monday .... 07 for Sunday \$today_numerical = date("N",\$today); //leadtime_days holds the numeric value for the number of business days \$leadtime_days = \$_POST["leadtime"]; //leadtime is the adjusted date for shipdate \$shipdate = time(); while (\$leadtime_days > 0) { if (\$today_numerical != 5 && \$today_numerical != 6) { \$shipdate = \$shipdate + (60*60*24); \$today_numerical = date("N",\$shipdate); \$leadtime_days --; } else \$shipdate = \$shipdate + (60*60*24); \$today_numerical = date("N",\$shipdate); } echo '<strong>Estimated Ship date: ' . '<font color="green">' . date('l, F j, Y', \$shipdate) . "</font></strong>"; ?>` `

` `<?php \$holiday_date_array = array("2016-01-26", "2016-03-07", "2016-03-24", "2016-03-25", "2016-04-15", "2016-08-15", "2016-09-12", "2016-10-11", "2016-10-31"); \$date_required = "2016-03-01"; function increase_date(\$date_required, \$holiday_date_array=array(), \$days = 15){ if(!empty(\$date_required)){ \$counter_1=0; \$incremented_date = ''; for(\$i=1; \$i <= \$days; \$i++){ \$date = strtotime("+\$i day", strtotime(\$date_required)); \$day_name = date("D", \$date); \$incremented_date = date("Ymd", \$date); if(\$day_name=='Sat'||\$day_name=='Sun'|| in_array(\$incremented_date ,\$holiday_date_array)==true){ \$counter_1+=1; } } if(\$counter_1 > 0){ return increase_date(\$incremented_date, \$holiday_date_array, \$counter_1); }else{ return \$incremented_date; } }else{ return 'invalid'; } } echo increase_date(\$date_required, \$holiday_date_array, 15); ?> //output after adding 15 business working days in 2016-03-01 will be "2016-03-23"` `

` `// \$start_date will default to today if (\$start_date=='') { \$start_date = date("Ymd"); } \$business_day_ct = 0; \$max_days = 10000 + \$num_days; // to avoid any possibility of an infinite loop // define holidays, this currently only goes to 2012 because, well, you know... ;-) // if the world is still here after that, you can find more at // http://www.opm.gov/Operating_Status_Schedules/fedhol/2013.asp // always add holidays in order, because the iteration will stop when the holiday is > date being tested \$fed_holidays=array( "2010-01-01", "2010-01-18", "2010-02-15", "2010-05-31", "2010-07-05", "2010-09-06", "2010-10-11", "2010-11-11", "2010-11-25", "2010-12-24", "2010-12-31", "2011-01-17", "2011-02-21", "2011-05-30", "2011-07-04", "2011-09-05", "2011-10-10", "2011-11-11", "2011-11-24", "2011-12-26", "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", ); \$curr_date_ymd = date('Ym-d', strtotime(\$start_date)); for (\$x=1;\$x<\$max_days;\$x++) { if (intval(\$num_days)==intval(\$business_day_ct)) { return(date(\$rtn_fmt, strtotime(\$curr_date_ymd))); } // date found - return // get next day to check \$curr_date_ymd = date('Ym-d', (strtotime(\$start_date)+(\$x * 86400))); // add 1 day to the current date \$is_business_day = 1; // check if this is a weekend 1 (for Monday) through 7 (for Sunday) if ( intval(date("N",strtotime(\$curr_date_ymd))) > 5) { \$is_business_day = 0; } //check for holiday foreach(\$fed_holidays as \$holiday) { if (strtotime(\$holiday)==strtotime(\$curr_date_ymd)) // holiday found { \$is_business_day = 0; break 1; } if (strtotime(\$holiday)>strtotime(\$curr_date_ymd)) { break 1; } // past date, stop searching (always add holidays in order) } \$business_day_ct = \$business_day_ct + \$is_business_day; // increment if this is a business day } // if we get here, you are hosed return ("ERROR");` `

}

` `function add_business_days(\$startdate, \$buisnessdays, \$holidays = array(), \$dateformat = 'Ym-d'){ \$i= 1; \$dayx= strtotime(\$startdate); \$buisnessdays= ceil(\$buisnessdays); while(\$i < \$buisnessdays) { \$day= date('N',\$dayx); \$date= date('Ym-d',\$dayx); if(\$day < 6 && !in_array(\$date,\$holidays)) \$i++; \$dayx= strtotime(\$date.' +1 day'); } ## If the calculated day falls on a weekend or is a holiday, then add days to the next business day \$day= date('N',\$dayx); \$date= date('Ym-d',\$dayx); while(\$day >= 6 || in_array(\$date,\$holidays)) { \$dayx= strtotime(\$date.' +1 day'); \$day= date('N',\$dayx); \$date= date('Ym-d',\$dayx); } return date(\$dateformat, \$dayx);}` `

` `function add_business_days(\$startdate,\$buisnessdays,\$holidays,\$dateformat){ \$enddate = strtotime(\$startdate); \$day = date('N',\$enddate); while(\$buisnessdays > 0){ // compatible with 1 businessday if I'll need it \$enddate = strtotime(date('Ym-d',\$enddate).' +1 day'); \$day = date('N',\$enddate); if(\$day < 6 && !in_array(date('Ym-d',\$enddate),\$holidays))\$buisnessdays--; } return date(\$dateformat,\$enddate); } // as a parameter in in_array function we should use endate formated to // compare correctly with the holidays array.` `

/ **
*美国国家假期
* @参数字符串\$年
* @return数组
* /

` `// January 1 - New Year's Day (Observed) // Third Monday in January - Birthday of Martin Luther King, Jr. // Third Monday in February - Washington's Birthday / President's Day // Last Monday in May - Memorial Day // July 4 - Independence Day // First Monday in September - Labor Day // Second Monday in October - Columbus Day // November 11 - Veterans' Day (Observed) // Fourth Thursday in November Thanksgiving Day // December 25 - Christmas Day \$bankHolidays = array( ['New Years Day'] => \$year . "-01-01", ['Martin Luther King Jr Birthday'] => "". date("Ymd",strtotime("third Monday of January " . \$year) ), ['Washingtons Birthday'] => "". date("Ymd",strtotime("third Monday of February " . \$year) ), ['Memorial Day'] => "". date("Ymd",strtotime("last Monday of May " . \$year) ), ['Independance Day'] => \$year . "-07-04", ['Labor Day'] => "". date("Ymd",strtotime("first Monday of September " . \$year) ), ['Columbus Day'] => "". date("Ymd",strtotime("second Monday of October " . \$year) ), ['Veterans Day'] => \$year . "-11-11", ['Thanksgiving Day'] => "". date("Ymd",strtotime("fourth Thursday of November " . \$year) ), ['Christmas Day'] => \$year . "-12-25" ); return \$bankHolidays;` `

}

〜Nate

PHP类来计算工作日

` `<?php function count_business_days(\$date, \$days, \$holidays) { \$date = strtotime(\$date); for (\$i = 1; \$i <= intval(\$days); \$i++) { //Loops each day count //First, find the next available weekday because this might be a weekend/holiday while (date('N', \$date) >= 6 || in_array(date('Ym-d', \$date), \$holidays)){ \$date = strtotime(date('Ym-d',\$date).' +1 day'); } //Now that we know we have a business day, add 1 day to it \$date = strtotime(date('Ym-d',\$date).' +1 day'); //If this day that was previously added falls on a weekend/holiday, then find the next business day while (date('N', \$date) >= 6 || in_array(date('Ym-d', \$date), \$holidays)){ \$date = strtotime(date('Ym-d',\$date).' +1 day'); } } return date('Ym-d', \$date); } //Also add in the code from Tony and James Pasta to handle holidays... function getNationalAmericanHolidays(\$year) { \$bankHolidays = array( 'New Years Day' => \$year . "-01-01", 'Martin Luther King Jr Birthday' => "". date("Ymd",strtotime("third Monday of January " . \$year) ), 'Washingtons Birthday' => "". date("Ymd",strtotime("third Monday of February " . \$year) ), 'Memorial Day' => "". date("Ymd",strtotime("last Monday of May " . \$year) ), 'Independance Day' => \$year . "-07-04", 'Labor Day' => "". date("Ymd",strtotime("first Monday of September " . \$year) ), 'Columbus Day' => "". date("Ymd",strtotime("second Monday of October " . \$year) ), 'Veterans Day' => \$year . "-11-11", 'Thanksgiving Day' => "". date("Ymd",strtotime("fourth Thursday of November " . \$year) ), 'Christmas Day' => \$year . "-12-25" ); return \$bankHolidays; } //Now to call it... since we're working with business days, we should //also be working with business hours so check if it's after 5 PM //and go to the next day if necessary. //Go to next day if after 5 pm (5 pm = 17) if (date(G) >= 17) { \$start_date = date("Ymd", strtotime("+ 1 day")); //Tomorrow } else { \$start_date = date("Ymd"); //Today } //Get the holidays for the current year and also for the next year \$this_year = getNationalAmericanHolidays(date('Y')); \$next_year = getNationalAmericanHolidays(date('Y', strtotime("+12 months"))); \$holidays = array_merge(\$this_year, \$next_year); //The number of days to count \$days_count = 10; echo count_business_days(\$start_date, \$days_count, \$holidays); ?>` `

` `function onlyWorkDays( \$d ) { \$holidays = array('2013-12-25','2013-12-31','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','2014-12-31'); while (in_array(\$d->format("Ymd"), \$holidays)) { // HOLIDAYS \$d->sub(new DateInterval("P1D")); } if (\$d->format("w") == 6) { // SATURDAY \$d->sub(new DateInterval("P1D")); } if (\$d->format("w") == 0) { // SUNDAY \$d->sub(new DateInterval("P2D")); } return \$d; }` `

` `function getBusinessDays(\$date1, \$date2){ if(!is_numeric(\$date1)){ \$date1 = strtotime(\$date1); } if(!is_numeric(\$date2)){ \$date2 = strtotime(\$date2); } if(\$date2 < \$date1){ \$temp_date = \$date1; \$date1 = \$date2; \$date2 = \$temp_date; unset(\$temp_date); } \$diff = \$date2 - \$date1; \$days_diff = intval(\$diff / (3600 * 24)); \$current_day_of_week = intval(date("N", \$date1)); \$business_days = 0; for(\$i = 1; \$i <= \$days_diff; \$i++){ if(!in_array(\$current_day_of_week, array("Sunday" => 1, "Saturday" => 7))){ \$business_days++; } \$current_day_of_week++; if(\$current_day_of_week > 7){ \$current_day_of_week = 1; } } return \$business_days; } echo "Business days: " . getBusinessDays("8/15/2014", "8/8/2014");` `

PHPClass为这个命名的PHP工作日有一个很好的类。 你可以检查这个课程。

1. 需要指定您将要工作的工作日（默认为MON-FRI） – 该类允许您单独启用或禁用每个工作日。
2. 需要知道你需要考虑公众假期（国家和州）是否准确

Functional Approach

` `/** * @param days, int * @param \$format, string: dateformat (if format defined OTHERWISE int: timestamp) * @param start, int: timestamp (mktime) default: time() //now * @param \$wk, bit[]: flags for each workday (0=SUN, 6=SAT) 1=workday, 0=day off * @param \$holiday, string[]: list of dates, YYYY-MM-DD, MM-DD */ function working_days(\$days, \$format='', \$start=null, \$week=[0,1,1,1,1,1,0], \$holiday=[]) { if(is_null(\$start)) \$start = time(); if(\$days <= 0) return \$start; if(count(\$week) != 7) trigger_error('workweek must contain bit-flags for 7 days'); if(array_sum(\$week) == 0) trigger_error('workweek must contain at least one workday'); \$wd = date('w', \$start);//0=sun, 6=sat \$time = \$start; while(\$days) { if( \$week[\$wd] && !in_array(date('Ym-d', \$time), \$holiday) && !in_array(date('m-d', \$time), \$holiday) ) --\$days; //decrement on workdays \$wd = date('w', \$time += 86400); //add one day in seconds } \$time -= 86400;//include today return \$format ? date(\$format, \$time): \$time; } //simple usage \$ten_days = working_days(10, 'DF d Y'); echo '<br>ten workingdays (MON-FRI) disregarding holidays: ',\$ten_days; //work on saturdays and add new years day as holiday \$ten_days = working_days(10, 'DF d Y', null, [0,1,1,1,1,1,1], ['01-01']); echo '<br>ten workingdays (MON-SAT) disregarding holidays: ',\$ten_days;` `

This is another solution, it is nearly 25% faster than checking holidays with in_array:

` `/** * Function to calculate the working days between two days, considering holidays. * @param string \$startDate -- Start date of the range (included), formatted as Ymd. * @param string \$endDate -- End date of the range (included), formatted as Ymd. * @param array(string) \$holidayDates -- OPTIONAL. Array of holidays dates, formatted as Ymd. (eg array("2016-08-15", "2016-12-25")) * @return int -- Number of working days. */ function getWorkingDays(\$startDate, \$endDate, \$holidayDates=array()){ \$dateRange = new DatePeriod(new DateTime(\$startDate), new DateInterval('P1D'), (new DateTime(\$endDate))->modify("+1day")); foreach (\$dateRange as \$dr) { if(\$dr->format("N")<6){\$workingDays[]=\$dr->format("Ymd");} } return count(array_diff(\$workingDays, \$holidayDates)); }` `