Углерод: сравните diffForHumans

Я использую Laravel 5.3 и библиотеку Carbon.

Я пытаюсь сравнить несколько результатов diffForHumans.

Например, у меня есть три отличия:

3 weeks after

7 days after

2 days after

Можно ли сравнить их, чтобы найти минимальное, максимальное и среднее значение?

В этом примере это будет:

  • мин: 2 дня
  • макс: 3 недели
  • в среднем: 10 дней

Я мог бы использовать diff вместо diffForHumans, если это необходимо (и мне кажется, что это будет для получения точных результатов в среднем).

Любые указатели на то, что тоже Google, приветствуются, так как я ничего не могу найти по этой теме, поэтому надеюсь, что ищу не ту вещь.

Спасибо!


person dbr    schedule 14.10.2016    source источник


Ответы (1)


Результат diffForHumans таков, ну, для людей, а люди, как мы знаем, ужасные калькуляторы. Не делай этого.

Учитывая массив \Carbon, вы можете вычислить свои значения следующим образом:

$carbons = [ ... ];
$diffs   = array_map(function ($c) { return $c->diffInSeconds(); }, $carbons);
$max = $carbons[array_search(max($diffs), $diffs)];
$min = $carbons[array_search(min($diffs), $diffs)];
$avg = array_sum($diffs)/count($diffs);

Если вы настаиваете и хотите отсортировать вывод из diffForHumans, вы можете отключить модификатор и числовое значение. После заказа вы можете сдвинуть минимум и вытолкнуть максимум:

function score($c) {
    $scores = [ 1 => 'second', 'minute', 'hour', 'day', 'week', 'month', 'year' ];
    $diff = $c->diffForHumans();
    foreach ($scores as $multiplier => $word) {
        if (false !== strpos($diff, $word)) {
            return $multiplier * (int)$diff;
        }
    }
    return (int)$diff;
}
usort(
    $carbons,
    function ($a, $b) { return score($a) <=> score($b); }
);

Имейте в виду, что вывод diffForHumans может быть краткой формы (например, 'd' вместо 'day'), а также переведен на другой язык. Таким образом, вы должны быть осторожны, манипулируя его выводом.

Примечание: приведенный выше код был скомпилирован только в уме.

person bishop    schedule 15.10.2016
comment
Итак, в основном, используйте diffInSeconds и сравните их (я полагаю, целые числа)? Так просто, и я не вижу практического недостатка, круто. Вы не поверите, обходные пути, которые я пытался реализовать... Я попробую завтра, но, вероятно, это должно сработать, так что спасибо! И один риторический вопрос: почему что-то подобное не реализовано в Carbon? - person dbr; 15.10.2016
comment
Я предполагаю, что Carbon не имеет этой возможности, потому что Carbon, по сути, представляет собой экземпляр времени, тогда как операции, которые вам нужны, представляют собой коллекцию экземпляров времени. - person bishop; 15.10.2016