Как рассчитать диапазон дат между несколькими датами, которые перекрываются
У меня много дат, которые мне нужно проверить.
Например:
1 - Start: 1387267200, End: 1387274400
2 - Start: 1387270800, End: 1387275000
3 - Start: 1387250200, End: 1387273000
4 - Start: 1387285200, End: 1387288800
Что мне нужно, чтобы рассчитать foreach перекрывает минимальную дату начала и максимальную дату окончания.
Для примера выше, что алгоритм должен дать в выводе:
Start1: 1387250200 -> End1: 1387275000.
Start2: 1387285200 -> End2: 1387288800.
Как мне это сделать?
Спасибо!
2 ответа
Решение
Этот скрипт ищет перекрывающиеся интервалы и получает новые с минимальной датой начала и максимальной датой окончания:
// Input
$intervals = array(
array(1387267200, 1387274400),
array(1387270800, 1387275000),
array(1387250200, 1387273000),
array(1387285200, 1387288800),
);
// Overlapped intervals
$overlapped = array();
foreach ($intervals as $i => $a) {
$group = [$a];
foreach ($intervals as $j => $b) {
if (
$i !== $j && (($a[0] <= $b[0] && $a[1] >= $b[0])
|| ($a[0] <= $b[1] && $a[0] >= $b[0]))
) {
$group[] = $b;
}
}
sort($group);
$overlapped[] = $group;
}
// Multidimensional array_unique()
$overlapped = array_map('unserialize',
array_unique(array_map('serialize', $overlapped))
);
// Output
$output = array();
// Get min/max dates for each overlapped group
foreach ($overlapped as $group) {
$min = null;
$max = null;
foreach ($group as $interval) {
if ($min === null || $interval[0] < $min) {
$min = $interval[0];
}
if ($max === null || $interval[1] > $max) {
$max = $interval[1];
}
}
$output[] = array($min, $max);
}
print_r($output);
Выход:
Array
(
[0] => Array
(
[0] => 1387250200
[1] => 1387275000
)
[1] => Array
(
[0] => 1387285200
[1] => 1387288800
)
)
Сортировать все время начала и окончания в массиве.
- Итерация по массиву.
- Задавать
i = 0;
а такжеcount = 0;
(количество отслеживает количество активных интервалов) - Когда вы встречаете время начала, запишите его как время начала
i'th
перекрытия. Кроме того, увеличить счетчикcount
, - Когда вы столкнетесь с временем окончания, уменьшите
count
, Еслиcount
становится равным нулю, отметьте это как время окончанияith
интервал и приращениеi
,