【问题标题】:Calculate business days计算工作日
【发布时间】:2010-09-25 01:37:36
【问题描述】:

我需要一种在 PHP 中添加“工作日”的方法。例如,周五 12 月 5 日 + 3 个工作日 = 周三 12 月 10 日。

至少我需要代码来理解周末,但理想情况下它也应该考虑到美国联邦假日。我敢肯定,如有必要,我可以通过蛮力提出解决方案,但我希望那里有更优雅的方法。有人吗?

谢谢。

【问题讨论】:

标签: php calendar date


【解决方案1】:

这是 PHP 手册中 date() 函数页面上 user comments 中的一个函数。这是对 cme​​ts 中早期功能的改进,增加了对闰年的支持。

输入开始和结束日期,以及可能介于两者之间的任何假期的数组,并将工作日作为整数返回:

<?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
?>

【讨论】:

  • 这个函数需要一个开始和结束日期如果你有一个开始日期并且你希望结果是给定日期的 x 个工作日怎么办?
  • 这个函数有一个bug。如果这些日期之间有时区变化怎么办?例如对于 CEST: echo getWorkingDays("2012-01-01","2012-05-01",$holidays);不会给你整数。 stackoverflow.com/questions/12490521/…
  • 这是的方法。如果可能,请使用 Glavić 答案
  • 对我来说,这个功能在最后几个季度出现了错误 - 可能是由于前面提到的 DST 错误。使用 Glavic 的方法效果很好。
  • 这个方法非常复杂,有更简单的方法可以实现,只需向下滚动...
【解决方案2】:

获取两个日期之间无节假日的工作日数

使用示例:

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('Y-m-d'), $holidayDays)) continue;
        if (in_array($period->format('*-m-d'), $holidayDays)) continue;
        $days++;
    }
    return $days;
}

【讨论】:

  • 我投了赞成票,因为它可以工作并且有一些很大的改进 :) 但是你真的应该至少提到一个月前发布大部分代码的@Suresh Kamrushi。 :)
  • 如果工作日总是周一到周五,您可以用 DateInterval 和 workingdays 数组替换 $interval = DateInterval::createFromFormat('1 weekday'); 我还建议在 foreach 之前使用 $holidays = array_flip($holidays);if isset($holidays[$period-&gt;format('Y-m-d')]); 以减少所需的处理时间每次迭代。但建议为假期创建一个自定义函数,以便能够处理相关的假期,例如感恩节 last thursday of november 或劳动节 first monday of september
  • 能否将其扩展到包括耶稣受难日(我记得好像是 3 月 21 日之后第一个满月之后的第一个星期日之前的星期五)?
  • 注意不同的时区。在欧洲/柏林这行不通。我现在只是在时间戳上使用 date('N') 并添加 1day 及其时区独立。
【解决方案3】:

date() 函数有一些参数应该会有所帮助。如果您检查 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;

这只是一种可能性的粗略示例..

