Working days (Mon-Fri) in PHP
Asked Answered
R

7

49

Is there a way to use strtotime to add working days (Monday to Friday) to a date? Or some other method? What I want to do is:

date ( 'Y-m-j' , strtotime ( '+3 working days' ) )
Rickrickard answered 23/11, 2010 at 21:33 Comment(6)
In some middle eastern countries a weekend a working week is Sunday to Thursday. Have you thought about them :OViscardi
This is for working out how many days in the future the deadline for payment is for a local event, so no :-)Rickrickard
You have to think about holydays too.Aniakudo
@Rickrickard are holidays an issue?Wilkens
True, working days are subjective.Stercoricolous
@Wilkens no, the booking system will only be open for a limited time.Rickrickard
S
114

If you are limiting to weekdays use the string weekdays.

echo date ( 'Y-m-j' , strtotime ( '3 weekdays' ) );

This should jump you ahead by 3 weekdays, so if it is Thursday it will add the additional weekend time.

Source: http://www.php.net/manual/en/datetime.formats.relative.php

Stercoricolous answered 23/11, 2010 at 21:38 Comment(12)
No way. This works? Is there anything strtotime() can't do?Wilkens
@Wilkens I've occasionally gotten screwed by its inability to things like "the first day of the month 10 months ago" and "the first day of this month".Ingvar
It works buggy though: echo date('Y-m-d', strtotime('2011-03-27 + 5 weekdays')); Expected April 1st, got April 3rd.Phenylketonuria
@Phenylketonuria - Did you factor in server time and not just date?Stercoricolous
compare "+ 4 weekdays" and "+5". The difference is wrong. And if you add "H:i:s" you'll see that this issue has nothing to do with time.Phenylketonuria
@zerkms: "Expected April 1st" - that was a Sunday in 2011. This is, by our definition, not a weekday! Thus, April 3rd (Tuesday) is correct.Maressa
@fab April 1st, 2011 was a Friday.Diondione
@Phenylketonuria Hell went ahead and tested it as well and this for sure is off still 3 years down the road... wonder why..Carousal
For anyone using an old PHP, this was implemented around PHP 5.3.X with bugs in 5.3.6 and 5.3.8, so if isn't working for you, please check your PHP version first. Was really hard to me to troubleshoot weekdays because even with E_ALL, no error is shown indicating that weekday wasn't an allowed keyword.Trujillo
If it is not working properly upgrade to php version minimum running version PHP Version 5.5.38 Using Example: date('Y-m-d',strtotime(date('Y-m-d').'+2 WEEKDAY'))Sherlene
Works for me. Today is Sunday, this code gets to me friday's date date ( 'Y-m-d' , strtotime ( '-1 weekdays' ) )Severalty
you are a genius! :)Faerie
L
4

You can do this too:

echo date_create()->modify("+3 weekdays")->format("Y-m-d");

See:

https://www.php.net/manual/en/function.date-create.php

https://www.php.net/manual/en/datetime.modify.php

Labana answered 22/10, 2019 at 14:50 Comment(0)
S
2

I have found this buggy when needing a larger amount of weekdays. I was looking for X amount of business days after the 1st of the current month.

Looked great at first until after adding > 5 business days (similar to what @zerkms found).

This has proved more accurate for me.

    function _getBusinessDayOfMonth( $days ) { 
        $time = strtotime(date("m/1/Y 00:00")); //finding # of business days after 1st of the month
        $i = 0; //start with zero
        while ($i < $days) { //loop through until reached the amount of weekdays
            $time = strtotime("+1 day", $time); //Increase day by 1
            if (date("N", $time) < 6) { //test if M-F
                $i++; //Increase by 1
            }
        }
        echo date("m/d/Y", $time);
    }
Struve answered 28/6, 2013 at 19:5 Comment(0)
P
2

For PHP >= 5.6

public function addWorkingDays($date, $day)
{

    if (!($date instanceof \DateTime) || is_string($date)) {
        $date = new \DateTime($date);
    }

    if ($date instanceof \DateTime) {
        $newDate = clone $date;
    }

    if ($day == 0) {
        return $newDate;
    }

    $i = 1;

    while ($i <= abs($day)) {

        $newDate->modify(($day > 0 ? ' +' : ' -') . '1 day');

        $next_day_number = $newDate->format('N');

        if (!in_array($next_day_number, [6, 7])) {
            $i++;
        }

    }

    return $newDate;

}
Paleography answered 19/4, 2018 at 20:30 Comment(0)
K
0

I think a function can be easily developed that you can just export current day no of the week and you can add two and mod of 5 will give you easily weekday.

function increaseWorkDay($workDayToProcess, $dayToAdd){
    if($workDayToProcess >= 4 && $workDayToProcess <= 6){
        $workDayToProcess= 4;
    }
    $workDayToProcess+= $dayToAdd;

    return $workDayToProcess % 5;
}

And you can export the weekday name by using an array, this method can alternatively be used.

Kolomna answered 21/9, 2016 at 19:13 Comment(0)
N
0

I do it recursively, worked for me

function add_work_days($date, $day){
    if($day == 0)
        return $date;

    $date->add(new DateInterval('P1D'));

    if(!in_array($date->format('N'), array('6', '7')))
        $day--;

    return add_work_days($date, $day);
}

$date  = add_work_days(new DateTime(), 3);
echo $date->format('d/m/Y');
Nianiabi answered 11/8, 2017 at 20:27 Comment(0)
D
0

For older versions of PHP < 5.3

function AddWorkingDays($startDate, $adddays)
{
  $retdate = $startDate;
  $sign = "+";
  if($adddays < 0){
    $adddays = $adddays*-1;
    $sign = "-";
  }
  while ($adddays > 0) {
    $retdate = date ( 'Y-m-d' , strtotime ( "$retdate {$sign}1 day" ) );

      $what_day = date("N", strtotime($retdate));
      if ( $what_day != 6 && $what_day != 7 ) // 6 and 7 are weekend
          $adddays--;

  };

  return $retdate;

}
Deca answered 25/10, 2017 at 18:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.