@Lavrov95

Как разделить диапазон дат на 3 части?

У меня есть диапазон дат $this->startDate, $this->endDate. Например с сентября по декабрь. Как я могу получить дату начала и дату окончания до сентября и после октября.

В этом случае

$startDate = May 1
$endDate = December 31


результат должен быть таким

[
   'before' => 'May 1, September 31',
   'match' =>  'September 1, October 31',
   'after' =>  'October 31, December 31',
]

В этом случае

$startDate = October 14
$endDate = December 15


результат должен быть таким

[
   'before' => null,
   'match' =>  'October 14, October 31',
   'after' =>  'October 31, December 15',
]


В этом случае

$startDate = November 14
$endDate = December 12


результат должен быть таким

[
   'before' => null,
   'match' =>  null,
   'after' =>  'November 14, December 12',
]


И так далее.
  • Вопрос задан
  • 79 просмотров
Пригласить эксперта
Ответы на вопрос 1
sergiks
@sergiks Куратор тега PHP
♬♬
Три зоны на отрезке:
  1. до 1 сентября
  2. между 1 сент. и 31 окт
  3. после 31 окт
Это три варианта начала, три варианта конца (совпадает или после начала)
Из 3x3=9 комбинаций, реально возможны только 6. Дающие 1, 2 или 3 отрезка на выходе:
.
     начало
   ---|---|---
к | 1
о -
н | 2   1
е -
ц | 3   2   1


Для простоты, та же задача с числами. Есть фиксированный отрезок 20..30 (сентрябрь - октябрь). И даются на вход два числа, второе больше первого.

Можно «в лоб» записать логику условиями if - else if - else
треш-код через условия
function ranges(int $a, int $b): array
{
    $start = 20;
    $finish = 30;

    $result = [
        'before' => null,
        'match' => null,
        'after' => null,
    ];

    if ($a < $start) {
        if ($b < $start) {
            $result['before'] = [$a, $b];
        } else {
            $result['before'] = [$a, $start];
            if ($b < $finish) {
                $result['match'] = [$start, $b];
            } else {   
                $result['match'] = [$start, $finish];
                $result['after'] = [$finish, $b];
            }
        }
    } else if ($a < $finish) {
        if ($b < $finish) {
            $result['match'] = [$a, $b];
        } else {
            $result['match'] = [$a, $finish];
            $result['after'] = [$finish, $b];
        }
    } else {
        $result['after'] = [$a, $b];
    }

    return $result;
}

print(json_encode(ranges(5, 25))); // {"before":[5,20],"match":[20,25],"after":null}
Но стоит подумать над более красивым решением. Положить все 4 значения в массив и отсортировать его по возрастанию. 4 значения определяют 3 смежных отрезка. Некоторые из отрезков стоит проигнорировать, если они за рамками входного диапазона.

$arr = [$start, $finish, $a, $b];
sort($arr, SORT_NUMERIC);
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы