计算 PHP 中的工作时间,包括刹车
Calculate time worked including brakes in PHP
我正在努力编写一个 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。请帮助
为此,请将字符串时间转换为 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;
?>
另一种方式,使用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
提供不需要太多数学运算或时间值解析的解决方案。
假设不知道哪一天,我们还可以计算结束时间和开始时间的偏移量,当开始时间是深夜时。
$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
。如果已知工作时间的日期,则可以修改脚本以允许指定日期并提供更精确的时间安排。
我正在努力编写一个 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。请帮助
为此,请将字符串时间转换为 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;
?>
另一种方式,使用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
提供不需要太多数学运算或时间值解析的解决方案。
假设不知道哪一天,我们还可以计算结束时间和开始时间的偏移量,当开始时间是深夜时。
$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
。如果已知工作时间的日期,则可以修改脚本以允许指定日期并提供更精确的时间安排。