Порядок сбора объектов по возрастанию дат с текущей даты - PullRequest
3 голосов
/ 08 октября 2019

В PHP у меня есть массив объектов, и мне нужно отсортировать его, начиная с самой последней даты с сегодняшнего дня и заканчивая выходом. Даты хранятся в виде строк только с месяцем и днем.

Я могу использовать usort с функцией, как показано ниже, чтобы отсортировать ее в хронологическом порядке, но я борюсь с тем, как отсортировать ее по сравнению с сегодняшней датой.

function date_sort($a, $b) {
  return strtotime($a->bday) - strtotime($b->bday);
}

usort($users, "date_sort");

Исходный массив выглядиткак это:

$users = array(
    [0] => stdClass Object
        (
            [name] => Tim
            [bday] => September 13
        )
    [1] => stdClass Object
        (
            [name] => Scott
            [bday] => November 8
        )
    [2] => stdClass Object
        (
            [name] => Bob
            [bday] => October 13
        )
    [3] => stdClass Object
        (
            [name] => Dan
            [bday] => February 2
        )
    [4] => stdClass Object
        (
            [name] => Jack
            [bday] => July 11
        ) 
)

Если сегодня 8 октября, мне нужно, чтобы отсортированный массив выглядел так:

$users = array(
    [0] => stdClass Object
        (
            [name] => Bob
            [bday] => October 13
        )
    [1] => stdClass Object
        (
            [name] => Scott
            [bday] => November 8
        )
    [2] => stdClass Object
        (
            [name] => Dan
            [bday] => February 2
        )
    [3] => stdClass Object
        (
            [name] => Jack
            [bday] => July 11
        ) 
    [4] => stdClass Object
        (
            [name] => Tim
            [bday] => September 13
        )
)

Ответы [ 2 ]

2 голосов
/ 08 октября 2019

Внутри функции сравнения вы сравниваете метки времени от strtotime() с меткой времени для текущей даты. Поскольку по умолчанию он будет использовать текущий год для дней без лет, если отметка времени меньше текущей отметки, добавьте год. Сделайте это для $a->bday и $ b-> bday`. Затем сделайте свое сравнение.

function date_sort($a, $b) {
    if(strtotime($a->bday) < strtotime(date("Y-m-d")))
    {
        $adate = strtotime(date("Y-m-d", strtotime($a->bday)) . " +1 year");
    }
    else
    {
        $adate = strtotime($a->bday);
    }
    if(strtotime($b->bday) < strtotime(date("Y-m-d")))
    {
        $bdate = strtotime(date("Y-m-d", strtotime($b->bday)) . " +1 year");
    }
    else
    {
        $bdate = strtotime($b->bday);
    }
  return $adate - $bdate;
}

DEMO

Другой вариант (возможно, с точки зрения производительности) - перебрать массив, сравнить с текущим днем,при необходимости измените даты, а затем вызовите usort() в настроенном массиве.

0 голосов
/ 08 октября 2019

Функция сортировки может выглядеть примерно так:

$now = new DateTime();

usort($users, function($a, $b) use ($now) {
    $aDate = new DateTime($a->bday);
    if ($aDate < $now) {
        $aDate->add(new DateInterval('P1Y'));
    }

    $bDate = new DateTime($b->bday);
    if ($bDate < $now) { 
        $bDate->add(new DateInterval('P1Y'));
    }

    return $aDate > $bDate;  
});

Конечно, преобразование в DateTime объекты может выполняться один раз в отдельном цикле while, чтобы уменьшить избыточность.

Образец скрипки https://3v4l.org/u3U80.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...