Php add 5 working days to current date excluding weekends (sat-sun) and excluding (multiple) holidays

前端 未结 3 1574
青春惊慌失措
青春惊慌失措 2021-02-11 11:23

For delivery of our webshop, we need to calculate 5 working days from the current date in php.

Our working days are from monday to friday and we have several closing day

相关标签:
3条回答
  • 2021-02-11 12:10

    You can use the "while statement", looping until get enough 5 days. Each time looping get & check one next day is in the holiday list or not.

    Here is the the example:

    $holidayDates = array(
        '2016-03-26',
        '2016-03-27',
        '2016-03-28',
        '2016-03-29',
        '2016-04-05',
    );
    
    $count5WD = 0;
    $temp = strtotime("2016-03-25 00:00:00"); //example as today is 2016-03-25
    while($count5WD<5){
        $next1WD = strtotime('+1 weekday', $temp);
        $next1WDDate = date('Y-m-d', $next1WD);
        if(!in_array($next1WDDate, $holidayDates)){
            $count5WD++;
        }
        $temp = $next1WD;
    }
    
    $next5WD = date("Y-m-d", $temp);
    
    echo $next5WD; //if today is 2016-03-25 then it will return 2016-04-06 as many days between are holidays
    
    0 讨论(0)
  • 2021-02-11 12:14

    Based on Luke's answer:

    Difference is that this one generates holidays for every year

    <?php
    class DateHelper
    {
        //change at will
        const HOLIDAY_DATES = [
            ['day' => 25, 'month' => 12],//christimas
            ['day' => 1, 'month' => 1],//new year
            ['day' => 13, 'month' => 4]//easter
        ];
        /**
         * @param int $numBusinessDays
         * @param \DateTimeInterface $date
         * @return \DateTime
         */
        public static function getFutureBusinessDay(int $numBusinessDays, \DateTimeInterface $date)
        {
            $numBusinessDays = min($numBusinessDays, 1000);
            $businessDayCount = 0;
            $currentTimestamp = strtotime($date->format('Y-m-d'));
            $holidayDates = self::getHolidayDates();
            while ($businessDayCount < $numBusinessDays) {
                $next1WD = strtotime('+1 weekday', $currentTimestamp);
                $next1WDDate = date('Y-m-d', $next1WD);
                if (!in_array($next1WDDate, $holidayDates)) {
                    $businessDayCount++;
                }
                $currentTimestamp = $next1WD;
            }
            return (new \DateTime())->setTimestamp($currentTimestamp);
        }
    
        /**
         * @return array
         */
        private static function getHolidayDates()
        {
            $holidays = [];
            foreach (self::HOLIDAY_DATES as $holidayDate) {
                $date = new \DateTime();
                $date->setDate($date->format('Y'), $holidayDate['month'], $holidayDate['day']);
                $holidays[] = $date->format('Y-m-d');
            }
            return $holidays;
        }
    }
    
    0 讨论(0)
  • 2021-02-11 12:27

    A function based on Tinh Dang's answer:

    function getFutureBusinessDay($num_business_days, $today_ymd = null, $holiday_dates_ymd = []) {
        $num_business_days = min($num_business_days, 1000);
        $business_day_count = 0;
        $current_timestamp = empty($today_ymd) ? time() : strtotime($today_ymd);
        while ($business_day_count < $num_business_days) {
            $next1WD = strtotime('+1 weekday', $current_timestamp);
            $next1WDDate = date('Y-m-d', $next1WD);        
            if (!in_array($next1WDDate, $holiday_dates_ymd)) {
                $business_day_count++;
            }
            $current_timestamp = $next1WD;
        }
        return date('Y-m-d', $current_timestamp);
    }
    

    I made it limit the loop to 1000 business days. There could be no limit if desired.

    0 讨论(0)
提交回复
热议问题