如何用PHP总结多个时间间隔

时间:2014-07-14 13:54:10

标签: php datetime

在我的应用程序中,我可以创建项目,每个项目我都可以记录工作报告。每个报告都有一个开始和结束时间戳。项目描述中的表格显示该项目的每个报告,并且还计算持续时间(使用DateTime和在开始和结束时间戳之间使用的diff()函数)。现在我想计算项目的总工作时间,但我不知道如何做到这一点。我已经尝试以某种方式循环遍历所有报告,然后使用DateTime函数,但我无处可去......我最后一次绝望的尝试是这样的:

public static function calculateDuration($start, $end)
{
    $start = date('Y-m-d H:i:s', $start);
    $end = date('Y-m-d H:i:s', $end);

    $s = new \DateTime($start);
    $e = new \DateTime($end);
    $interval = $e->diff($s);

    return $interval->format('%H:%I');
}

public static function calculateTotal($idProject)
{
  $reports = self::find('id_project = "' . $idProject . '"');
  $totalReports = new \DateTime();
  foreach ($reports as $report) {
      $totalReports->add(new \DateInterval(self::calculateDuration($report->getStart(), $report->getEnd())));
  }
  /*echo '<pre>';
  die(var_dump($totalReports));
  echo '</pre>';*/
  return $totalReports->format('H:I');
}

calculateDuration函数完美地工作,但当然calculateTotal没有,因为DateInterval不接受类似&#34; 0:30&#34;的字符串。所以这完全没用......

我希望我提供了所有必要的信息,如果您需要其他信息,请告诉我。

2 个答案:

答案 0 :(得分:1)

只需创建一个有效的DateInterval格式,而不是返回小时和分钟:

// Untested. Might need escaping.
return $interval->format('PT%HH%IM');

答案 1 :(得分:1)

为了清楚我的评论:您已经calculateDuration完成了所有工作,并在内部处理DateInterval对象。那么为什么不利用呢?这里,getInterval是一个受保护的方法,它由两个现有方法使用,并直接返回DateInterval对象。现在calculateDuration成为一个简单的格式化函数,calculateTotal可以访问DateInterval对象。

protected static function getInterval($start, $end)
{
    $s = new \DateTime('@' . $start);
    $e = new \DateTime('@' . $end);
    return $e->diff($s);
}

public static function calculateDuration($start, $end)
{
    return self::getInterval($start, $end)->format('%H:%I');
}

public static function calculateTotal($idProject)
{
    // ...

    $totalReports = new \DateTime();
    $totalReportsEnd = clone $totalReports;

    foreach ($reports as $report) {
        $totalReportsEnd->add(self::getInterval(
            $report->getStart(),
            $report->getEnd()
        ));
    }

    $totalInterval = $totalReportsEnd->diff($totalReports);
    // do as you wish with the interval
}