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



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

目前,我只需取当前日期和项目结束日期之间的差值,除以7,乘以5。这在很长一段时间内已经足够了,对于周一至周五全职工作的员工来说也足够准确。然而,我们现在有一些员工每周只工作一天。

时间表系统知道员工的工作日,这些信息存储在用户类中的字符串中,对于全职员工,其值为NNYYYYY(意思是ssMTWTF(。

我可以很容易地将两个日期之间的差值除以7,然后乘以它们的工作天数,从而使结果更加准确,但在做出这一改变的同时,我正在考虑产生一种更准确的计算实际价值的方法。

脑海中浮现的最简单的方法是在两个日期之间使用一个循环,将一周中的哪一天与用户的工作模式进行比较,并在用户当天工作的日子的计数器中添加一个。

考虑到由于时间表上的项目数量,这种计算平均每个页面视图必须执行约30次,并且项目一次可以跨越12或18个月(每次页面加载都需要大量循环(,我想知道是否有更有效的PHP方法来实现这一点?

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

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

另一种解决方案可以是:获取两个日期之间的日期范围(不包括周末(

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

在这里你可以看到现场演示。

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

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

        $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++; 
          }
        }

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

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表中的日期。

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')));

希望这能有所帮助。

相关内容

  • 没有找到相关文章

最新更新