涵盖多个(较小)期间的期间

I have a period of time (travel), e.g. 2015-04-01 - 2015-04-23.

Now, there a several other periods (conditions), e.g.:
2015-03-27 - 2015-04-02
2015-04-04 - 2015-04-18
2015-04-02 - 2015-04-06
2015-04-14 - 2015-04-16
2015-04-23 - 2015-04-30

Here a sketch (black is the travel and red are the condition periods) enter image description here

The goal is to cover the whole travel with conditions without gaps (if possible), overlappings and duplicates.

So my final conditions would look like this:
2015-04-01 - 2015-04-02
2015-04-02 - 2015-04-03
2015-04-03 - 2015-04-18
2015-04-23 - 2015-04-23

And the new sketch: enter image description here

The conditions don't have a specific order when I get them.

My current implementation is pretty huge and buggy. Is there a proven way to do this?

Please note the period dates are examples and the sketches aren't accurate.

Hi here is a "quck" demo ... I hope is clear enough to understand.

Your dates:

$travel = array('from'=>'20150401', 'to'=>'20150423');
$conditions = array(
    'condition_1' => array('from'=>'20150327', 'to'=>'20150402'),
    'condition_2' => array('from'=>'20150404', 'to'=>'20150418'),
    'condition_3' => array('from'=>'20150402', 'to'=>'20150406'),
    'condition_4' => array('from'=>'20150414', 'to'=>'20150416'),
    'condition_5' => array('from'=>'20150423', 'to'=>'20150430')
);

Functions to prepare dates:

// CONVERTS DATES INTO TIME
function get_times($from, $to){
    preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})/', preg_replace("/\D/m", '', $from), $d); $from = @mktime(0, 0, 0, $d[2], $d[3], $d[1]);
    preg_match('/([0-9]{4})([0-9]{2})([0-9]{2})/', preg_replace("/\D/m", '', $to), $d); $to = @mktime(0, 0, 0, $d[2], $d[3], $d[1]);
    $delta = $to-$from;
    return array('from'=>$from, 'to'=>$to, 'delta'=>$delta, 'days'=>$delta/86400);
}

// PARSE MORE DATA INTO $travel & $conditions
function parse_dates($travel, $conditions){
    $travel['times'] = get_times($travel['from'], $travel['to']);
    $applicable_conditions = array();
    foreach($conditions as $i=>$cond){
        if($cond['from']<=$travel['to'] && $cond['to']>=$travel['from']){
            $cond['times'] = get_times($cond['from']<$travel['from']?$travel['from']:$cond['from'], $cond['to']>$travel['to']?$travel['to']:$cond['to']);
            $applicable_conditions[$i] = $cond;
        }
    }
    return array('travel'=>$travel, 'conditions'=>$applicable_conditions);
}

Just an example, you may wanna change this into something more suitable for you:

// (mockup) DISPLAY GRAPHICS
function show_graph($dates){
    $w = 600; $w2 = 100; $h = 30; $bg = '#4682B4'; $col = '#FFFFFF';
    $day = '<div style="display:inline-block; width:'.(round($w/$dates['travel']['times']['days'])-2).'px; border:1px solid '.$col.'; height:'.($h-2).'px;';
    $day_blue = $day.' background-color:'.$bg.';">';
    $day_red = $day.' background-color:red;">';
    $day_empty = $day.' background-color:white;">';
    $day_black = $day.' background-color:black;">';
    $cd = '</div>';
    $days = ''; $cond_days = $day_nocond = array();
    for($i=1; $i<=$dates['travel']['times']['days']; $i++){
        $daytime = $dates['travel']['times']['from']+(86400*$i);
        $days .= $day_blue.$i.$cd;
        $day_havecond[$i] = false;
        foreach($dates['conditions'] as $name=>$cond){
            $is_cond = $daytime>=$cond['times']['from'] && $daytime<=$cond['times']['to'];
            $day_box = $is_cond ? ( $day_havecond[$i] ? $day_black.$i.$cd : $day_red.$i.$cd ) : $day_empty.'&nbsp;'.$cd;
            if($is_cond && !$day_havecond[$i]){ $day_havecond[$i] = true;}
            @$cond_days[$name] .= $day_box;
        }
    }
    $o = '
        <div style="display:inline-block; width:'.$w2.'px;">Travel</div>
        <div style="display:inline-block; color:'.$col.';">'.$days.'</div><br/>';
    foreach($cond_days as $name=>$days){
        $o .= '
        <div style="display:inline-block; width:'.$w2.'px;">'.$name.'</div>
        <div style="display:inline-block; color:'.$col.';">'.$days.'</div><br/>';
    }
    return '<div style="width:'.($w+$w2).'px;">'.$o.'</div>' ;
}

this is how you produce the graphics:

# USAGE
$dates = parse_dates($travel, $conditions);
echo show_graph($dates);

# DEBUG
echo '<hr>'; print_r($dates);