PHP расчет 'простоев' - PullRequest
       9

PHP расчет 'простоев'

1 голос
/ 06 мая 2011

Я создал программу на 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 ]

2 голосов
/ 06 мая 2011

Этот код должен работать, я проверил его на данных вашего примера:

// 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 голос
/ 08 мая 2011

Решение, которое я использую сейчас, следующее:

    $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;
    }     

Get (); моя функция для связи с базой данных: она возвращает объекты (записи), найденные запросом, замените его следующим, если вы хотите проверить / использовать этот код:

$objects = array();
$result = mysql_query("SELECT * FROM table WHERE `date` BETWEEN '".$date_start."' AND '".$date_end."'");
while($object = mysql_fetch_object($result))
{
    $objects[] = $object;    
}
1 голос
/ 06 мая 2011

Пройдите по всем строкам, конвертируя временные метки в эпоху Unix с помощью strtotime () , затем просто найдите разницу между ними и сложите ее, чтобы получить общее время простоя.

0 голосов
/ 06 мая 2011
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

Это должно дать вам несколько строк, по одному на каждый период простоя.Каждая строка показывает разницу во времени, и вам все равно придется добавить эти строки вместе, чтобы найти фактическое время простоя.Я не уверен, что происходит, когда вы используете функцию sum () MySQL для разницы во времени, она, вероятно, просто возвращает секунды.Вы можете ограничить поле time по желанию, хотя я не проверял, что происходит, когда время начала или окончания находится в период простоя.

0 голосов
/ 06 мая 2011

Редактировать: я неправильно понял вопрос, игнорировать этот ответ

Ответ во многом зависит от того, как вы сохранили эти данные в MySQL. Скорее всего, вам понадобится запрос типа:

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

Что даст вам количество единиц в данном диапазоне.

...