Search code examples
phparraysalgorithmmergedate-range

Algorithm to combine date ranges in PHP


I have an array that have start and end date in key/value. eg.

/* formate 'mm/dd/yyyy'=>  'mm/dd/yyyy'*/

$arr = array(
'01/01/2016'=>'01/01/2016',
'01/02/2016'=>'01/02/2016',
'01/03/2016'=>'01/03/2016',


'04/10/2016'=>'04/10/2016',
'04/11/2016'=>'04/11/2016',
'04/12/2016'=>'04/12/2016',


'04/25/2016'=>'04/25/2016',

'04/30/2016'=>'04/30/2016',
'05/01/2016'=>'05/01/2016',
'05/02/2016'=>'05/02/2016' }

)

Here you can see some element have continuously dates. eg. first three element have 04/01 to 04/03 dates. I want that in one element. so new array should be like this >

$arr = array(
    '01/01/2016'=>'01/03/2016',

    '04/10/2016'=>'04/12/2016',

    '04/25/2016'=>'04/25/2016',

    '04/30/2016'=>'05/02/2016'
})

How can do it ?

Thanks


Solution

  • I know there's already an answer but here's my version - spent a bit of time on it so wanted to share!

    As in your example, I'm assuming your original array is in date order and the keys and values are always the same.

    You can use a function to iterate over your original dataset and return an array of grouped dates as follows...

    function group_dates($dates_array) {
    
       // prepare results array
       $result = array();
    
       // take the first date from the submitted array
       $group_start = array_shift($dates_array);
       $timestamp_previous_iteration = strtotime($group_start);
    
       // iterate over remaining values
       foreach ($dates_array as $date) {
          // calculate current iteration's timestamp
          $timestamp_current = strtotime($date);
    
          // calculate timestamp for 1 day before the current value
          $timestamp_yesterday = strtotime('-1 day', $timestamp_current);
    
          if ($timestamp_previous_iteration != $timestamp_yesterday) {
             // create group...
             $result[$group_start] = date('m/d/Y', $timestamp_previous_iteration);
             // ...and store the next group's start date
             $group_start = $date;
          }
    
          // log timestamp for next iteration
          $timestamp_previous_iteration = $timestamp_current;
       }
    
       // add final group
       $result[$group_start] = date('m/d/Y', $timestamp_previous_iteration);
    
       return $result;
    }
    

    You can then use the function as follows,

    $result_array = group_dates($arr);
    

    Feeding the function the array in your example will result in an array as you requested.

    As your dates are formatted MM/DD/YYYY the string will be correctly converted to a unix timestamp by strtotime(). If you were using other date formats you will want to look at the PHP DateTime object.

    Reference
    http://php.net/manual/en/function.strtotime.php
    http://php.net/manual/en/book.datetime.php