douyujun0152 2015-03-11 12:37
浏览 42

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

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.

  • 写回答

1条回答 默认 最新

  • douweilaton2762 2015-03-11 15:16
    关注

    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);
    
    评论

报告相同问题?

悬赏问题

  • ¥15 stm32代码移植没反应
  • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效
  • ¥100 连续两帧图像高速减法
  • ¥15 组策略中的计算机配置策略无法下发
  • ¥15 如何绘制动力学系统的相图
  • ¥15 对接wps接口实现获取元数据
  • ¥20 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)
  • ¥50 mac mini外接显示器 画质字体模糊