Рассчитайте разницу между двумя датами и временем, исключая выходные - PullRequest
0 голосов
/ 05 ноября 2018

Например 02-11-2018 15:00 - 05-11-2018 11:00 должно быть 2 часа. Потому что 3 и 4 выходные.

$date1 = "2018-03-01 11:12:45"; 
$date2 = "2018-03-04 15:37:04";  
$date1Timestamp = strtotime($date1); 
$date2Timestamp = strtotime($date2); 
$difference = $date2Timestamp - $date1Timestamp; 
echo $difference; 

1 Ответ

0 голосов
/ 05 ноября 2018

Вы можете использовать mktime() для создания меток времени UNIX для двух дат / времени, которые вы хотите сравнить. Эти временные метки будут представлять количество секунд между эпохой Unix (1 января 1970 г. 00:00:00 по Гринвичу) и указанным временем. Поскольку они оба будут в секундах, очень легко рассчитать секунды между двумя временными метками:

<?php

//set start time and end time - mktime(hour, minute, second, month, day, year)
$startTime = mktime(15, 0, 0, 11, 2, 2018); // 2-11-2018 3:00PM
$endTime = mktime(11, 0, 0, 11, 5, 2018); // 5-11-2018 11:00AM

//calculate total number of seconds between two date/times
$totalSeconds = $endTime - $startTime;

//apply whatever other math you need...

?>

Что касается учета выходных и рабочих часов, вам нужно проявить творческий подход, определив, сколько дней выходных существует между двумя датами / временем и сколько часов приходится на рабочие часы в рабочие дни. Руководство PHP для функций date пригодится. Следующий код дает результаты, которые вы ищете:

<?php
//set business start and end hours
$businessStartHour = 10; //10 AM
$businessEndHour = 16; //4 PM

//set weekend days
$arrWeekendDays = array(6,0); //numeric representations of Saturday (6) and Sunday (0)

//set start and end dates and times
//2-11-2018 3 PM
$startHour = 15;
$startMinute = 0;
$startSecond = 0;
$startMonth = 11;
$startDay = 2;
$startYear = 2018;

//5-11-2018 11 AM
$endHour = 11;
$endMinute = 0;
$endSecond = 0;
$endMonth = 11;
$endDay = 5;
$endYear = 2018;

//create UNIX timestamps
$startTime = mktime($startHour, $startMinute, $startSecond, $startMonth, $startDay, $startYear);
$endTime = mktime($endHour, $endMinute, $endSecond, $endMonth, $endDay, $endYear);

//ensure $endTime is greater than $startTime
if($startTime >= $endTime){
    //invalid start and end datetimes
    die("Invalid start and end datetimes.");
}

//calculate eligible seconds from partial time on first and last day
$totalSeconds = 0;

$currentTime = mktime(0, 0, 0, $startMonth, $startDay, $startYear); //beginning of $startTime day
$lastFullDay = mktime(0, 0, 0, $endMonth, $endDay, $endYear); //beginning of $endTime day

$startingBusinessTime = mktime($businessStartHour, 0, 0, $startMonth, $startDay, $startYear);
$endingBusinessTime = mktime($businessEndHour, 0, 0, $endMonth, $endDay, $endYear);

if($startTime < $startingBusinessTime){
    $startTime = $startingBusinessTime;
}
if($endTime > $endingBusinessTime){
    $endTime = $endingBusinessTime;
}

if($currentTime == $lastFullDay){
    //$startTime and $endTime occur on the same day
    if($endTime > $startTime){
        $totalSeconds += ($endTime - $startTime);
    }
}else{
    //$startTime and $endTime do not occur on the same day
    $startingBusinessTime = mktime($businessStartHour, 0, 0, $endMonth, $endDay, $endYear);
    $endingBusinessTime = mktime($businessEndHour, 0, 0, $startMonth, $startDay, $startYear);
    if($endingBusinessTime > $startTime){
        $totalSeconds += ($endingBusinessTime - $startTime);
    }
    if($endTime > $startingBusinessTime){
        $totalSeconds += ($endTime - $startingBusinessTime);
    }
}

//calculate eligible seconds from all full days in between start day and end day
$fullDayBusinessSeconds = (($businessEndHour - $businessStartHour) * 3600);

//set $currentTime to beginning of first full day
$nextDay = $currentTime + (26 * 3600); //add 26 hours to $currentTime to get into the next day, compensating for possible daylight savings
$currentTime = mktime(0, 0, 0, date('n', $nextDay), date('j', $nextDay), date('Y', $nextDay));

while($currentTime < $lastFullDay){
    //determine if $currentTime is a weekday
    if(!in_array(date('w', $currentTime), $arrWeekendDays)){
        //it's a business day, add all business seconds to $totalSeconds
        $totalSeconds += $fullDayBusinessSeconds;
    }
    //increment $currentTime to beginning of next day
    $nextDay = $currentTime + (26 * 3600); //add 26 hours to $currentTime to get into the next day, compensating for possible daylight savings
    $currentTime = mktime(0, 0, 0, date('n', $nextDay), date('j', $nextDay), date('Y', $nextDay));
}

echo "Total eligible time between start time and end time: " . $totalSeconds . " seconds (" . convertSecToTime($totalSeconds) . ")";

function convertSecToTime($sec) 
 {
  $date1 = new DateTime("@0");
  $date2 = new DateTime("@$sec");
  $interval =  date_diff($date1, $date2);
  return $interval->format('%y Years, %m months, %d days, %h hours, %i minutes and %s seconds');
  // convert into Days, Hours, Minutes
  // return $interval->format('%a days, %h hours, %i minutes and %s seconds'); 
  }
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...