inavo
@inavo

Как реализовать сортировку по датам?

У меня есть массив вида
[
[date => "06-2020", name => "Vanaya"],
[date => "01-2020", name => "Petya"],
[date => "04-2019", name => "Grizha"],
[date => "011-2019", name => "Oleg"]
]


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

Как это делаю сейчас, довольно топорно, уверен можно сильно упростить
$arItems = [];
$result = [];
$result['created_date_min'] = 'now';
$result['created_date_max'] = 0;

foreach ($arItems['item'] as &$elem) {
    // unix time
    $date = strtotime($elem['created_date']);

    // получим перебором самую маленькую и большую даты
    if ((int)strtotime($result['created_date_min']) > (int)$date) {
        $result['created_date_min'] = date('d.m.Y', $date);
    }
    if ((int)strtotime($result['created_date_max']) < (int)$date) {
        $result['created_date_max'] = date('d.m.Y', $date);
    }

    // массив вида [дата => количество элементов]
    $result['count_dates'][date('m.Y', $date)]++;
}

// пустой помесячный массив 
$result['by_month'] = getMonth($result['created_date_min'], $result['created_date_max']);

for ($i = 0, $count = count($result['by_month']); $i < $count; $i++) {
    $date = $result['by_month'][$i];

    $result['points'][$i] = [
        'date' => $date,
        'count' => (int)$result['count_dates'][$date]
    ];
}


function getMonth($min, $max)
{
    $res = [];

    $min = new DateTime($min);
    $max = new DateTime($max);

    $diff = $max->diff($min);

    // если месяцев больше 12ти
    $diff = $diff->m + 12 * $diff->y;

    for ($i = 0; $i < $diff; $i++) {
        $nowTemp = new DateTime();
        $dateMonth = $nowTemp->sub(new DateInterval('P' . $i . 'M'));

        $dateMonth = $dateMonth->format('m.Y');

        $res[] = $dateMonth;
    }

    return $res;
}
  • Вопрос задан
  • 81 просмотр
Пригласить эксперта
Ответы на вопрос 2
Я бы придумал что-нибудь как обойти эту историю. Но на вскидку - надо дату делать от года, то есть "2020-06" ну и какую-то проверку делать, если циферки месяца (можно получить их легко) идут не согласно порядку 1-2-3-...-12
Ответ написан
<?php

function prepareDataForDashboard(array $data, DateTimeInterface $minDate, DateTimeInterface $maxDate): array {
    $dateInterval = new DateInterval('P1D');
    $datePeriod   = new DatePeriod($minDate, $dateInterval, $maxDate);

    $result = [];

    foreach ($datePeriod as $item) {
        $date = $item->format('m-Y');

        $result[$date] = [
            'date' => $date,
            'name' => null,
        ];
    }

    foreach ($data as $item) {
        $date = DateTimeImmutable::createFromFormat('m-Y', $item['date']);
        $date = $date->format('m-Y');

        $result[$date] = $item;
    }

    return array_values($result);
}


$data = [
    ['date' => '06-2020', 'name' => 'Vanaya'],
    ['date' => '01-2020', 'name' => 'Petya'],
    ['date' => '04-2019', 'name' => 'Grizha'],
    ['date' => '11-2019', 'name' => 'Oleg'],
];

$minDate = new DateTimeImmutable('01.04.2019');
$maxDate = new DateTimeImmutable('01.06.2020');

$result = prepareDataForDashboard($data, $minDate, $maxDate);

print_r($result);
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы
YCLIENTS Москва
от 200 000 до 350 000 ₽
Ведисофт Екатеринбург
от 25 000 ₽
ИТЦ Аусферр Магнитогорск
от 100 000 до 160 000 ₽