Это связано с моим предыдущим вопросом о получении среднего временного интервала по определенному набору данных [здесь] [1]. Я снова опубликую всю функцию:
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
и так далее. Кажется, что, несмотря на то, что время добавляется только в пару секунд, каждый час добавляется час. Вызов add()
на $timeDiff
выше – это то, как я добавляю.
Итак, вопрос в том, есть ли другой способ вызвать функцию add()
, чтобы она добавила только секунды? Я называю это неправильно?
Hm, средняя разница в секундах, почему этот 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
Отформатируйте те min / max / avg / sum секунды, сколько хотите.
Как я писал в ответе на ваш другой вопрос, это проблема летнего времени (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