簡體   English   中英

從日期/時間范圍數組中排除重疊的日期/時間范圍

[英]Exclude date/time ranges from an array of date/time ranges with overlapping

希望你過得很好!!

我有點堅持,我所做的只是在沒有重疊的情況下才起作用,而且無論如何都不確定這是正確的方法。

因此,我當前的實現是合並所有時間(start_time和end_time作為該數組中的不同條目),對其進行排序並刪除重復項(如果有)。

然后,我進入該列表,並檢查它們是否在$ times范圍內,而不在限制范圍內。

所有通過這些條件的對象都將添加到另一個列表中。 最后,我將遍歷該列表“一次2個項目”,並構建最終的時間范圍數組。

代碼: https ://3v4l.org/2elDs(Laravel,使用Collection和Carbon,所以不會在那里運行)

沒有日期/時間重疊的樣本:

$times = [
        [
            'start_time' => '2017-06-26 00:00:00',
            'end_time' => '2017-06-26 05:00:00',
        ],
        [
            'start_time' => '2017-06-26 13:00:00',
            'end_time' => '2017-06-26 18:00:00',
        ]
    ];

$timesToExclude= [
        [
            'start_time' => '2017-06-26 04:00:00',
            'end_time' => '2017-06-26 04:30:00',
        ],
        [
            'start_time' => '2017-06-26 07:00:00',
            'end_time' => '2017-06-26 10:00:00',
        ],
        [
            'start_time' => '2017-06-26 15:00:00',
            'end_time' => '2017-06-26 16:00:00',
        ]
    ];

結果為:

    $result = [
        [
            "start_time" => "2017-06-26 00:00:00",
            "end_time"   => "2017-06-26 04:00:00"
        ], [
            "start_time" => "2017-06-26 04:30:00",
            "end_time"   => "2017-06-26 05:00:00"
        ],
        [
            "start_time" => "2017-06-26 13:00:00",
            "end_time"   => "2017-06-26 15:00:00"
        ],
        [
            "start_time" => "2017-06-26 16:00:00",
            "end_time"   => "2017-06-26 18:00:00"
        ]
    ]

日期/時間重疊的樣本

    $times = [
        [
            'start_time' => '2017-06-26 00:00:00',
            'end_time'   => '2017-06-26 10:00:00',
        ],
        [
            'start_time' => '2017-06-26 05:00:00',
            'end_time'   => '2017-06-26 20:00:00',
        ]
    ];

    $timesToExclude= [
        [
            'start_time' => '2017-06-26 04:00:00',
            'end_time'   => '2017-06-26 04:30:00',
        ],
        [
            'start_time' => '2017-06-26 07:00:00',
            'end_time'   => '2017-06-26 09:00:00',
        ],
        [
            'start_time' => '2017-06-26 15:00:00',
            'end_time'   => '2017-06-26 16:00:00',
        ]
    ];

結果應為:

$result = [
        [
            "start_time" => "2017-06-26 00:00:00",
            "end_time"   => "2017-06-26 04:00:00"
        ], [
            "start_time" => "2017-06-26 04:30:00",
            "end_time"   => "2017-06-26 05:00:00"
        ],
        [
            "start_time" => "2017-06-26 05:00:00",
            "end_time"   => "2017-06-26 07:00:00"
        ],
        [
            "start_time" => "2017-06-26 09:00:00",
            "end_time"   => "2017-06-26 10:00:00"
        ],
        [
            "start_time" => "2017-06-26 10:00:00",
            "end_time"   => "2017-06-26 15:00:00"
        ],
        [
            "start_time" => "2017-06-26 16:00:00",
            "end_time"   => "2017-06-26 20:00:00"
        ]
    ]

任何人都知道正確的算法/偽來處理嗎?

建立共用的配對清單{time; flag} {time; flag} ,其中標記是time_start, time_end, restriction_start or restriction_end

按時間對該列表進行排序。 如果是平局, restr_start標志用作輔助鍵(例如, restr_start應該在time_end之后)。

使$Active=0$Exclude=0

遍歷排序列表。

當您遇到time_start$Active {1}的增量值

