PHP: working at intervals

    Once upon a time I was faced with a problem, a solution to which I did not find on the Internet. Either the problem is specific and no one has encountered it, or it is primitive, and I used the wrong search procedures. But as for any programmer, it became interesting for me to solve it myself and in my own way ...

    The problem was this: for example, there are 10 tasks running in parallel, each task is divided into subtasks that start at a certain time and their duration is known, we need to add a couple of subtasks to one of the tasks, but first we need to find out if there are any free lengths of time of the duration we need and from how long to how long they last. We have a $ reservArray with data that contains the start and end time of the event for each array element, we also have the start and end time ($ timeArray) of the interval in which we need to check what intervals and what duration we have left if in the given interval all events from the previous array will happen.

    As a result, I needed the function to return the array with free intervals if they are longer than the duration that I pass to the function as the $ duration parameter, an error variable was also added for the start and end times of the event, which I needed at that moment to cut off the intervals not of interest to me (less than 3 sec)



    function getFreeTimeArray($timeArray, $reservArray, $duration, $nullDuration = 3) {
      $resultArray = null;
      $tmpArray[] = $timeArray;
      if (!empty($reservArray) && is_array($reservArray)) {
        foreach ($reservArray as $value) {
          if (!empty($tmpArray))
            foreach ($tmpArray as $tmp_key => $tmp_val) {
              /*
               * reserved line
               * a|============|b
               *
               * time line
               * x|------------|y
               *
               *
               * a = $value['start']
               * b = $value['end']
               *
               * x = $tmp_val['start']
               * y = $tmp_val['end']
               */
              /* if x>a && x>b
               *
               * a|====|b
               *
               * x|------|y
               *
               *
               * OR y
               *
               * a|====|b
               *
               * x|------|y
               *
               *
               * => reserved & time line not intersect
               */
              if (($tmp_val['start'] > $value['start'] && $tmp_val['start'] > $value['end']) 
                  || ($tmp_val['end'] < $value['start'] && $tmp_val['end'] < $value['end'])) {
              } else {
    //reserved & time line intersect
                /* if x<=a && y>=b
                 *
                 * a|====|b
                 *
                 * x|------------|y
                 *
                 */
                if ($tmp_val['start'] <= $value['start'] && $tmp_val['end'] >= $value['end']) {
    //if (a-x) > nullDuration -> save data to array('start'=>x,'end'=>(a-1))
                  if (($value['start'] - $tmp_val['start']) > $nullDuration)
                    $tmpArray[] = array('start' => $tmp_val['start'], 'end' => $value['start'] - 1);
    //if (y-b) > nullDuration -> save data to array('start'=>(b+1),'end'=>y)
                  if (($tmp_val['end'] - $value['end']) > $nullDuration)
                    $tmpArray[] = array('start' => ($value['end'] + 1), 'end' => $tmp_val['end']);
    //delete this time interval
                  unset($tmpArray[$tmp_key]);
                }
                /* if x>=a && y<=b
                 *
                 * a|==========|b
                 *
                 * x|------|y
                 *
                 */
                else if ($tmp_val['start'] >= $value['start'] && $tmp_val['end'] <= $value['end']) {
                  unset($tmpArray[$tmp_key]);
                }
                /* if x>=a && x<=b
                 *
                 * a|=====|b
                 *
                 * x|------------|y
                 *
                 */ else if ($tmp_val['start'] >= $value['start'] && $tmp_val['start'] <= $value['end']) {
                  if (($tmp_val['end'] - $value['end']) > $nullDuration)
                    $tmpArray[] = array('start' => ($value['end'] + 1), 'end' => $tmp_val['end']);
                  unset($tmpArray[$tmp_key]);
                }
                /* if y>=a && y<=b
                 *
                 * a|=====|b
                 *
                 * x|----------|y
                 *
                 */
                else if ($tmp_val['end'] >= $value['start'] && $tmp_val['end'] <= $value['end']) {
                  if (($value['start'] - $tmp_val['start']) > $nullDuration)
                    $tmpArray[] = array('start' => $tmp_val['start'], 'end' => ($value['start'] - 1));
                  unset($tmpArray[$tmp_key]);
                }
              }
            }
        }
      }
    // if result is not null
    // check duration in result data and sort array
      if (!empty($tmpArray)) {
        $tmpArray2 = null;
        foreach ($tmpArray as $val) {
          if ($duration <= ($val['end'] - $val['start']))
            $tmpArray2[$val['start']] = $val;
        }
        ksort($tmpArray2);
        $tmpArray = $tmpArray2;
      }
      $resultArray = $tmpArray;
      return $resultArray;
    }
    


    as a result of passing this function to all the parameters, I received at the output of the time intervals free of events and the duration is longer than the specified time in $ duration;

    if you have questions, ask, but I would like to hear a solution to this problem in other ways. ;) the
    original article in my blog on LJ

    PS if you are minuscule then at least indicate what you didn’t like or if I’m in a bad mood, let’s ruin others as well ...
    A person solves a problem and offers its solution to others, while someone quietly minus him too the mood rises ...

    PS2 Here are the trolls ... at least tell me what you don’t like, why just minus it ??? there are still a couple of solutions in Javascript and PHP, but I don’t even know with such trolls you can only write memoirs here, judging by the evaluation of this topic, you don’t like free solutions here ... at least there are a couple of minuses and minuses than pluses. Does it make sense to publish further?

    PPS, thanks to MikhailEdoshin, a solution was found allowing replacing lines 46-52 with
    if($tmp_val['start'] < $value['end'] && $value['start'] < $tmp_val['end'])
    a special thank you to him!

    Also popular now: