簡體   English   中英

PHP-將日期范圍拆分為多個部分

[英]php - Split a date range into pieces

我需要將范圍內的日期范圍數組除以其他日期范圍。

例如,我的起始數組可以是:

$items = array(
    array(
        'ID' => 2,
        'from' => new DateTime('2016-07-01'),
        'to' => new DateTime('2016-07-19')
    ),
    array(
        'ID' => 3,
        'from' => new DateTime('2016-07-15'),
        'to' => new DateTime('2016-07-29')
    ),
    array(
        'ID' => 1,
        'from' => new DateTime('2016-01-01'),
        'to' => new DateTime('2016-12-31')
    ),
    array(
        'ID' => 4,
        'from' => new DateTime('2016-06-15'),
        'to' => new DateTime('2016-07-07')
    ),
    array(
        'ID' => 5,
        'from' => new DateTime('2016-07-05'),
        'to' => new DateTime('2016-07-17')
    ),
);

而且我期望的結果是一個包含所有期間的數組,並引用了item的ID,如下所示:

$result = array(
    array(
        'from' => new DateTime('2016-01-01'),
        'to' => new DateTime('2016-06-14'),
        'ids' => array(
            1
        )
    ),
    array(
        'from' => new DateTime('2016-06-15'),
        'to' => new DateTime('2016-06-30'),
        'ids' => array(
            1, 4
        )
    ),
    array(
        'from' => new DateTime('2016-07-01'),
        'to' => new DateTime('2016-07-04'),
        'ids' => array(
            1, 2, 4
        )
    ),
    array(
        'from' => new DateTime('2016-07-05'),
        'to' => new DateTime('2016-07-07'),
        'ids' => array(
            1, 2, 4, 5
        )
    ),
    array(
        'from' => new DateTime('2016-07-08'),
        'to' => new DateTime('2016-07-14'),
        'ids' => array(
            1, 2, 5
        )
    ),
    array(
        'from' => new DateTime('2016-07-15'),
        'to' => new DateTime('2016-07-17'),
        'ids' => array(
            1, 2, 3, 5
        )
    ),
    array(
        'from' => new DateTime('2016-07-18'),
        'to' => new DateTime('2016-07-19'),
        'ids' => array(
            1, 2, 3
        )
    ),
    array(
        'from' => new DateTime('2016-07-20'),
        'to' => new DateTime('2016-07-29'),
        'ids' => array(
            1, 3
        )
    ),
    array(
        'from' => new DateTime('2016-07-30'),
        'to' => new DateTime('2016-12-31'),
        'ids' => array(
            1
        )
    ),
);

你能幫助我嗎? 謝謝

更新現在我已經嘗試按“ from”項和循環項以及范圍數組對數組進行排序。 這是我的代碼:

usort($items, function($a, $b) {
    if ($a['from'] == $b['from']) {
        return 0;
    }
    if ($a['from'] < $b['from']) {
        return -1;
    }
    return 1;
});

$ranges = array(
    array(
        'from' => clone $items[0]['from'],
        'to' => clone $items[0]['to'],
        'ids' => array($items[0]['ID'])
    )
);
unset($items[0]);
foreach($items as $item) {
    foreach($ranges as $k => $range) {
        if (($range['from'] <= $item['from']) || ($range['to'] > $item['to'])) {
            if ($range['from'] <= $item['from']) {
                $clone = $range;
                $clone['from'] = $item['from'];
                $clone['to'] = clone $item['to'];
                $clone['ids'][] = $item['ID'];

                $ranges[$k]['to'] = clone $item['from'];
                $ranges[$k]['to']->modify('-1 day');
                $ranges[] = $clone;
            }

            if ($range['to'] > $item['to']) {
                $clone = $range;
                $clone['from'] = clone $item['to'];
                $clone['from']->modify('+1 day');
                $clone['to'] = clone $range['to'];
                $ranges[] = $clone;
            }
        }
    }
}

但是結果是一個數組,需要更多結果。 謝謝您的幫助。

老實說,我會將其設置為一個多步驟的過程……盡管我確定可以一步完成,但是代碼可能會(而且可能已經)令人困惑(因為我不理解您的代碼)在幾秒鍾內):

我將從一遍開始,將所有to+1日期和所有from日期存儲到一個數組中並對其進行排序。

現在您有了間隔。 第一項是from ,且必須與最小from日期。 下一個日期可以是to+1from日期。 無論哪種方式,間隔為from到無論下一個是減1的一個區間從該值開始直到,直到下一個-1等。

下一步,將原始間隔分類為新間隔。 (並過濾掉那些不包含任何內容的間隔。)

除非性能/存儲是一個非常大的問題,否則這將足夠好,並且無論您的代碼將被繼承的人如何理解。

暫無
暫無

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

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