Bryan Bryan - 6 months ago 16
PHP Question

How can I calculate the number of working days between two dates

We have a PHP based timesheet system that's been developed in house, and has evolved over the years, however one piece of information presented to the users is the number of working days remaining on each project.

Currently, I simply take the difference between the current date and project end date, and divide by 7 and multiply by 5. This has sufficed for a long time and is mostly accurate enough for staff that work full time Monday to Friday. However, we now have a number of staff who work only the odd day a week.

The timesheet system is aware of what days which staff work, this information is stored in a string in the user class, for a full time worker, the value would be

NNYYYYY
(meaning
ssMTWTF
).

I could very easily make the result more accurate, by dividing the difference between the two dates by seven, and then multiplying by the number of days they work, but whilst making this change, I'm considering producing a much more accurate means of calculating the real value.

The easiest way that springs to mind would be to just use a loop between the two dates, comparing the day of the week to the user's working pattern, adding one to a counter on days where the user works that day.

Given that this calculation has to be performed on average about 30 times per page view due to the number of projects on the timesheet and projects can span 12 or 18 months at a time (that's a lot of looping for every page load), I'm wondering if there's a more efficient method of doing this in PHP?

Answer

May be this code snippet will help:

<?php
//get current month for example
$beginday = date("Y-m-01");
$lastday  = date("Y-m-t");

$nr_work_days = getWorkingDays($beginday, $lastday);
echo $nr_work_days;

function getWorkingDays($startDate, $endDate)
{
    $begin = strtotime($startDate);
    $end   = strtotime($endDate);
    if ($begin > $end) {
        echo "startdate is in the future! <br />";

        return 0;
    } else {
        $no_days  = 0;
        $weekends = 0;
        while ($begin <= $end) {
            $no_days++; // no of days in the given interval
            $what_day = date("N", $begin);
            if ($what_day > 5) { // 6 and 7 are weekend days
                $weekends++;
            };
            $begin += 86400; // +1 day
        };
        $working_days = $no_days - $weekends;

        return $working_days;
    }
}

Another solution can be: Get date range between two dates excluding weekends