Разница во времени между 2 датами, игнорируя время выходных - PullRequest
0 голосов
/ 19 января 2010

Учитывая 2 даты, как я могу рассчитать количество часов / минут между ними, исключая время выходных (с пятницы 17:30 до понедельника 09:00)

Скрипт запрашивает базу данных MySql, но я предполагаю, что такого рода вычисления будут проще в php. Я имею в виду итеративную функцию для определения дня недели и продолжения цикла, пока последняя дата не станет меньше, чем индикатор текущего дня?

Есть предложения?

Ответы [ 2 ]

1 голос
/ 19 января 2010

Предполагая, что у вас есть две временные метки: $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);        
}
0 голосов
/ 19 января 2010

Спасибо, Хармен, твой код указал мне правильное направление. Очень ценится!

Ваше решение не принимает во внимание, когда 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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...