2014-03-13 121 views
0

我用下面的代碼來計算的開始時間和結束時間,一些事件(從數據庫)之間的平均時間:平均時間

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

您是否確認來自您的數據庫的數據是正確的?您也可以嘗試對小數據樣本進行硬編碼以運行您的算法,以便您可以手動檢查結果並比較結果。 – ajp15243

+0

start_time和end_time如何存儲?時間戳秒數或日期時間字符串? –

+0

DateTime。另外,請參閱我的文章的最新更新。 – muttley91

回答

1

這很可能是DST問題。您的代碼是否在美國時區運行?再次提醒您,當您使用new DateTime("@0")時,這代表1970-01-01 00:00:00(非DST);在美國,DST已經開始了,所以從數據庫創建的DateTime對象的絕對值是一個小時。

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