[英]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+1
或from
日期。 無論哪種方式,間隔為from
到無論下一個是減1的一個區間從該值開始直到,直到下一個-1等。
下一步,將原始間隔分類為新間隔。 (並過濾掉那些不包含任何內容的間隔。)
除非性能/存儲是一個非常大的問題,否則這將足夠好,並且無論您的代碼將被繼承的人如何理解。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.