Calculate business days

后端 未结 30 1820
猫巷女王i
猫巷女王i 2020-11-22 05:16

I need a method for adding \"business days\" in PHP. For example, Friday 12/5 + 3 business days = Wednesday 12/10.

At a minimum I need the code to understand weekend

相关标签:
30条回答
  • 2020-11-22 06:07

    Personally, I think this is a cleaner and more concise solution:

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

    Just send the proposed new date to this function.

    0 讨论(0)
  • 2020-11-22 06:08

    A function to add or subtract business days from a given date, this doesn't account for holidays.

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

    use like so...

    echo date("m/d/Y", dateFromBusinessDays(-7));
    echo date("m/d/Y", dateFromBusinessDays(3, time() + 3*60*60*24));
    
    0 讨论(0)
  • 2020-11-22 06:08
    <?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>";
    ?>
    
    0 讨论(0)
  • 2020-11-22 06:08

    An enhancement to the function offered by James Pasta above, to include all Federal Holidays, and to correct 4th July (was calculated as 4th June above!), and to also include the holiday name as the array key...

    /**
    * National American Holidays
    * @param string $year
    * @return array
    */
    public static function 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;
    

    }

    0 讨论(0)
  • 2020-11-22 06:10
    $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);
    
    0 讨论(0)
  • 2020-11-22 06:11

    Thanks to Bobbin, mcgrailm, Tony, James Pasta and a few others who posted here. I had written my own function to add business days to a date, but modified it with some code I found here. This will handle the start date being on a weekend/holiday. This will also handle business hours. I added some comments and break up the code to make it easier to read.

    <?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);
    
    ?>
    
    0 讨论(0)
提交回复
热议问题