Php 持续时间之间的差异

Php 持续时间之间的差异,php,datetime,time,difference,Php,Datetime,Time,Difference,我正在创建一个时间表,其中显示了预期和实际的小时数 持续时间按如下方式保存 $acutal=='23:15'; $expected=='25:45'; $start_time = new DateTime("1970-01-01 $acutal:00"); $time = $start_date->diff(new DateTime("1970-01-01 $expected:00")); 23:15-23小时15分钟 25:45-25小时45分钟 我需要计算出两者之间的小时和分钟差异(

我正在创建一个时间表,其中显示了预期和实际的小时数

持续时间按如下方式保存

$acutal=='23:15';
$expected=='25:45';
$start_time = new DateTime("1970-01-01 $acutal:00");
$time = $start_date->diff(new DateTime("1970-01-01 $expected:00"));
23:15
-23小时15分钟

25:45
-25小时45分钟

我需要计算出两者之间的小时和分钟差异(额外工作小时)

我试过下面的方法

$acutal=='23:15';
$expected=='25:45';
$start_time = new DateTime("1970-01-01 $acutal:00");
$time = $start_date->diff(new DateTime("1970-01-01 $expected:00"));
但是,当小时数超过24:00时,它会抛出一个错误(显然是因为它将其作为时间读取)

未捕获异常“exception”,消息为“DateTime::\u构造(): 无法分析时间字符串(1970-01-01 25:45:00)


还有其他方法吗?

您可以检查小时数是否大于24小时,如果是,请添加一天,然后删除24小时

$actual='23:15';
$expected='25:45';

$day = 1;
list($hrs, $min) = explode(':', $expected);
if ($hrs > 24) { $day += 1; $hrs -= 24; }

$start_time = new DateTime("1970-01-01 $actual:00");
$time = $start_time->diff(new DateTime("1970-01-$day $hrs:$min:00"));

echo $time->format('%hh %Im');
输出:

2h 30m
还请注意,
==
用于比较,而不是分配

如果($hrs>24),您还可以通过
while()
更改
if($hrs>24)
,如果有48小时或更长时间


编辑

正如@CollinD所指出的,如果时间超过一个月的天数,它将失败。下面是另一个解决方案:

$actual='23:15';
$expected='25:45';

list($hrs, $min) = explode(':', $actual);
$total1 = $min + $hrs * 60;

list($hrs, $min) = explode(':', $expected);
$diff = $min + $hrs * 60 - $total1;

$start_time = new DateTime();
$expected_time = new DateTime();
$expected_time->modify("+ $diff minutes");
$time = $start_time->diff($expected_time);

echo $time->format('%hh %Im');

您可以尝试使用datetime函数,但对我来说,将时间视为字符串、使用split或explode获取小时和分钟、转换为整数、获取分钟差并将其转换回小时和分钟(整数除以60和余数)似乎更为简单


您可以通过跟踪工作分钟数手动执行此操作-这将是精确的,并且允许您显示负差异


如果你不在乎时区之类的东西,可能最简单的方法就是转换成分钟,减法,再转换回来。不需要增加创建实时样式对象的复杂性。@CollinD-你能提供一个例子吗?作为提醒,我怀疑如果你的持续时间超过1970年1月的小时数,这将遇到与你以前相同的问题。你说得对@CollinD,谢谢。我已经用一种新的方法更新了答案。如果您已经将所有内容都转换为分钟,那么似乎最好是同时使用
DateTime
来消除增加的复杂性。持续时间实际上只是维度时间的标量,因此添加时间上下文只会带来奇怪的边缘情况。感谢您对@CollinD的有趣评论。(我稍微修改了代码)。
DateInterval
对象允许格式化,我用它来匹配OP原始代码。@Syscall-当使用这些变量时,更新返回
0h00m
$预计时间为22:00
string(5) "-2:30"
string(4) "1:30"