简体   繁体   English

DateTime :: add会增加小时,即使间隔应该只有几秒钟

[英]DateTime::add adds hours even when interval should only be seconds

This comes from my previous question on getting the average time interval over a specified data set, [located here][1]. 这来自于我先前的问题,该问题是获取指定数据集[位于此处] [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. 上面$timeDiff上对add()的调用是我添加的方式。

So the question is - is there a different way to call the add() function such that it will only add the seconds? 所以问题是-是否有另一种方式来调用add()函数,使其仅增加秒数? Am I calling it incorrectly? 我打错电话了吗?

As I wrote in the answer to your other question, this is a DST (Daylight Savings Time) problem. 正如我在回答其他问题的答案中所写的那样,这是DST(夏令时)问题。 In the US, DST has already begun; 在美国,DST已经开始。 in Europe not. 在欧洲没有。

Try this code: 试试这个代码:

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"));
}

The output: 输出:

[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

Hm, average difference in seconds, why that PHP swath of code if your database can give it to you: 嗯,以秒为单位的平均差异,如果数据库可以为您提供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

Format those min/max/avg/sum of seconds as you like. 根据需要设置秒的最小值/最大值/平均值/总和。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM