PHP计算'停机时间'

时间:2011-05-06 16:44:21

标签: php mysql datediff downtime

我用PHP创建了一个程序,它在MySQL数据库工作时存储。显示程序是否正常的表格如下所示:

Table_name: downtime
Working(int)    Time(datetime)
1               2011-05-06 15:18:55
0               2011-05-06 15:20:21
1               2011-05-06 15:20:24
0               2011-05-06 16:05:13
1               2011-05-06 16:05:15
0               2011-05-06 16:27:59
1               2011-05-06 16:28:01
0               2011-05-06 16:37:35
1               2011-05-06 16:37:37

现在我想检索日期之间的“停机时间”。假设日期1是2011-05-06 15:20:24而日期2是2011-05-06 16:28:15,那么我希望脚本返回该期间1和0之间差异的总和。我该怎么做?

重要的是要知道日期1例如是2011-05-06 15:20:22,那么有两个额外的秒停机时间。很难想到一个(几乎)完美的解决方案。

5 个答案:

答案 0 :(得分:2)

此代码应该可以使用,我已经使用您的示例数据对其进行了测试:

// Example data
// Note: assumes $data is sorted by date already
$data = array(
    "2011-05-06 15:18:55"=>1,
    "2011-05-06 15:20:21"=>0,
    "2011-05-06 15:20:24"=>0,
    "2011-05-06 16:05:13"=>0,
    "2011-05-06 16:05:15"=>0,
    "2011-05-06 16:27:59"=>1,
    "2011-05-06 16:28:01"=>0,
    "2011-05-06 16:37:35"=>0,
    "2011-05-06 16:37:37"=>1
    );

$startTime = strtotime("2011-05-06 15:18:55");
$endTime = strtotime("2011-05-06 16:28:01");

$totalUptime = 0;    
$lastUptime = 0;

foreach ($data as $dateString => $isWorking)
{
    $timestamp = strtotime($dateString);

    if ($lastWorking && $lastTimestamp)
    {
        $allowedStart = $lastTimestamp;
        if ($allowedStart<$startTime)
            $allowedStart = $startTime;

        $allowedEnd = $timestamp;
        if ($allowedEnd>$endTime)
            $allowedEnd = $endTime;

        $diff = $allowedEnd-$allowedStart;

        if ($diff>0)
        {
            $totalUptime += $diff;
        }
    }

    if ($timestamp>=$endTime)
    {
        break;
    }

    $lastTimestamp = $timestamp;    
    $lastWorking = $isWorking;
}

print "Total uptime: ".$totalUptime." seconds";

您只需要使用自己的记录从数据库中填充$data

答案 1 :(得分:1)

浏览将时间戳转换为使用strtotime()的unix时期的所有行,然后找到它们之间的差异,并将其相加以获得总停机时间。

答案 2 :(得分:1)

我现在使用的解决方案如下:

    $objects = Get("table","`date` BETWEEN '".$date_start."' AND '".$date_end."'");   

    $prev = new stdClass();
    $prev->new = 1;
    $prev->date = $date_start;

    $next = new stdClass();
    $next->new = 0;
    $next->date = $date_end;
    $objects = array_merge(array($prev),$objects,array($next));

    $uptime = 0;
    $downtime = 0;
    $prevtime = false;
    foreach($objects as $object)
    {
        $newtime = strtotime($object->date);
        if($prevtime && $object->new == 1)
        {
            $downtime += $newtime - $prevtime;
        }
        elseif($prevtime && $object->new == 0)
        {
            $uptime += $newtime - $prevtime;
        }
        $prevtime = $newtime;
    }     

获取();是我与数据库进行通信的函数:它返回查询找到的对象(记录),如果要测试/使用此代码,请将其替换为以下内容:

$objects = array();
$result = mysql_query("SELECT * FROM table WHERE `date` BETWEEN '".$date_start."' AND '".$date_end."'");
while($object = mysql_fetch_object($result))
{
    $objects[] = $object;    
}

答案 3 :(得分:0)

select timediff(
(
    select `time`
    from downtime
    where working = 1
    and `time` > t1.`time`
    order by `time` asc
    limit 1
),
t1.`time`
)
from downtime t1
where t1.working = 0

这应该给你几行,每个停机时间一行。每行显示时间差,您仍然需要将这些行添加到一起以查找实际的停机时间。我不确定当你在时间差上使用MySQL的sum()函数时会发生什么,它可能只返回秒。您可以根据需要限制time字段,但我还没有测试当开始时间或结束时间处于停机时间段时会发生什么。

答案 4 :(得分:-1)

编辑:我误解了这个问题,忽略了这个答案

答案很大程度上取决于你如何在MySQL中存储这些数据。您很可能需要一个类似的查询:

SELECT COUNT(*) FROM table WHERE working='1' AND DATE>='startDate' AND DATE<='endDate';

这将为您提供给定范围内的'1'的数量。