【讨论】:

    【解决方案4】:

    每个州的假期计算都是非标准的。我正在编写一个银行应用程序,我需要一些硬性的业务规则,但仍然只能获得一个粗略的标准。

    /**
     * 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("Y-m-d",strtotime("last Monday of May " . $year) ) // Memorial Day
            , $year . "-07-04" // Independence Day (corrected)
            , "". date("Y-m-d",strtotime("first Monday of September " . $year) ) // Labor Day
            , $year . "-11-11" // Veterans Day
            , "". date("Y-m-d",strtotime("fourth Thursday of November " . $year) ) // Thanksgiving
            , $year . "-12-25" // XMAS
            );
    
        return $bankHolidays;
    }
    

    【讨论】:

    • 独立日是 $year.'-07-04'(7 月 4 日),而不是 6 月 4 日
    • 周末节假日在前一天(如果是周六)或后天(如果是周日)观察。我能够使用您的数组来获取实际观察到的天数。谢谢。
    【解决方案5】:
    $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);
    

    【讨论】:

      【解决方案6】:

      这是一个将工作日添加到日期的函数

       function add_business_days($startdate,$buisnessdays,$holidays,$dateformat){
        $i=1;
        $dayx = strtotime($startdate);
        while($i < $buisnessdays){
         $day = date('N',$dayx);
         $date = date('Y-m-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');
      

      另一篇文章提到 getWorkingDays(来自 php.net cmets 并包含在此处),但我认为如果您从周日开始并在工作日结束,它会中断。

      使用以下内容(您需要包含上一篇文章中的 getWorkingDays 函数)

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

      结果为 5 而不是 4

      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('Y-m-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);
      

      带上假期...

      【讨论】:

        【解决方案7】:

        你可以试试这个更简单的功能。

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

        【讨论】:

          【解决方案8】:

          我的版本基于@mcgrailm 的工作...进行了调整,因为报告需要在 3 个工作日内进行审核,如果在周末提交,则将从下周一开始计算:

          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('Y-m-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('Y-m-d', $current_date), $holidays)) {
                      $business_days++;
                  }
                  if ($current_date <= $end_date) {
                      $current_date = strtotime('+1 day', $current_date);
                  }
              }
              return $business_days;
          }
          

          请注意,使用 86400 或 24*60*60 的每个人,请不要……您的遗忘时间与冬/夏时间不同,其中一天不完全是 24 小时。虽然 strtotime('+1 day', $timestamp) 慢了一点,但更可靠。

          【讨论】:

            【解决方案9】:

            从给定日期增加或减少工作日的函数,这不考虑假期。

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

            【讨论】:

              【解决方案10】:

              检测工作时间的粗暴尝试 - 周一至周五上午 8 点至下午 4 点:

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

              【讨论】:

                【解决方案11】:

                以下是从给定日期计算工作日的工作代码。

                <?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("Y-m-d", $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"
                

                【讨论】:

                  【解决方案12】:

                  这段代码sn-p很容易计算没有周末和节假日的工作日:

                  function getWorkingDays($startDate,$endDate,$offdays,$holidays){
                  $endDate = strtotime($endDate);
                  $startDate = strtotime($startDate);
                  $days = ($endDate - $startDate) / 86400 + 1;
                  $counter=0;
                  for ($i = 1; $i <= $days; $i++) {
                      $the_first_day_of_week = date("N", $startDate);
                      $startDate+=86400;
                  if (!in_array($the_first_day_of_week, $offdays) && !in_array(date("Y-m-
                  d",$startDate), $holidays)) {
                  $counter++;
                  }
                  
                  }   
                  return $counter;
                  }
                  //example to use
                  $holidays=array("2017-07-03","2017-07-20");
                  $offdays=array(5,6);//weekend days Monday=1 .... Sunday=7
                  echo getWorkingDays("2017-01-01","2017-12-31",$offdays,$holidays)
                  

                  【讨论】:

                    【解决方案13】:

                    这是另一种没有 for 循环的解决方案。

                    $from = new DateTime($first_date);
                    $to = new DateTime($second_date);
                    
                    $to->modify('+1 day');
                    $interval = $from->diff($to);
                    $days = $interval->format('%a');
                    
                    $extra_days = fmod($days, 7);
                    $workdays = ( ( $days - $extra_days ) / 7 ) * 5;
                    
                    $first_day = date('N', strtotime($first_date));
                    $last_day = date('N', strtotime("1 day", strtotime($second_date)));
                    $extra = 0;
                    if($first_day > $last_day) {
                       if($first_day == 7) {
                           $first_day = 6;
                       }
                    
                       $extra = (6 - $first_day) + ($last_day - 1);
                       if($extra < 0) {
                           $extra = $extra * -1;
                       }
                    }
                    if($last_day > $first_day) {
                        $extra = $last_day - $first_day;
                    }
                    $days = $workdays + $extra
                    

                    【讨论】:

                      【解决方案14】:

                      对于假期,以 date() 可以生成的某种格式创建一个天数组。示例:

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

                      然后使用in_array()date()函数检查时间戳是否代表节日:

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

                      【讨论】:

                        【解决方案15】:

                        我也有同样的需求,我从 bobbin 的第一个例子开始,最后得到了这个

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

                        第一个人

                        【讨论】:

                        • 对不起,但你的 mcgrailm 不太好用....它没有考虑 $enddate 中的一天是否是假期...它只关心添加期间的假期,除非我错过了什么
                        • @Richard 我想我明白你的意思。它不会检查开始日期以查看它是在开始日期之后计算工作日还是假期或周末。如果您想在支票中包含开始日期,您可以去掉 +1 天
                        • 我认为这取决于语法和你想要达到的目标。例如,我正在尝试计算何时需要审核报告,但如果它是在周末提交的,并且需要在 3 个业务中完成,那么计数从星期一开始(假设它不是假期)...我已经发布了我的版本,它们都基于您的代码,但略有调整。
                        • 非常有用 - 有一件事,如果使用像 Bobbins 一样传入的假日数组,我必须将 !in_array($enddate,$holidays) 更改为 !in_array(date('Y-m-d',$enddate),$holidays) - $holidays=array('2013-06-16','2013-07-12','2013-08-05'); 否则,您正在检查一个充满日期的数组时间戳,总是返回 false。
                        【解决方案16】:

                        变体 1:

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

                        变体 2:

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

                        变体 3:

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

                        通过执行以下操作,可以使用上述变体来考虑额外的假期。笔记!确保所有时间戳都是一天中的同一时间(即午夜)。

                        制作一组假期日期(作为 unixtimestamps),即:

                        $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('Y-m-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;
                        }
                        

                        【讨论】:

                          【解决方案17】:
                          <?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);
                          }
                          ?>
                          

                          【讨论】:

                            【解决方案18】:

                            这是一个递归解决方案。它可以轻松修改为仅跟踪并返回最新日期。

                            //  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('Y-m-d');
                            
                              return getWorkingDays($currentDate, $numBusDays, $holidays, $resultDates);
                            }
                            
                            //  test
                            $days = getWorkingDays('2008-12-05', 4);
                            print_r($days);
                            

                            【讨论】:

                              【解决方案19】:
                              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('Y-m-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('Y-m-d',$result)) && (!(is_holiday(date('Y-m-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";
                              

                              【讨论】:

                                【解决方案20】:
                                <?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>";
                                ?>
                                

                                【讨论】:

                                  【解决方案21】:

                                  计算两个日期之间的工作日,包括假期和自定义工作周

                                  答案并不是那么微不足道——因此我的建议是使用一个类,您可以在其中配置更多内容,而不是依赖简单的功能(或假设固定的语言环境和文化)。要在一定数量的工作日后获取日期,您将:

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

                                  函数式方法

                                  /**
                                   * @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('Y-m-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, 'D F 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, 'D F d Y', null, [0,1,1,1,1,1,1], ['01-01']);
                                  echo '<br>ten workingdays (MON-SAT) disregarding holidays: ',$ten_days;
                                  

                                  【讨论】:

                                    【解决方案22】:

                                    这是另一种解决方案,它比使用 in_array 检查假期快近 25%:

                                    /**
                                     * Function to calculate the working days between two days, considering holidays.
                                     * @param string $startDate -- Start date of the range (included), formatted as Y-m-d.
                                     * @param string $endDate -- End date of the range (included), formatted as Y-m-d.
                                     * @param array(string) $holidayDates -- OPTIONAL. Array of holidays dates, formatted as Y-m-d. (e.g. 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("Y-m-d");} }
                                        return count(array_diff($workingDays, $holidayDates));
                                    }
                                    

                                    【讨论】:

                                      【解决方案23】:

                                      我知道我迟到了,但我使用 Marcos J. Montes 的这套旧函数来计算假期和工作日。他花时间为复活节添加了 1876 年的算法,并添加了美国所有主要的假期。这可以很容易地为其他国家/地区更新。

                                      //Usage
                                      $days = 30;
                                      $next_working_date = nextWorkingDay($days, $somedate);
                                      
                                      //add date function
                                      function DateAdd($interval, $number, $date) {
                                      
                                          $date_time_array = getdate($date);
                                          //die(print_r($date_time_array));
                                      
                                          $hours = $date_time_array["hours"];
                                          $minutes = $date_time_array["minutes"];
                                          $seconds = $date_time_array["seconds"];
                                          $month = $date_time_array["mon"];
                                          $day = $date_time_array["mday"];
                                          $year = $date_time_array["year"];
                                      
                                          switch ($interval) {
                                      
                                              case "yyyy":
                                                  $year+=$number;
                                                  break;
                                              case "q":
                                                  $year+=($number*3);
                                                  break;
                                              case "m":
                                                  $month+=$number;
                                                  break;
                                              case "y":
                                              case "d":
                                              case "w":
                                                  $day+=$number;
                                                  break;
                                              case "ww":
                                                  $day+=($number*7);
                                                  break;
                                              case "h":
                                                  $hours+=$number;
                                                  break;
                                              case "n":
                                                  $minutes+=$number;
                                                  break;
                                              case "s":
                                                  $seconds+=$number; 
                                                  break;            
                                          }
                                          //      echo "day:" . $day;
                                          $timestamp= mktime($hours,$minutes,$seconds,$month,$day,$year);
                                          return $timestamp;
                                      }
                                      
                                      // the following function get_holiday() is based on the work done by
                                      // Marcos J. Montes
                                      function get_holiday($year, $month, $day_of_week, $week="") {
                                          if ( (($week != "") && (($week > 5) || ($week < 1))) || ($day_of_week > 6) || ($day_of_week < 0) ) {
                                              // $day_of_week must be between 0 and 6 (Sun=0, ... Sat=6); $week must be between 1 and 5
                                              return FALSE;
                                          } else {
                                              if (!$week || ($week == "")) {
                                                  $lastday = date("t", mktime(0,0,0,$month,1,$year));
                                                  $temp = (date("w",mktime(0,0,0,$month,$lastday,$year)) - $day_of_week) % 7;
                                              } else {
                                                  $temp = ($day_of_week - date("w",mktime(0,0,0,$month,1,$year))) % 7;
                                              }
                                      
                                              if ($temp < 0) {
                                                  $temp += 7;
                                              }
                                      
                                              if (!$week || ($week == "")) {
                                                  $day = $lastday - $temp;
                                              } else {
                                                  $day = (7 * $week) - 6 + $temp;
                                              }
                                              //echo $year.", ".$month.", ".$day . "<br><br>";
                                              return format_date($year, $month, $day);
                                          }
                                      }
                                      
                                      function observed_day($year, $month, $day) {
                                          // sat -> fri & sun -> mon, any exceptions?
                                          //
                                          // should check $lastday for bumping forward and $firstday for bumping back,
                                          // although New Year's & Easter look to be the only holidays that potentially
                                          // move to a different month, and both are accounted for.
                                      
                                          $dow = date("w", mktime(0, 0, 0, $month, $day, $year));
                                      
                                          if ($dow == 0) {
                                              $dow = $day + 1;
                                          } elseif ($dow == 6) {
                                              if (($month == 1) && ($day == 1)) {    // New Year's on a Saturday
                                                  $year--;
                                                  $month = 12;
                                                  $dow = 31;
                                              } else {
                                                  $dow = $day - 1;
                                              }
                                          } else {
                                              $dow = $day;
                                          }
                                      
                                          return format_date($year, $month, $dow);
                                      }
                                      
                                      function calculate_easter($y) {
                                          // In the text below, 'intval($var1/$var2)' represents an integer division neglecting
                                          // the remainder, while % is division keeping only the remainder. So 30/7=4, and 30%7=2
                                      //
                                          // This algorithm is from Practical Astronomy With Your Calculator, 2nd Edition by Peter
                                          // Duffett-Smith. It was originally from Butcher's Ecclesiastical Calendar, published in
                                          // 1876. This algorithm has also been published in the 1922 book General Astronomy by
                                          // Spencer Jones; in The Journal of the British Astronomical Association (Vol.88, page
                                          // 91, December 1977); and in Astronomical Algorithms (1991) by Jean Meeus. 
                                      
                                          $a = $y%19;
                                          $b = intval($y/100);
                                          $c = $y%100;
                                          $d = intval($b/4);
                                          $e = $b%4;
                                          $f = intval(($b+8)/25);
                                          $g = intval(($b-$f+1)/3);
                                          $h = (19*$a+$b-$d-$g+15)%30;
                                          $i = intval($c/4);
                                          $k = $c%4;
                                          $l = (32+2*$e+2*$i-$h-$k)%7;
                                          $m = intval(($a+11*$h+22*$l)/451);
                                          $p = ($h+$l-7*$m+114)%31;
                                          $EasterMonth = intval(($h+$l-7*$m+114)/31);    // [3 = March, 4 = April]
                                          $EasterDay = $p+1;    // (day in Easter Month)
                                      
                                          return format_date($y, $EasterMonth, $EasterDay);
                                      }
                                      
                                      
                                      function nextWorkingDay($number_days, $start_date = "") {
                                          $day_counter = 0;
                                          $intCounter = 0;    
                                      
                                          if ($start_date=="") {
                                              $today  = mktime(0, 0, 0, date("m")  , date("d"), date("Y"));
                                          } else {
                                              $start_time = strtotime($start_date);
                                              $today  = mktime(0, 0, 0, date("m", $start_time)  , date("d", $start_time), date("Y", $start_time));
                                          }
                                      
                                          while($day_counter < $number_days) {
                                              $working_time = DateAdd("d", 1, $today);
                                              $working_date = date("Y-m-d", $working_date);
                                              if (!isWeekend($working_date) && !confirm_holiday(date("Y-m-d", strtotime($working_date))) ) {
                                                  $day_counter++;
                                              }
                                              $intCounter++;
                                              $today  = $working_time;
                                              if ($intCounter > 1000) {
                                                  //just in case out of control?
                                                  break;
                                              }
                                          }
                                      
                                          return $working_date;
                                      }
                                      function isWeekend($check_date) {
                                          return (date("N",  strtotime($check_date)) > 5);
                                      }
                                      function confirm_holiday($somedate="") {
                                          if ($somedate=="") {
                                              $somedate = date("Y-m-d");
                                          }
                                          $year = date("Y", strtotime($somedate));
                                          $blnHoliday = false;
                                          //newyears
                                          if ($somedate == observed_day($year, 1, 1)) {
                                              $blnHoliday = true;
                                          }
                                          if ($somedate == format_date($year, 1, 1)) {
                                              $blnHoliday = true;
                                          }
                                          if ($somedate == format_date($year, 12, 31)) {
                                              $blnHoliday = true;
                                          }
                                          //Martin Luther King
                                          if ($somedate == get_holiday($year, 1, 1, 3)) {
                                              $blnHoliday = true;
                                          }
                                          //President's
                                          if ($somedate == get_holiday($year, 2, 1, 3)) {
                                              $blnHoliday = true;
                                          }
                                          //easter
                                          if ($somedate == calculate_easter($year)) {
                                              $blnHoliday = true;
                                          }
                                          //Memorial
                                          if ($somedate == get_holiday($year, 5, 1)) {
                                              $blnHoliday = true;
                                          }
                                          //july4
                                          if ($somedate == observed_day($year, 7, 4)) {
                                              $blnHoliday = true;
                                          }
                                          //labor
                                          if ($somedate == get_holiday($year, 9, 1, 1)) {
                                              $blnHoliday = true;
                                          }
                                          //columbus
                                          if ($somedate == get_holiday($year, 10, 1, 2)) {
                                              $blnHoliday = true;
                                          }
                                          //thanks
                                          if ($somedate == get_holiday($year, 11, 4, 4)) {
                                              $blnHoliday = true;
                                          }
                                          //xmas
                                          if ($somedate == format_date($year, 12, 24)) {
                                              $blnHoliday = true;
                                          }
                                          if ($somedate == format_date($year, 12, 25)) {
                                              $blnHoliday = true;
                                          }
                                          return $blnHoliday;
                                      }
                                      

                                      【讨论】:

                                        【解决方案24】:

                                        函数 get_business_days_forward_from_date($num_days, $start_date='', $rtn_fmt='Y-m-d') {

                                        // $start_date will default to today    
                                        
                                        if ($start_date=='') { $start_date = date("Y-m-d"); }
                                        
                                        $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('Y-m-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('Y-m-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");
                                        

                                        }

                                        【讨论】:

                                          【解决方案25】:

                                          add_business_days 有一个小错误。使用现有函数尝试以下操作,输出将是星期六。

                                          开始日期 = 星期五 要添加的工作日 = 1 Holidays 数组 = 添加下周一的日期。

                                          我已经在下面的函数中解决了这个问题。

                                          function add_business_days($startdate, $buisnessdays, $holidays = array(), $dateformat = 'Y-m-d'){
                                          $i= 1;
                                          $dayx= strtotime($startdate);
                                          $buisnessdays= ceil($buisnessdays);
                                          
                                          while($i < $buisnessdays)
                                          {
                                              $day= date('N',$dayx);
                                          
                                              $date= date('Y-m-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('Y-m-d',$dayx);
                                          
                                          while($day >= 6 || in_array($date,$holidays))
                                          {
                                              $dayx= strtotime($date.' +1 day');
                                              $day= date('N',$dayx);
                                              $date= date('Y-m-d',$dayx);
                                          }
                                          
                                          return date($dateformat, $dayx);}
                                          

                                          【讨论】:

                                          • 我假设这是基于 Bobbin 的代码我相信我也解决了这个问题
                                          【解决方案26】:

                                          我只是让我的函数基于 Bobbin 和 mcgrailm 代码工作,添加了一些对我来说完美的东西。

                                          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('Y-m-d',$enddate).' +1 day');
                                                  $day = date('N',$enddate);
                                                  if($day < 6 && !in_array(date('Y-m-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.
                                          

                                          【讨论】:

                                          • 我的和你的唯一区别是我的是一基的,你的是零基的。你在这里真的什么都没做。我很高兴这段代码对您有所帮助。但是,我不符合“基于”代码的条件,这更像是您试图将我的代码声明为您自己的代码
                                          【解决方案27】:

                                          对上面 James Pasta 提供的功能的增强,包括所有联邦假期,并更正了 7 月 4 日(上面计算为 6 月 4 日!),还包括假期名称作为数组键...

                                          /**
                                          * 美国国定假日
                                          * @param 字符串 $year
                                          * @return 数组
                                          */
                                          公共静态函数 getNationalAmericanHolidays($year) {

                                          //  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("Y-m-d",strtotime("third Monday of January " . $year) ),
                                              ['Washingtons Birthday'] => "". date("Y-m-d",strtotime("third Monday of February " . $year) ),
                                              ['Memorial Day'] => "". date("Y-m-d",strtotime("last Monday of May " . $year) ),
                                              ['Independance Day'] => $year . "-07-04",
                                              ['Labor Day'] => "". date("Y-m-d",strtotime("first Monday of September " . $year) ),
                                              ['Columbus Day'] => "". date("Y-m-d",strtotime("second Monday of October " . $year) ),
                                              ['Veterans Day'] => $year . "-11-11",
                                              ['Thanksgiving Day'] => "". date("Y-m-d",strtotime("fourth Thursday of November " . $year) ),
                                              ['Christmas Day'] => $year . "-12-25"
                                          );
                                          
                                          return $bankHolidays;
                                          

                                          }

                                          【讨论】:

                                            【解决方案28】:

                                            刚刚编写完一个可用于处理工作日的 API(这些解决方案都不太适合我的情况 :-);在这里链接到它,以防其他人发现它有用。

                                            ~内特

                                            PHP Class to Calculate Business Days

                                            【讨论】:

                                              【解决方案29】:

                                              感谢 Bobbin、mcgrailm、Tony、James Pasta 和其他几位在这里发帖的人。我已经编写了自己的函数来将工作日添加到日期,但使用我在此处找到的一些代码对其进行了修改。这将处理周末/节假日的开始日期。这也将处理营业时间。我添加了一些 cmets 并分解了代码以使其更易于阅读。

                                              <?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('Y-m-d', $date), $holidays)){
                                                          $date = strtotime(date('Y-m-d',$date).' +1 day');
                                                      }
                                              
                                                      //Now that we know we have a business day, add 1 day to it
                                                      $date = strtotime(date('Y-m-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('Y-m-d', $date), $holidays)){
                                                          $date = strtotime(date('Y-m-d',$date).' +1 day');
                                                      }
                                                  }
                                                  return date('Y-m-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("Y-m-d",strtotime("third Monday of January " . $year) ),
                                                  'Washingtons Birthday' => "". date("Y-m-d",strtotime("third Monday of February " . $year) ),
                                                  'Memorial Day' => "". date("Y-m-d",strtotime("last Monday of May " . $year) ),
                                                  'Independance Day' => $year . "-07-04",
                                                  'Labor Day' => "". date("Y-m-d",strtotime("first Monday of September " . $year) ),
                                                  'Columbus Day' => "". date("Y-m-d",strtotime("second Monday of October " . $year) ),
                                                  'Veterans Day' => $year . "-11-11",
                                                  'Thanksgiving Day' => "". date("Y-m-d",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("Y-m-d", strtotime("+ 1 day")); //Tomorrow
                                              } else {
                                                  $start_date = date("Y-m-d"); //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);
                                              
                                              ?>
                                              

                                              【讨论】:

                                                【解决方案30】:

                                                个人认为这是一个更简洁更简洁的解决方案:

                                                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("Y-m-d"), $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;
                                                }
                                                

                                                只需将建议的new 日期发送到此函数即可。

                                                【讨论】:

                                                  猜你喜欢
                                                  • 2022-01-17
                                                  • 1970-01-01
                                                  • 1970-01-01
                                                  • 2017-03-08
                                                  • 2023-03-08
                                                  • 1970-01-01
                                                  • 2012-06-12
                                                  • 2017-08-19
                                                  相关资源
                                                  最近更新 更多