即使间隔只能是秒,DateTime :: add也会添加小时数 [英] DateTime::add adds hours even when interval should only be seconds
问题描述
这来自我之前关于获取指定数据集[位于此处] [1]的平均时间间隔的问题。我将再次发布整个函数:
function getATBData($ siteID,$ fromDate,$ toDate)
{
global $ pdo;
$ ATBarray = array();
$ maxATB;
$ minATB;
$ avgATB;
$ totalATB = new DateTime(@ 0);
$ totalEvents = 0;
$ timeet;
$ 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);
echoadded。 $ timeDiff->格式(%H:%I:%S)。 现在总计:。 $ totalATB->格式(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->格式(%H:%I:%S);
$ ATBarray ['min'] = $ minATB->格式(%H:%I:%S);
$ ATBarray ['avg'] = $ avgATB;
$ ATBarray ['total'] = $ totalATB->格式(H:i:s);
$ ATBarray ['events'] = $ totalEvents;
return $ ATBarray;
}
给定这个函数,我添加了一个输出语句来尝试调试为什么我得到如此大的时间间隔我的总时间(当大多数值是小的秒数),这是它的输出:
添加00:00:02总共现在是:01:00:02
/ pre>
添加00:00:00总共现在:02:00:02
添加00: 00:01总是现在:03:00:03
加00:00:01总共现在:04:00:04
加00:00:00总共现在:05:00:04
添加00:00:02总共现在:06:00:06
添加00:00:00总共现在: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
根据需要格式化最小/最大/平均/秒的秒数。
This comes from my previous question on getting the average time interval over a specified data set, [located here][1]. I'll post the entire function again:
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; }
Given this function, I have added an output statement to try to debug why I was getting such a large time interval for my total time (when most of the values are a small number of seconds) and this is what it's outputting:
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
and so on. So it seems like, despite the time to be added only being a couple seconds, it adds an hour every time. The call to
add()
on$timeDiff
above is how I'm adding.So the question is - is there a different way to call the
add()
function such that it will only add the seconds? Am I calling it incorrectly?解决方案Hm, average difference in seconds, why that PHP swath of code if your database can give it to you:
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
Format those min/max/avg/sum of seconds as you like.
这篇关于即使间隔只能是秒,DateTime :: add也会添加小时数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!