我正在努力编写一个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。请帮忙
答案 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)
提供一个不需要太多数学或解析时间值的解决方案。
假设当天不知道,我们还可以说明结束时间和开始时间的偏移,当开始时间是深夜时。
$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