2014-03-13 20 views
1

這來自我上一個關於獲取指定數據集[位於此處] [1]的平均時間間隔的問題。我會後再次全部功能:DateTime :: add即使間隔時間應該僅爲秒,也會增加小時數

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); 
     echo "added " . $timeDiff->format("%H:%I:%S") . " total is now: " . $totalATB->format("H:i:s") . "<br />"; 
     $totalEvents++; 
    } 

    if($totalEvents!=0) 
    { 
     $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'] = $avgATB; 
    $ATBarray['total'] = $totalATB->format("H:i:s"); 
    $ATBarray['events'] = $totalEvents; 

    return $ATBarray; 

} 

鑑於此功能,我增加了一個輸出語句來嘗試調試(爲什麼我得到這麼大的時間間隔爲我的總時間,當大部分值是幾秒鐘),這就是它的輸出:

added 00:00:02 total is now: 01:00:02 
added 00:00:00 total is now: 02:00:02 
added 00:00:01 total is now: 03:00:03 
added 00:00:01 total is now: 04:00:04 
added 00:00:00 total is now: 05:00:04 
added 00:00:02 total is now: 06:00:06 
added 00:00:00 total is now: 07:00:06 

等等。所以看起來,儘管時間只有幾秒鐘,但每次都會增加一個小時。上面$timeDiffadd()的呼叫是我如何添加的。

所以問題是 - 有沒有不同的方式來調用add()函數,使它只會添加秒?我說錯了嗎?

回答

1

嗯,在幾秒鐘內平均差異,爲什麼代碼PHP大片,如果你的數據庫可以給你:

SELECT 
    SEC_TO_TIME(MAX(TIME_TO_SEC(TIMEDIFF(end_time,start_time)))) AS max_timediff, 
    SEC_TO_TIME(MIN(TIME_TO_SEC(TIMEDIFF(end_time,start_time)))) AS min_timediff, 
    SEC_TO_TIME(AVG(TIME_TO_SEC(TIMEDIFF(end_time,start_time)))) AS avg_timediff, 
    SEC_TO_TIME(SUM(TIME_TO_SEC(TIMEDIFF(end_time,start_time)))) AS sum_timediff, 
    COUNT(id) as total_events 
FROM atb_log 
WHERE 
    siteID=:siteID 
    AND start_time > :fromDate 
    AND end_time < :toDate 

根據你的喜好設置最小/最大/平均/秒數之和。

+0

稱它比PHP更熟悉PHP? :)這很好,我可能會重寫這些函數來做到這一點。 這些結果可以從PHP格式化,或者你也可以從SQL中完成? – muttley91

+0

'SEC_TO_TIME'應該這樣做,我會加入它。 – Wrikken

+0

這節省了我大量的工作。非常感謝你。今天學到的教訓是儘可能讓數據庫爲你工作,無論如何主要是爲'DateTime'工作。 – muttley91

1

正如我在回答您的其他問題時寫的,這是夏令時(DST)問題。在美國,DST已經開始了;在歐洲不是。

試試這個代碼:

timecheck("Europe/Amsterdam"); 
timecheck("America/Los_Angeles"); 

function timecheck($timezone) { 
date_default_timezone_set($timezone); 

$totalATB=new DateTime("@0"); 
$t1 = "2014-01-01 17:30:00"; 
$t2 = "2014-01-01 17:35:00"; 

$dt1 = new DateTime($t1); 
$dt2 = new DateTime($t2); 

$timeDiff = date_diff($dt1, $dt2, true); 

printf("[%s] Starting with with: %s\n", $timezone, $totalATB->format("H:i:s")); 
$totalATB->add($timeDiff); 
printf("[%s] added %s, total is now: %s\n", $timezone, $timeDiff->format("%H:%I:%S"), $totalATB->format("H:i:s")); 
} 

輸出:

[Europe/Amsterdam] Starting with with: 00:00:00 
[Europe/Amsterdam] added 00:05:00, total is now: 00:05:00 
[America/Los_Angeles] Starting with with: 00:00:00 
[America/Los_Angeles] added 00:05:00, total is now: 01:05:00 
+0

對不起,我打算回到你對這個問題的答案。所以我有點困惑 - 如何增加這樣的間隔會受到DST的影響?更重要的是,我怎樣才能防止這種情況發生? DST決不會影響這類事情,因爲它會徹底改變數據的準確性(不僅會拋出總數,而且會影響平均數)。 – muttley91

+0

不想模糊東西,但上面的代碼在這裏沒有重現問題(不添加1h)。 – Niloct

+0

我其實只是發現這個:https://bugs.php.net/bug.php?id = 61955一個用戶報告設置一個特定的時區確實解決了這個問題,但是......當DST不會被搞亂打歐洲? – muttley91