Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. Социальная инженерия и социальные хакеры. Авторы: Кузнецов М.В., Симдянов И.В. C++. Мастер-класс в задачах и примерах. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум Структурный форум

тема: Интервалы дат
 
 автор: Zdraff   (03.12.2013 в 11:50)   письмо автору
 
 

Всем привет. Есть массив, в котором хранятся начальное и конечное время промежутка в unixtime:
[0] => ( [start] => 12325446, [stop] => 12389556), [1] => ... )
Временные промежутки пересекаются. То есть один может быть с 1 января по 20 февраля, второй с 5 января по 1 февраля, третий с 25 января по 25 апреля и т.д.
Нужно вывести временные промежутки от "сегодня" до "конца самого последнего промежутка", на которых пересекается не больше n промежутков из имеющегося массива.
Пример: есть промежутки:
10 января - 20 января
12 января - 23 января
8 января - 15 января
16 января - 25 января
Если n=2, то нужно вывести время, не занятое двумя или более промежутками, то есть на выходе получить:
8 января - 12 января
15 января -16 января
20 января - 25 января

В голову пришло следующеее решение - разделить каждый промежуток на дни и для каждого из дней промежутка "самый ранний старт - самый поздний финиш" и искать каждый день в каждом из массивов. Потом отбирать дни, присутствующие в меньшем количестве промежутков, чем n. Решение рабочее, но, как мне кажется, при больших количествах промежутков будет слишком энергозатратное. Быть может кто посоветует более красивое решение?

  Ответить  
 
 автор: Sfinks   (03.12.2013 в 21:34)   письмо автору
 
   для: Zdraff   (03.12.2013 в 11:50)
 

Наверно примерно тоже самое.....
<?php
  date_default_timezone_set
('Europe/Moscow');

  
$n 2;
  
$date_intervals = array(
    array(
'start'=>1357761600,'stop'=>1358625600),
    array(
'start'=>1357934400,'stop'=>1358884800),
    array(
'start'=>1357588800,'stop'=>1358193600),
    array(
'start'=>1358280000,'stop'=>1359057600),
  );

  
$days = array();
  
$null_array array_fill(1,365,0);

  foreach(
$date_intervals as $num => $interval){
    
$int_start date('z'$interval['start']);
    
$int_stop  date('z'$interval['stop']);
    
$arr_interval array_fill($int_start+1,$int_stop-$int_start+1,1);
    
$days[$num] = array_replace($null_array,$arr_interval);
  }

  
$result_array = array();
  foreach(
$null_array as $i => $v)
    foreach(
$date_intervals as $j => $v)
      
$result_array[$i] = isset($result_array[$i]) ? $result_array[$i]+$days[$j][$i] : $days[$j][$i];

  
$i 1;
  while(!
$result_array[$i])
    unset(
$result_array[$i++]);

  
$i 365;
  while(!
$result_array[$i])
    unset(
$result_array[$i--]);

  
$start_flag false;
  
$period 1;
  
$result = array();
  foreach(
$result_array as $day => $count)
    if(!
$start_flag && $count <= $n){
      
$result[$period]['start'] = $day;
      
$start_flag true;
    }
    elseif(
$start_flag && $count $n){
      
$result[$period++]['stop'] = $day-1;
      
$start_flag false;
    }

  if(
$start_flag)
    
$result[$period]['stop'] = $day;

  foreach(
$result as $interval)
    echo 
date('j.m.Y'strtotime('1/1 next year +'.($interval['start']-1).' day'))
       . 
' - '
       
date('j.m.Y'strtotime('1/1 next year +'.($interval['stop']-1).' day'))
       . 
"\n";

Что-то захотелось порешать =)

  Ответить  
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования