Не понимаю, если хочешь просто по дате сортировать по убыванию, то функция
$dates = [];
for ($i = 0; $i < 10; $i++) {
$dates[] = new DateTime('now +' . $i . 'days');
}
usort($dates,function ($a, $b) {
return null
?? ( $b < $a ? -1 : null )
?? ( $b > $a ? 1 : null )
?? 0;
});
var_dump($dates);
делает, что сказали.
====
Если твоя задача сортировать массив по возрастанию РАЗНИЦЫ дат, то нужно так:
$dates = [];
for ($i = 0; $i < 10; $i++) {
$dates[] = [
new DateTime('now +' . $i . 'days'),
new DateTime('now +' . $i+$i . 'days')
];
}
usort($dates,function ($a, $b) {
$diffA = $a[1]->getTimestamp() - $a[0]->getTimestamp();
$diffB = $b[1]->getTimestamp() - $b[0]->getTimestamp();
return null
?? ( $diffA < $diffB ? -1 : null )
?? ( $diffA > $diffB ? 1 : null )
?? 0;
});
var_dump($dates);
Помнить, что на getTimestamp() влияет временная зона. То есть 2 часа по Гринвичу меньше чем 2 часа по Москве, это как бы понятно, просто здесь тоже это важно.
====
Третий вариант, который "возможно" ты хотел получить здесь - как определить пересечение дат:
# опционально, можно донастраивать с помощью знаков `<=` `>=`, чтоб получить "включая-исключая"
# и оператора NOT, чтобы инвертировать.
# можно играться с оператором OR вместо AND, но это уровень 2, тебе не надо
# ещё есть кейз "вне моего промежутка", который можно получить AND двух имеющихся или NOT для "внутри промежутка"
# дай промежутки, которые помещаются в мои рамки
# '2022-01-02 00:00:00' < date_from < date_to < '2022-01-04 00:00:00'
# |----------|
# |----|
# AND `date_from` > '2022-01-02 00:00:00'
# AND `date_to` < '2022-01-04 00:00:00'
# вернуло бы [ '2022-01-03 00:00:00', '2022-01-03 00:00:00' ]
# дай промежутки, которые пересекаются с моим только началом
# '2022-01-02 00:00:00' < date_from < '2022-01-04 00:00:00' < date_to
# |------|
# |------|
# AND `date_from` > '2022-01-02 00:00:00'
# AND `date_to` > '2022-01-04 00:00:00'
# вернуло бы [ '2022-01-03 00:00:00', '2022-01-05 00:00:00' ]
# дай промежутки, которые пересекаются с моим только концом
# date_from < '2022-01-02 00:00:00' < date_to < '2022-01-04 00:00:00'
# |------|
# |------|
# AND `date_from` < '2022-01-02 00:00:00'
# AND `date_to` < '2022-01-04 00:00:00'
# вернуло бы [ '2022-01-01 00:00:00', '2022-01-03 00:00:00' ]
# дай промежутки, которые шире моих рамок (рамка внутри промежутка и потому пересечения нет, пересечение целиком)
# date_from < '2022-01-02 00:00:00' < '2022-01-04 00:00:00' < date_to
# |----|
# |----------|
# AND `date_from` < '2022-01-02 00:00:00'
# AND `date_to` > '2022-01-04 00:00:00'
# вернуло бы [ '2022-01-01 00:00:00', '2022-01-05 00:00:00' ]
Чаще всего задача звучит "найдите все пересечения сразу", чтобы убедится, что туда можно что-то еще добавить и оно не закосячит потом. Поэтому и начинают играться с OR чтобы не писать NOT ( AND / AND / AND / AND )
Вот тут есть уровень 2 и 3 и тд.
www.michurin.net/computer-science/boolean-logic.html