БлогNot. PHP: ищем среднее время за сутки

PHP: ищем среднее время за сутки

Имеется несколько строк со значениями времени вида ЧЧ:ММ или ЧЧ:ММ:СС в 24-часовом формате, найти среднее время.

Будем считать, что 0:00 - это прошедшая полночь, а 24:00 - следующая.

Строки со временем "положим" в массив $timestamps, с помощью функции time2sec найдем время в секундах (массив $times), усредним его и переведём обратно в часы, минуты и секунды функцией sec2time.

Думается, для практических целей такой точности, как в показанном ниже коде достаточно (вообще-то, значение $average выходит вещественным и при обработке его функцией sec2time мы теряем точность). Ниже показан PHP-код функций для перевода времени ЧЧ:ММ:СС в секунды и обратно и тестовый вызов этих функций.

<?php
 function time2sec ($timestr) {
  $parsed = date_parse ($timestr); //функция доступна с версии PHP 5.2.0
  return $parsed['hour'] * 3600 + $parsed['minute'] * 60 + $parsed['second'];
 }

 function sec2time ($sec) { //только для положительных значений $sec
  return sprintf("%02d:%02d:%02d", floor($sec/3600), ($sec/60)%60, $sec%60);
 }

 $timestamps = array('12:00:20','15:30:10','0:00','24:00');
 $times = array();
 foreach ($timestamps as $t) $times[] = time2sec($t);
 $average = array_sum($times)/count($times);
 echo sec2time($average);
?>

Результат совпадает с тем, что выдаёт для этих меток времени Excel (метки отформатированы форматом Время - 37:30:55 в Excel 2007):

Среднее время в Excel
Среднее время в Excel

Можно подойти к задаче и по-другому.

Добавив к листингу функции time2ang для перевода строки ЧЧ:ММ:СС в угол от 0 до 360 градусов, ang2time для обратного перевода угла в строку времени и mean_angle для вычисления среднего угла по массиву заданных в градусах от до 360 углов $angs, получим ещё один вариант усреднения времени, вот код изменённого скрипта.

<?php
 function time2sec ($timestr) {
  $parsed = date_parse ($timestr); //функция доступна с версии PHP 5.2.0
  return $parsed['hour'] * 3600 + $parsed['minute'] * 60 + $parsed['second'];
 }

 function sec2time ($sec) { //только для положительных значений $sec
  return sprintf("%02d:%02d:%02d", floor($sec/3600), ($sec/60)%60, $sec%60);
 }

 function time2ang ($timestr) {
  return 360. * (time2sec($timestr)/86400.);
 }
 
 function ang2time ($ang) {
  return sec2time (86400. * $ang / 360.);
 }
 
 function mean_angle($angs) {
  if (!is_array($angs)) return $angs;
  $sins = $coss = 0.;
  foreach ($angs as $a) {
   $sins += sin(deg2rad($a)); $coss += cos(deg2rad($a));
  }
  $avgsins = $sins / count($angs);
  $avgcoss = $coss / count($angs);
  $avg = rad2deg(atan2($avgsins,$avgcoss));
  while ($avg<0) $avg += 360;
  return $avg;
 }
 
 $timestamps = array('12:00:20','15:30:10','24:00','0:00');
 $times = array();
 foreach ($timestamps as $t) $times[] = time2ang($t);
 $average = mean_angle($times);
 echo 'Average angle='.$average.', time='.ang2time($average);
?>

Результат, выданный этим скриптом, будет отличаться, здесь мы усредняем время как бы по 24-часовому кругу.

05.11.2017, 20:40 [2251 просмотр]


теги: php числа время

К этой статье пока нет комментариев, Ваш будет первым