2个日期之间的时差忽略周末时间

时间:2010-01-19 07:34:59

标签: php mysql datetime

鉴于2个日期,我如何计算它们之间的小时/分钟数,不包括周末时间(从星期五17:30到星期一09:00)

该脚本查询MySql数据库但我认为这种计算在php中会更容易。 我正在考虑一个迭代函数来确定工作日并保持循环,直到最后一个日期小于当前日期指标?

有什么建议吗?

2 个答案:

答案 0 :(得分:1)

假设您有两个时间戳:$timestamp1$timestamp2,您可以减去它们并减去周末数:$difference - ($weekends*2*24*3600)

function difWeekends($timestamp1, $timestamp2){
    $difference = $timestamp2 - $timestamp1;
    $nextWeekend = strtotime('next Saturday', $timestamp1);
    $weekends = 0;
    $weekendFound = true;
    while($weekendFound){
        if($nextWeekend < $timestamp2){
            $weekendFound = false;
        } else {
            $nextWeekend = strtotime('+7 days', $nextWeekend);
            $weekends++;
        }
    }
    $difference -= $weekends*48*60*60;

    $hours = $difference % 3600; // Not sure about this, I assume you already got this...
    $difference -= $hours*3600;
    $minutes = $difference % 60;
    return array('hours'=>$hours, 'minutes'=>$minutes);        
}

需要修改:

function difWeekends($timestamp1, $timestamp2){
    $difference = $timestamp2 - $timestamp1;

    // Calculate the start of the first next weekend
    $nextWeekendStart = strtotime('next Friday 17:30', $timestamp1);

    // Calculate the end of the first next weekend
    $nextWeekendEnd = strtotime('next Monday 9:00', $nextWeekendStart);

    // This wil hold the number of weekend-seconds that needs to be subtracted
    $weekendSubtract = 0;

    $weekendFound = true;
    while($weekendFound){
        // If $timestamp2 ends before the next weekend, no weekend is found. [] = weekends, --- is time range
        // ---  [    ]
        if($timestamp2 < $nextWeekendStart){
            $weekendFound = false;
        } else {
            // ----[--  ]
            if($timestamp2 < $nextWeekendEnd){
                $weekendSubtract += $timestamp2-$nextWeekendStart;
                $weekendFound = false; // Last weekend was found
            } else {
                // ---[----]---
                $weekendSubtract += $nextWeekendEnd - $nextWeekendStart;
                $nextWeekendStart += 7*24*60*60;
                $nextWeekendEnd += 7*24*60*60;
            }
        }
    }
    $difference -= $weekendSubtract;

    $hours = $difference % 3600; // Not sure about this, I assume you already got this...
    $difference -= $hours*3600;
    $minutes = $difference % 60;
    return array('hours'=>$hours, 'minutes'=>$minutes);        
}

答案 1 :(得分:0)

感谢哈曼,你的代码指出了我正确的方向。非常感谢!!

当timestamp1是星期五时,你的解决方案没有考虑到,=&gt;而不是“下周五”应该是“这个星期五”

我进行了扩展,以便时间戳可以涵盖多个周末,而不仅仅是一个周末。

function timeDiffWeekendsOff($timestamp1, $timestamp2){

    // Double check $timestamp2 is after and not before $timestamp1
    if ($timestamp2 < $timestamp1) return 0;

    // All-time difference
     $difference = $timestamp2 - $timestamp1;

    // This will hold the number of weekend-seconds that needs to be subtracted
    $weekendSubtract = 0;

    $keepLoop = true;
    $currentDayStart = $timestamp1;

    while ($keepLoop) {

        if (isSameDay($currentDayStart,$timestamp2)){ 
            $keepLoop = false; // exit at the last day
            $currentDayEnd = $timestamp2;
        } else {
            $currentDayEnd = strtotime('tomorrow 00:00', $currentDayStart);
        }

        switch (date('w',$currentDayStart)){ // 0 - Sunday, 1 - Monday, 5 - Friday, 6 - Saturday
            case 5: // Friday
                $weekendSubtract += timeIntersect($currentDayStart, $currentDayEnd, strtotime('this Friday 17:30', $currentDayStart), strtotime('this Saturday 00:00', $currentDayStart));
                break;

            case 6: // full weekend days, 0 - Sunday, 6 - Saturday
            case 0:     
                $weekendSubtract += $currentDayEnd - $currentDayStart;
                break;

            case 1: // Monday
                $weekendSubtract += timeIntersect($currentDayStart, $currentDayEnd, strtotime('this Monday 00:00', $currentDayStart), strtotime('this Monday 09:00', $currentDayStart));    

            default:
                break;  
        } // end switch

        // -- lastly, set the new day start
        $currentDayStart = strtotime('tomorrow 00:00', $currentDayStart);

    } // end while $keepLoop

    $difference -= $weekendSubtract;

    return $difference;     
}

function isSameDay($compare1, $compare2){
    if (date('Ymd',$compare1)==date('Ymd',$compare2))
        return true;
    else 
        return false;
}

function timeIntersect($time1_from, $time1_to, $time2_from, $time2_to){
    $overlap = min($time1_to, $time2_to) - max($time1_from, $time2_from);
    if ($overlap < 0) $overlap = 0;
    return $overlap;
}