我想知道如果满足某些特定条件,是否可以将给定的日期范围拆分为单独的日期范围?
我有两个日期开始日期和结束日期。 我正在实施季节性价格系统,如果两个日期范围与现有日期匹配,则需要分割日期。示例:
月 | 开始日期 | 结束日期 |
---|---|---|
十一月 | 2023年11月25日 | 2023年11月30日 |
十二月 | 2023年12月22日 | 2023 年 12 月 31 日 |
一月 | 2024年1月1日 | 2024年5月1日 |
我想要以下结果。
第一个条件:如果我想添加/更新 start_date 01/12/2023 和 end_date 31/12/2023 值,那么结果将是
月 | 开始日期 | 结束日期 |
---|---|---|
十一月 | 2023年11月25日 | 2023年11月30日 |
十二月 | 2023年1月12日 | 2023 年 12 月 31 日 |
一月 | 2024年1月1日 | 2024年5月1日 |
第二个条件:如果我想添加/更新 start_date 05/12/2023 和 end_date 31/12/2023 值,那么结果将是
月 | 开始日期 | 结束日期 |
---|---|---|
十一月 | 2023年11月25日 | 2023年11月30日 |
十二月 | 2023年1月12日 | 2023/04/12 |
十二月 | 2023/05/12 | 2023 年 12 月 31 日 |
一月 | 2024年1月1日 | 2024年5月1日 |
第三个条件:如果我想添加/更新 start_date 10/12/2023 和 end_date 25/12/2023 值,那么结果将是
月 | 开始日期 | 结束日期 |
---|---|---|
十一月 | 2023年11月25日 | 2023年11月30日 |
十二月 | 2023年1月12日 | 2023/04/12 |
十二月 | 2023/05/12 | 2023年9月12日 |
十二月 | 2023年10月12日 | 2023年12月25日 |
十二月 | 2023年12月26日 | 2023 年 12 月 31 日 |
一月 | 2024年1月1日 | 2024年5月1日 |
第四个条件:如果我想添加/更新 start_date 28/12/2023 和 end_date 04/01/2024 值,那么结果将是
月 | 开始日期 | 结束日期 |
---|---|---|
十一月 | 2023年11月25日 | 2023年11月30日 |
十二月 | 2023年1月12日 | 2023/04/12 |
十二月 | 2023年5月12日 | 2023年9月12日 |
十二月 | 2023年10月12日 | 2023年12月25日 |
十二月 | 2023年12月26日 | 2023年12月27日 |
十二月 | 2023年12月28日 | 2024年4月1日 |
一月 | 2024年5月1日 | 2024年5月1日 |
请帮我解决这个问题。
我花了很多时间来编写这个函数
splitDateRanges
,但它的有趣之处在于它需要两个参数 - 现有日期范围的数组和要添加或更新的新日期范围。它检查与现有范围的重叠并相应地进行调整。然后,该函数按开始日期对日期范围的最终数组进行排序。我添加了如何调用函数。
function splitDateRanges($existingRanges, $newRange) {
$newStart = DateTime::createFromFormat('d/m/Y', $newRange['start']);
$newEnd = DateTime::createFromFormat('d/m/Y', $newRange['end']);
$result = [];
foreach ($existingRanges as $range) {
$rangeStart = DateTime::createFromFormat('d/m/Y', $range['start']);
$rangeEnd = DateTime::createFromFormat('d/m/Y', $range['end']);
if ($newStart <= $rangeStart && $newEnd >= $rangeEnd) {
continue;
}
if ($newStart <= $rangeEnd && $newEnd >= $rangeStart) {
if ($newStart > $rangeStart) {
$result[] = ['start' => $range['start'], 'end' => $newStart->modify('-1 day')->format('d/m/Y')];
}
if ($newEnd < $rangeEnd) {
$result[] = ['start' => $newEnd->modify('+1 day')->format('d/m/Y'), 'end' => $range['end']];
}
} else {
$result[] = $range;
}
}
$result[] = $newRange;
// Sort the ranges by start date
usort($result, function($a, $b) {
$dateA = DateTime::createFromFormat('d/m/Y', $a['start']);
$dateB = DateTime::createFromFormat('d/m/Y', $b['start']);
return $dateA <=> $dateB;
});
return $result;
}
// Sample usage
$existingRanges = [
['start' => '25/11/2023', 'end' => '30/11/2023'],
['start' => '22/12/2023', 'end' => '31/12/2023'],
['start' => '01/01/2024', 'end' => '05/01/2024']
];
$newRange = ['start' => '01/12/2023', 'end' => '31/12/2023'];
$updatedRanges = splitDateRanges($existingRanges, $newRange);
foreach ($updatedRanges as $range) {
echo $range['start'] . " - " . $range['end'] . "\n";
}