【问题标题】:Time difference between 2 dates ignoring weekend time忽略周末时间的两个日期之间的时差
【发布时间】:2010-01-19 07:34:58
【问题描述】:

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

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

有什么建议吗?

【问题讨论】:

    标签: php mysql datetime


    【解决方案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);        
    }
    

    【讨论】:

    • 周末从周五 17:30 开始,到周一 09:00 结束,所以你的等式有点偏离。
    • 哎呀,我的周末从星期六开始;)
    【解决方案2】:

    感谢 Harmen,您的代码为我指明了正确的方向。非常感谢!

    当timestamp1在星期五时,您的解决方案没有考虑,=>而不是“下星期五”应该是“本星期五”

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-10
      • 2012-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-17
      • 1970-01-01
      相关资源
      最近更新 更多