计算时间范围内的小时数

时间:2019-08-06 06:28:21

标签: php

我正在尝试创建一个计算不同时间范围内小时数的函数。

假设我的时间段为08:00-20:00,并且以下时间段为

08:00-10:00, 10:00-16:00, 16:00-20:00

我希望函数像这样返回一个数组,其中包含每个组中的小时数

08:00-10:00 => 2
10:00-16:00 => 6
16:00-20:00 => 4

如果我给函数另一个时间段,例如09:00-12:00,则应返回

08:00-10:00 => 1
10:00-16:00 => 2
16:00-20:00 => 0 

编辑

我有此代码,但计数不正确($ group ['count']始终为0)

    $start = new DateTime( '09:00' );
    $end = new DateTime( '12:00' ); 

    $daterange = new DatePeriod($start, new DateInterval('PT1H') ,$end);

    $hourgroups = [
        ['start' => '08:00', 'end' => '11:00', 'count' => 0],
        ['start' => '11:00', 'end' => '15:00', 'count' => 0],
    ];

    foreach($daterange as $hour){
        foreach($hourgroups as $group){
            if($hour > new DateTime($group['start']) && $hour < new DateTime($group['end'])){
                $group['count'] ++;
            }
        }
    }

3 个答案:

答案 0 :(得分:1)

/**
 * @param   string start time
 * @param   string end time
 * @param   string start of period
 * @param   string end time
 * @return  int
 */

function hours($s, $e, $sp, $ep){
    // get max of starts of time dnd period
    $t1=max(new dateTime($s), new dateTime($sp));
    // get min of ends of time and period
    $t2=min(new DateTime($e), new dateTime($ep));
    // if $t2 <=  $t1  - no overlap
    return ($t2 > $t1) ? $t2->diff($t1)->h : 0;
}


echo 'Hours: ' . hours('08:00','10:00', '09:00', '16:00');

更新

具有您的数据结构

foreach($hourgroups as &$group){
        $group['count'] = hours($group['start'], $group['end'], $start, $end);             
}

答案 1 :(得分:1)

我不太确定您的输入是什么,但是我假设它们是字符串,就像您的问题一样。如果是数组,则可以跳过爆炸。如果还有其他问题,请添加注释,然后我将相应地更改代码。

我制作了字符串数组,然后创建了可以相交和计数的时间范围。

$groups = "08:00-10:00, 10:00-16:00, 16:00-20:00";
$input = "09:00 - 12:00";
$inputarr = explode(" - ", $input);
$inputhours = range((int)$inputarr[0], (int)$inputarr[1]-1); // [9,10,11]

$arr = explode("-", str_replace(", ", "-", $groups)); //["08:00", "10:00", "10:00", "16:00", "16:00", "20:00"]

foreach(array_chunk($arr, 2) as $item){
    $times[implode("-", $item)] = count(array_intersect($inputhours, range(substr($item[0],0,2), substr($item[1],0,2)-1)));
    // the range() creates arrays such as [8,9] , [10,11,12,13,14,15] , [16,17,18,19] 
    // these are intersected with the inputhours array created earlier and the count is
    // returned to an associative array with the timeranges as key 
}

https://3v4l.org/eUBbt

array(3) {
  ["08:00-10:00"]=>
  int(1)
  ["10:00-16:00"]=>
  int(2)
  ["16:00-20:00"]=>
  int(0)
}

答案 2 :(得分:0)

使用以下时间戳创建一个数组:

    $start = Array("08:00","10:00","16:00"); // Start Intervals
    $end = Array("10:00","16:00","20:00"); // Stop Intervals

现在,您可以使用如下所示的for循环轻松运行它们:

                for ($i = 0; $i != sizeof($start); $i++) {
                    $time = new DateTime($start[$i]);
                    $timeStop = new DateTime($end[$i]);
                    $diff = $timeStop->diff($time); // Get the Difference between end and start
                    echo('
                        <tr>
                            <td>
                                '.$start[$i].'
                            </td>
                            <td>
                                '.$end[$i].'
                            </td>
                            <td>
                                '.$diff->format('%h:%i').'
                            </td>
                        </tr>
                    ');
                }

恢复:

Start|End  |Duration
08:00|10:00|2:0
10:00|16:00|6:0
16:00|20:00|4:0

---编辑---

以下是代码和结果以及您的数据结构;)

代码:

<?php
    $stard = '09:00';
    $end = '12:00';
    $stard = new DateTime($stard);
    $end = new DateTime($end);

    $daterange = new DatePeriod($stard, new DateInterval('PT1H') ,$end);

    $stard = $stard->format('H');
    $end = $end->format('H');

    $hourgroups = [
        ['start' => '08:00', 'end' => '11:00', 'duration' => 0],
        ['start' => '11:00', 'end' => '15:00', 'duration' => 0],
    ];
    echo("Duration:<br>");
    for($i = 0; $i != sizeof($hourgroups); $i++) {
        $time = new DateTime($hourgroups[$i]['start']);
        $timeStop = new DateTime($hourgroups[$i]['end']);
        $beging = $time->format('H');
        $ending = $timeStop->format('H');

            foreach($daterange as $hour){
                $checker = $hour->format('H');
                if($checker > $beging && $checker < $ending){
                    $hourgroups[$i]['duration'] = $hourgroups[$i]['duration'] + 1;
                }
            }

        echo(($hourgroups[$i]['duration'] + 1)."<br>");
    }
?>

此代码的重新存储为:

Duration:
3
1