當您遇到time_end ,遞減值$Active {2}

當您遇到restriction_start$Exclude {3}的增量值

當您達到restriction_end ,遞減值$Exclude {4}

在以下情況下打開輸出間隔:
{1}: $Active變為1, $Exclude = 0
{4}: $Exclude becomes 0$Active不為零

在以下情況下關閉輸出間隔:
{2} $Active變為0, $Exclude = 0
{3} $Exclude becomes 1$Active則為非零

示例:(不知道復雜條件的確切php語法)

 case $TimeStart:
            $active = $active + 1;
            if ($active=1) and ($exclude=0)
                 $range['start_time'] = $mergedTime['time'];
            break;
 ....
  case $RestrictionEnd:
            $exclude = $exclude - 1;
            if ($exclude=0) and ($active > 0)
                 $range['start_time'] = $mergedTime['time'];
            break;
function excludeOverlaping($disponibilities,$plages) {

        if(count($disponibilities) == 0)
            return $disponibilities;
        if(count($plages) == 0)
            return $disponibilities;

                usort($disponibilities, function($a, $b)
                {
                    return strtotime($a->startDate) - strtotime($b->startDate);
                });
                usort($plages, function($a, $b)
                {
                    return strtotime($a->startDate) - strtotime($b->startDate);
                });

                for($i = 0; $i < count($disponibilities); $i++){
                    for($j=0;$j<count($plages);$j++){
                        $dispo = $disponibilities[$i];
                        if(isset($dispo->exclude)){
                            break;
                        }
                        $plage = $plages[$j]; 
                        if(strtotime($dispo->startDate)>=strtotime($plage->startDate) && strtotime($dispo->endDate)<=strtotime($plage->endDate)){
                                $disponibilities[$i]->exclude = true;

                        }else if( strtotime($dispo->startDate)<strtotime($plage->startDate) && strtotime($dispo->endDate) <= strtotime($plage->endDate) && strtotime($dispo->endDate) > strtotime($plage->startDate)){
                                 $disponibilities[$i]->endDate = $plage->startDate;
                        }else if( strtotime($dispo->startDate)>=strtotime($plage->startDate)  && strtotime($dispo->startDate)<=strtotime($plage->endDate) && strtotime($dispo->endDate) > strtotime($plage->endDate)){
                                 $disponibilities[$i]->startDate = $plage->endDate;
                        }else if( strtotime($dispo->startDate)<strtotime($plage->startDate) &&  strtotime($dispo->endDate) > strtotime($plage->endDate) ){
                              echo "[[[4]]]\n";
                                $tmp = new stdClass();
                                $tmp->startDate = $dispo->startDate;
                                $tmp->endDate = $plage->startDate;
                                $tmp2 = new stdClass();
                                $tmp2->startDate = $plage->endDate;
                                $tmp2->endDate = $dispo->endDate;
                                $disponibilities[$i]->exclude = true;
                                array_push($disponibilities,$tmp);
                                array_push($disponibilities,$tmp2);

                        } 
                    }
                }
                for($i=0;$i<count($disponibilities);$i++){
                    if(isset($disponibilities[$i]->exclude)){
                       array_splice($disponibilities,$i,1);
                       $i--;
                    }
                }
                var_dump($disponibilities);

    }

    $times = array();
    $restrictions = array();
    $obj = new stdClass();
    $obj->startDate = '2017-06-26 00:00:00';
    $obj->endDate =  '2017-06-26 07:00:00';
    array_push($times,$obj);
    $obj = new stdClass();
    $obj->startDate = '2017-06-26 00:00:00';
    $obj->endDate = '2017-06-26 24:00:00';
    array_push($times,$obj);


    $obj = new stdClass();
    $obj->startDate =  '2017-06-26 04:00:00';
    $obj->endDate = '2017-06-26 06:00:00';
    array_push($restrictions,$obj);


    $obj = new stdClass();
    $obj->startDate = '2017-06-26 00:00:00' ;
    $obj->endDate = '2017-06-26 01:00:00';
    array_push($restrictions,$obj);


    excludeOverlaping($times,$restrictions);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM