自定义工作日的两个日期之间的总工作日

I want to calculate total working days between two dates by using custom off day. I inserted Monday,Saturday and Sunday is off days into table. But,when I calculate from start date 2015-07-26 and end date 2015-08-26,the result is correct. However,if start date 2015-08-01 and end date 2015-08-31,the result is incorrect.

How can I do that?

Here is my code

<?php 
include 'connect.php';
error_reporting(E_ALL ^ E_NOTICE);
if (isset($_POST['startdate']) && isset($_POST['enddate']))
{
        $startdate=$_POST['startdate'];
        $enddate=$_POST['enddate'];
        $no = 0;

    $daysdiff = floor(((strtotime($enddate) -strtotime($startdate)) / 86400)+1); 
        echo "total day is".$daysdiff;

    $startdate = new DateTime($startdate);
    $enddate= new DateTime($enddate);
    $interval = DateInterval::createFromDateString('1 day');
    $period = new DatePeriod($startdate, $interval, $enddate);

    $res=mysql_query("SELECT * From working_day") or die(mysql_error());
    while ($row = mysql_fetch_assoc($res))
    {
        $id=$row['id'];
        $name_value=$row['off_days'];


        foreach ($period as $dt)
        {
            if (($dt->format('N')== $id ))
            {
            $no++;
            //$result=$daysdiff-$no;
            }
        }
        $result=$daysdiff-$no;                      

    }
    echo "<input class='form-control' type='text' name='working_day' value='$result'  />";

}
?>

I use a function that I believe I got from this site a long time ago to calculate time off for employees in my web app. Here's the full function, where I also take into account custom holidays from a table called "holiday_dates":

function countWorkingDays($startDate,$endDate)
{
    $pdoCore = Core::getInstance();

    // Build the holiday array
    $holidays_q = $pdoCore->dbh->prepare("SELECT holidayDate FROM holiday_dates");
    $holidays_q->execute();

    while($holidays_a = $holidays_q->fetch(PDO::FETCH_ASSOC))
    {
        $holidays[] = $holidays_a['holidayDate'];
    }

    // 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 and 6 <= $the_last_day_of_week)
        {
            $no_remaining_days--;
        }
        if($the_first_day_of_week <= 7 and 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 and $time_stamp <= $endDate and date("N",$time_stamp) != 6 and date("N",$time_stamp) != 7)
        {
            $workingDays--;
        }
    }

    return $workingDays;
}

For your use case, I'd say pay attention to this line:

if($startDate <= $time_stamp and $time_stamp <= $endDate and date("N",$time_stamp) != 6 and date("N",$time_stamp) != 7)

And add this for Monday:

 and date("N",$time_stamp) != 1