Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/245.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP计算总小时数无法获得准确答案_Php_Date_Datetime - Fatal编程技术网

PHP计算总小时数无法获得准确答案

PHP计算总小时数无法获得准确答案,php,date,datetime,Php,Date,Datetime,我试图根据一个人何时进入、何时中断、何时恢复和何时退出来计算他的总人数 我有这些数据: $data[0]['type'] = 'in'; $data[0]['created_at'] = '2019-02-01 08:01:52'; $data[1]['type'] = 'break'; $data[1]['created_at'] = '2019-02-01 12:00:40'; $data[2]['type'] = 'resume'; $data[2]['created_at'] = '

我试图根据一个人何时进入、何时中断、何时恢复和何时退出来计算他的总人数

我有这些数据:

$data[0]['type'] = 'in';
$data[0]['created_at'] = '2019-02-01 08:01:52';

$data[1]['type'] = 'break';
$data[1]['created_at'] = '2019-02-01 12:00:40';

$data[2]['type'] = 'resume';
$data[2]['created_at'] = '2019-02-01 13:00:39';

$data[3]['type'] = 'break';
$data[3]['created_at'] = '2019-02-01 14:29:21';

$data[4]['type'] = 'resume';
$data[4]['created_at'] = '2019-02-01 14:29:50';

$data[5]['type'] = 'break';
$data[5]['created_at'] = '2019-02-01 14:29:53';

$data[6]['type'] = 'resume';
$data[6]['created_at'] = '2019-02-01 14:30:00';

$data[7]['type'] = 'break';
$data[7]['created_at'] = '2019-02-01 14:30:09';

$data[8]['type'] = 'resume';
$data[8]['created_at'] = '2019-02-01 14:30:12';

$data[9]['type'] = 'out';
$data[9]['created_at'] = '2019-02-01 18:01:51';

$hours = 0;
$minutes = 0;
foreach($data as $key => $d){
    $d['created_at'] = str_replace(" ","T",$d['created_at']);
    if($d['type'] == 'in' || $d['type'] == 'resume'){
        $workingTime = new DateTime($d['created_at']);
    }

    if($d['type'] == 'break' || $d['type'] == 'out'){
        $date2 = new DateTime($d['created_at']);
        $diff = $date2->diff($workingTime);
        $tempHours = $diff->h;

        $tempHours = $tempHours + ($diff->days*24);
        $hours += $tempHours;

        $tempMin = $diff->i;
        $minutes  += $tempMin;
    }
}

if($minutes == 60){
    $hours += 1;
    echo $hours. " hours and 00 minutes";
}else if($minutes > 60){
    $hours = $hours + floor($minutes/60);
    $minutes = $minutes % 60;
    echo $hours. " hours and ".$minutes." minutes";
}else{
    echo $hours. " hours and ".$minutes." minutes";
}
我得到的总数是:
8小时57分,,而正确答案应该是
08小时59分21秒

我认为我没有得到正确答案的原因是因为在我的代码中,我没有在计算中包含秒数

有人能帮我在计算中加入秒数来得到正确答案吗

非常感谢您的帮助!多谢各位

顺便说一下,我之所以知道正确答案是
08小时59分21秒
,是因为这个网站:

我得到所有这些的差值之和:

$a = break - in
$b = break - resume
$c = out - resume
Then: $total_time = $a + $b + $c

如果不清楚,请告诉我。谢谢。

此代码将执行您想要的操作。它处理数组的每个元素,当我们在
中看到
时,设置工作开始和结束时间;每次在
恢复中看到
时设置一个时段开始;每次我们看到
out
break
时,将时段长度添加到一天的工作时间中。最后,我们计算一天的开始时间和我们通过添加所有时段而创建的时间之间的差值,这给了我们一整天的工作时间

foreach ($data as $event) {
    $this_time = new DateTime($event['created_at']);
    switch ($event['type']) {
        case 'in':
            $work_start_time = clone $this_time;
            $work_end_time = clone $this_time;
        case 'resume':
            $start_time = $this_time;
            break;
        case 'break':
        case 'out':
            $work_end_time->add($start_time->diff($this_time));
            break;
    }
}
$working_hours = $work_start_time->diff($work_end_time);
echo $working_hours->format('%H hours, %i minutes, %s seconds');
输出:

08 hours, 59 minutes, 21 seconds
注意

如果班次可能超过一天,您需要将最后一行更改为:

echo $working_hours->format('%a days, %H hours, %i minutes, %s seconds');
或者,如果您只需要几个小时,而不需要几天,请使用以下选项:

echo $working_hours->days*24+$working_hours->h . $working_hours->format(' hours, %i minutes, %s seconds');

此代码将执行您想要的操作。它处理数组的每个元素,当我们在
中看到
时,设置工作开始和结束时间;每次在
或恢复中看到
时设置一个时段开始;每次我们看到
out
break
时,将时段长度添加到一天的工作时间中。最后,我们计算一天的开始时间和我们通过添加所有时段而创建的时间之间的差值,这给了我们一整天的工作时间

foreach ($data as $event) {
    $this_time = new DateTime($event['created_at']);
    switch ($event['type']) {
        case 'in':
            $work_start_time = clone $this_time;
            $work_end_time = clone $this_time;
        case 'resume':
            $start_time = $this_time;
            break;
        case 'break':
        case 'out':
            $work_end_time->add($start_time->diff($this_time));
            break;
    }
}
$working_hours = $work_start_time->diff($work_end_time);
echo $working_hours->format('%H hours, %i minutes, %s seconds');
输出:

08 hours, 59 minutes, 21 seconds
注意

如果班次可能超过一天,您需要将最后一行更改为:

echo $working_hours->format('%a days, %H hours, %i minutes, %s seconds');
或者,如果您只需要几个小时,而不需要几天,请使用以下选项:

echo $working_hours->days*24+$working_hours->h . $working_hours->format(' hours, %i minutes, %s seconds');

请显示计算的实际代码。请显示计算的实际代码。嘿,尼克,谢谢。我现在是AFK自动取款机。我一回到电脑就会查这个。顺便问一下,如果日期范围与开始日期不一致,这是否支持?示例2月1日至2月2日?我在问br,因为一个人的班次有时会转换到第二天,比如夜班。谢谢。@PinoyStackOverflower只要事件的顺序是
in
,(
break
resume
)*,
out
,那么实际的日期值就无关紧要了(如果它们倒转时间就会被取消!)。如果转换在夜间进行,这将得到处理,因为所有变量都是完整日期。我尝试在同一时间将输入日期更改为2019-01-31,但输出仍然相同。@PinoyStackOverflower请参阅我的编辑。这将处理比一天更长的轮班嘿,尼克,这看起来很完美。我会好好测试的。之后我会把这个标记为正确答案。嘿,尼克,谢谢你。我现在是AFK自动取款机。我一回到电脑就会查这个。顺便问一下,如果日期范围与开始日期不一致,这是否支持?示例2月1日至2月2日?我在问br,因为一个人的班次有时会转换到第二天,比如夜班。谢谢。@PinoyStackOverflower只要事件的顺序是
in
,(
break
resume
)*,
out
,那么实际的日期值就无关紧要了(如果它们倒转时间就会被取消!)。如果转换在夜间进行,这将得到处理,因为所有变量都是完整日期。我尝试在同一时间将输入日期更改为2019-01-31,但输出仍然相同。@PinoyStackOverflower请参阅我的编辑。这将处理比一天更长的轮班嘿,尼克,这看起来很完美。我会好好测试的。之后我会把这个标记为正确答案。