如何编写分割日期范围的逻辑

问题描述 投票:0回答:1

我想知道如果满足某些特定条件,是否可以将给定的日期范围拆分为单独的日期范围?

我有两个日期开始日期结束日期。 我正在实施季节性价格系统,如果两个日期范围与现有日期匹配,则需要分割日期。示例:

开始日期 结束日期
十一月 2023年11月25日 2023年11月30日
十二月 2023年12月22日 2023 年 12 月 31 日
一月 2024年1月1日 2024年5月1日

我想要以下结果。

第一个条件:如果我想添加/更新 start_date 01/12/2023end_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/2023end_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/2023end_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/2023end_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日

请帮我解决这个问题。

php date split
1个回答
0
投票

我花了很多时间来编写这个函数

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";
}
© www.soinside.com 2019 - 2024. All rights reserved.