Search code examples
phpalgorithmdaterangeoverlapping-matches

How to calculate date range between multiple date that overlaps


i have many dates that i need to check.

For example:

1 - Start: 1387267200, End: 1387274400
2 - Start: 1387270800, End: 1387275000 
3 - Start: 1387250200, End: 1387273000 
4 - Start: 1387285200, End: 1387288800

What i need is to calculate foreach overlaps the minimum start date and maximum end date.

For the example above, what the algor has to give in output is:

Start1: 1387250200 -> End1: 1387275000.
Start2: 1387285200 -> End2: 1387288800.

How can i do it?

Thanks!


Solution

  • This script looks for overlapped intervals and gets new ones with minimum start date and maximum end date:

    // 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);
    

    Output:

    Array
    (
        [0] => Array
            (
                [0] => 1387250200
                [1] => 1387275000
            )
    
        [1] => Array
            (
                [0] => 1387285200
                [1] => 1387288800
            )
    
    )