【问题标题】:Difference between durations持续时间之间的差异
【发布时间】:2018-10-12 23:40:59
【问题描述】:

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

持续时间如下所示

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 时,它会引发错误(显然是因为它正在读取它作为时间)

带有消息“DateTime::__construct()”的未捕获异常“Exception”: 时间字符串解析失败(1970-01-01 25:45:00)

还有其他方法吗?

【问题讨论】:

  • 如果您不关心时区等,最简单的方法可能是转换为分钟,减去,然后再转换回来。无需添加创建真正的 DateTime 样式对象的复杂性。
  • @CollinD - 你能举个例子吗?

标签: php datetime time difference


【解决方案1】:

您可以检查小时数是否大于 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

还请注意== 用于比较,而不是分配。

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


编辑

正如@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');

【讨论】:

  • 提醒一下,如果您的持续时间超过 1970 年 1 月的小时数,我怀疑这将遇到与您之前相同的问题。
  • 你是对的@CollinD,谢谢。我已经更新了一个新方法的答案。
  • 如果您已经将所有内容都转换为分钟,那么最好只删除使用DateTime all-together 所增加的复杂性。持续时间实际上只是维度时间的标量,因此添加时间上下文只是要求 imo 遇到奇怪的边缘情况问题。
  • 感谢您的有趣评论@CollinD。 (我稍微修改了代码)。 DateInterval 对象允许格式化,我用它来匹配 OP 原始代码。
  • @Syscall - 使用这些变量$actual='34:50'; $expected='22:00';时,您的更新返回0h 00m
【解决方案2】:

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

$t1=explode(':',$expected);
$t2=explode(':',$actual);
$d=60*($t1[0]-$t2[0])+t1[1]-t2[1];
$result=str_pad(floor($d/60),2,'0',STR_PAD_LEFT).':'.str_pad($d%60,2,'0',STR_PAD_LEFT);

【讨论】:

    【解决方案3】:

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

    <?php
    // get the difference in H:mm between two H:mm 
    function diff_time($actual, $expected) {
        $diff_mins = mins($actual) - mins($expected);
    
        return format_mins($diff_mins);
    }
    
    // convert a HH:mm to number of minutes
    function mins($t) {
        $parts = explode(':', $t);
    
        return $parts[0] * 60 + $parts[1];
    }
    
    // convert number of minutes into HH:mm
    function format_mins($m) {
        $mins = $m % 60;
        $hours = ($m - $mins) / 60;
    
        // format HH:mm
        return $hours . ':' . sprintf('%02d', abs($mins));
    }
    
    var_dump(diff_time('23:15', '25:45'));
    var_dump(diff_time('25:15', '23:45'));
    

    这个输出:

    string(5) "-2:30"
    string(4) "1:30"
    

    .. 第一次比预期少 2:30,第二次比预期多 1:30。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-10
      • 2017-03-15
      • 1970-01-01
      相关资源
      最近更新 更多