如何计算两个日期之间的工作日数

时间:2014-05-03 13:19:29

标签: php algorithm date datetime

我们有一个基于PHP的时间表系统,该系统已在内部开发,并且多年来不断发展,但向用户提供的一条信息是每个项目剩余的工作日数。

目前,我只是采用当前日期和项目结束日期之间的差异,然后除以7并乘以5.这已经足够长时间,对于周一至周五全职工作的员工来说,大部分都是准确的。但是,我们现在有一些工作人员每周只工作一天。

时间表系统知道员工工作的日期,此信息存储在用户类的字符串中,对于全职工作人员,值为NNYYYYY(表示ssMTWTF

通过将两个日期之间的差异除以7,然后乘以他们工作的天数,我可以非常轻松地使结果更准确,但是在进行此更改时,我考虑生产更多更准确的计算实际价值的方法。

最让人想到的方法是在两个日期之间使用一个循环,将星期几与用户的工作模式进行比较,在用户工作的日子将一个添加到计数器一天。

由于时间表上的项目数量,项目每页浏览量平均需要执行大约30次,并且项目一次可能跨越12个月或18个月(每个项目的循环次数很多)页面加载),我想知道是否有更好的方法在PHP中执行此操作?

5 个答案:

答案 0 :(得分:9)

这段代码可能会有所帮助:

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

另一种解决方案可以是: Get date range between two dates excluding weekends

答案 1 :(得分:2)

您可以使用以下功能查找工作日数。

您可以在此处查看LIVE DEMO

function number_of_working_days($startDate, $endDate)
{
    $workingDays = 0;
    $startTimestamp = strtotime($startDate);
    $endTimestamp = strtotime($endDate);
    for ($i = $startTimestamp; $i <= $endTimestamp; $i = $i + (60 * 60 * 24)) {
        if (date("N", $i) <= 5) $workingDays = $workingDays + 1;
    }
    return $workingDays;
}

答案 2 :(得分:1)

如果您想查找两个日期与工作日选项之间的总工作日。那么这将有所帮助

        $startDate = '2016-10-01';
        $endDate =  '2016-10-31';
        $weekdays = array('1','2','3','4','5','6'); //this i think monday-saturday

        $begin = new DateTime($startDate);
        $end = new DateTime($endDate);

        $end = $end->modify( '+1 day' ); //add one day so as to include the end date of our range

        $interval = new DateInterval('P1D'); // 1 Day
        $dateRange = new DatePeriod($begin, $interval, $end);

        $total_days = 0;
        //this will calculate total days from monday to saturday in above date range
        foreach ($dateRange as $date) {

         if (in_array($date->format("N"),$weekdays)) {
                $total_days++; 
          }
        }

答案 3 :(得分:0)

我尝试了一些解决方案,它们对我不起作用(给我的结果包括周末),所以我把它写成一个解决方案:

function number_of_working_days($from, $to) {
    $target = strtotime($from);
    $days = 0;  
    while ($target < strtotime(date("Y-m-d",strtotime($to)))) {
        if(date("N",$target) <= 5) $days++;
        $target += (60*60*24);  /* move forward by 1 day */
    }
    return $days;
}

$from$to是mySQL表中的日期。

答案 4 :(得分:0)

function workingDaysBetweenDates(startDate, endDate) {

    // Validate input
    if (endDate < startDate)
        return 0;

    // Calculate days between dates
    var millisecondsPerDay = 86400 * 1000; // Day in milliseconds
    startDate.setHours(0,0,0,1);  // Start just after midnight
    endDate.setHours(23,59,59,999);  // End just before midnight
    var diff = endDate - startDate;  // Milliseconds between datetime objects    
    var days = Math.ceil(diff / millisecondsPerDay);

    // Subtract two weekend days for every week in between
    var weeks = Math.floor(days / 7);
    days = days - (weeks * 2);

    // Handle special cases
    var startDay = startDate.getDay();
    var endDay = endDate.getDay();

    // Remove weekend not previously removed.   
    if (startDay - endDay > 1)         
        days = days - 2;      

    // Remove start day if span starts on Sunday but ends before Saturday
    if (startDay == 0 && endDay != 6) {
        days = days - 1;  
    }

    // Remove end day if span ends on Saturday but starts after Sunday
    if (endDay == 6 && startDay != 0) {
        days = days - 1;
    }

    return days;
}

$('#results').html(workingDaysBetweenDates(new Date('6/03/2019'), new Date('6/17/2019')));

希望这会有所帮助。

相关问题