计算工作时间,包括PHP中的制动器

时间:2018-02-22 17:54:49

标签: php date time decimal difference

我正在努力编写一个PHP函数来计算两个小时之间的时差(减去刹车),结果将是十进制格式。我的输入是24小时格式的字符串(hh:mm):

$start = '07:00'; //started at 7 after midnight
$brake = '01:30'; //1 hour and 30 minutes of brake
$finish = '15:00'; //finished at 3 afternoon
//the desired result is to print out '6.5'

示例2

$start = '19:00'; //started late afternoon
$brake = '00:30'; //30 minutes of brake
$finish = '03:00'; //finished at 3 after midnight
//the desired result is to print out '7.5'

我曾经在MS Excel中使用以下公式,效果很好:

=IF(D12>=F12,((F12+1)-D12-E12)*24,(F12-D12-E12)*24) '7.5 worked hours

其中
D12 - 开始时间'19:00
F12 - 结束时间'03:00
E12 - 制动时间'00:30

我试着玩strtotime()而没有运气。我的PHP版本是5.4.45。请帮忙

3 个答案:

答案 0 :(得分:1)

为此,请将字符串时间转换为unix时间戳。这是自unix纪元以来的整数秒数( 00:00:00协调世界时(UTC),1970年1月1日星期四,减去自那时以来发生的闰秒数) 。算一算,然后使用Date()函数将其格式化为起始格式:

<?php

$start = '19:00'; //started late afternoon
$break = '00:30'; //30 minutes of brake
$finish = '03:00'; //finished at 3 after midnight

//get the number of seconds for which we took a $break
//do this by converting break to unix timestamp, then extracting the hour and multiplying by 360
//and do the same extracting minutes and multiplying by 60
$breaktime = date("G",strtotime($break))*60*60 + date("i",strtotime($break))*60;

//get start time
$unixstart=strtotime($start);

//get finish time. Add a day if finish is tomorrow
if (strtotime($finish) < $unixstart) {
    $unixfinish = strtotime('+1 day', strtotime($finish));
} else {
    $unixfinish = strtotime($finish);
}

//figure out time worked
$timeworked = ($unixfinish - $unixstart - $breaktime) / 3600;

echo $timeworked;

?>

答案 1 :(得分:1)

提供一个不需要太多数学或解析时间值的解决方案。

假设当天不知道,我们还可以说明结束时间和开始时间的偏移,当开始时间是深夜时。

示例:https://3v4l.org/FsRbT

$start = '07:00'; //started at 7 after midnight
$break = '01:30'; //1 hour and 30 minutes of brake
$finish = '15:00'; //finished at 3 afternoon

//create the start and end date objects
$startDate = \DateTime::createFromFormat('H:i', $start);
$endDate =  \DateTime::createFromFormat('H:i', $finish);

if ($endDate < $startDate) {
    //end date is in the past, adjust to the next day
    //this is only needed since the day the time was worked is not known
    $endDate->add(new \DateInterval('PT24H'));
}

//determine the number of hours and minutes during the break
$breakPeriod = new \DateInterval(vsprintf('PT%sH%sM', explode(':', $break)));

//increase the start date by the amount of time taken during the break period
$startDate->add($breakPeriod);

//determine how many minutes are between the start and end dates
$minutes = new \DateInterval('PT1M');
$datePeriods = new \DatePeriod($startDate, $minutes, $endDate);

//count the number of minute date periods
$minutesWorked = iterator_count($datePeriods);

//divide the number of minutes worked by 60 to display the fractional hours
var_dump($minutesWorked / 60); //6.5

这适用于24小时内00:00 - 23:59内的任何时间值。如果知道工作时间的那一天,可以修改脚本以允许给出这一天并提供更精确的时间。

答案 2 :(得分:0)

另一种方法,使用DateTime。基本上,使用开始和结束的时间创建2个DateTime个对象。到开始时间,减去制动时间,并从结果中减去结束时间。

您需要分割制动时间才能使用modify()

<?php
$start = '07:00'; //started at 7 after midnight
$brake = '01:30'; //1 hour and 30 minutes of brake
$brakeBits = explode(":", $brake);
$finish = '15:00'; //finished at 3 afternoon
$startDate = \DateTime::createFromFormat("!H:i", $start);
$startDate->modify($brakeBits[0]." hour ".$brakeBits[1]." minutes");
$endDate  = \DateTime::createFromFormat("!H:i", $finish);
$diff = $startDate->diff($endDate);
echo $diff->format("%r%H:%I"); // 06:30

Demo