我正在使用以下代码计算许多事件(来自数据库)的开始时间和结束时间之间的平均时间:
function getATBData($siteID, $fromDate, $toDate)
{
global $pdo;
$ATBarray = array();
$maxATB;
$minATB;
$avgATB;
$totalATB=new DateTime("@0");
$totalEvents=0;
$timetable;
$query = "SELECT id, siteID, start_time, end_time FROM atb_log WHERE siteID=:siteID AND (start_time BETWEEN :fromDate AND :toDate) AND (end_time BETWEEN :fromDate AND :toDate)";
$stmt = $pdo->prepare($query);
$stmt->bindParam(":siteID", $siteID);
$stmt->bindParam(":fromDate", $fromDate);
$stmt->bindParam(":toDate", $toDate);
$stmt->execute();
foreach ($stmt as $row)
{
$timeDiff = date_diff(new DateTime($row['start_time']),new DateTime($row['end_time']), true); //force absolute
if(!isset($maxATB) OR dateIntervalInSeconds($timeDiff) > dateIntervalInSeconds($maxATB))
$maxATB = $timeDiff;
if(!isset($minATB) OR dateIntervalInSeconds($timeDiff) < dateIntervalInSeconds($minATB))
$minATB = $timeDiff;
$totalATB->add($timeDiff);
$totalEvents++;
}
if($totalEvents!=0)
{
//$avgATB=round($totalATB->getTimestamp() / $totalEvents);
$avgATB = average_time($totalATB->format("H:i:s"),$totalEvents,0);
}
else
{
$avgATB=0;
$maxATB=new DateInterval('PT0S');
$minATB=new DateInterval('PT0S');
}
$avgSeconds = new DateInterval("PT" . $avgATB . "S");
$ATBarray['max'] = $maxATB->format("%H:%I:%S");
$ATBarray['min'] = $minATB->format("%H:%I:%S");
$ATBarray['avg'] = gmdate("H:i:s",$avgATB); //$avgSeconds->format("%H:%i:%s");
$ATBarray['total'] = $totalATB->format("H:i:s");
$ATBarray['events'] = $totalEvents;
return $ATBarray;
}
不幸的是,我的平均成绩非常高。例如,我发现最大时间是3秒,最小时间是0秒,但平均时间是1小时1秒。这显然是不可能的,所以我计算总数和/或平均数有什么不对吗?总数也相当高,但我无法手动添加这些数据,因此我不确定这是否也是错误的。
答案 0 :(得分:1)
这很可能是DST问题。您的代码是否在美国时区运行?重新表示当您使用new DateTime("@0")
时,这表示1970-01-01 00:00:00(非DST);在美国,DST现已启动,因此从数据库创建的DateTime对象的绝对值为一小时。
答案 1 :(得分:0)
编辑:
我改变了我计算平均值的方式。我在上面添加了新功能,这里是平均函数(found here):
function average_time($total, $count, $rounding = 0) //from SO
{
$total = explode(":", strval($total));
if (count($total) !== 3) return false;
$sum = $total[0]*60*60 + $total[1]*60 + $total[2];
$average = $sum/(float)$count;
$hours = floor($average/3600);
$minutes = floor(fmod($average,3600)/60);
$seconds = number_format(fmod(fmod($average,3600),60),(int)$rounding);
if($hours<10) $hours = "0"+$hours; //add leading 0
if($minutes<10) $minutes = "0"+$minutes;
if($seconds<10) $seconds = "0"+$seconds;
return $hours.":".$minutes.":".$seconds;
}
所以现在我的平均数字发生了变化,我试图查看总数以确定它们是否正确。但我已将此问题发布为另一个问题located here。