Формат даты и времени с минимальной разницей

я найденный это действительно хороший PHP-скрипт, который преобразует любую дату и время в относительную строку, например:

'2013-05-01 00:22:35'  ->  '3 months ago'

Это действительно круто, но я бы хотел «обмануть» функцию, чтобы, даже если дата была, скажем, 20 минут назад, функция возвращает 1 hour ago вместо 20 minutes ago, Таким образом, я хочу обеспечить минимальную разницу в 1 час, даже если разница меньше этой.

Для справки, вот функция.

function time_elapsed_string($datetime, $full = false) {
$now = new DateTime;
$ago = new DateTime($datetime);
$diff = $now->diff($ago);

$diff->w = floor($diff->d / 7);
$diff->d -= $diff->w * 7;

$string = array(
'y' => 'year',
'm' => 'month',
'w' => 'week',
'd' => 'day',
'h' => 'hour',
'i' => 'minute',
's' => 'second',
);
foreach ($string as $k => &$v) {
if ($diff->$k) {
$v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
} else {
unset($string[$k]);
}
}

if (!$full) $string = array_slice($string, 0, 1);
return $string ? implode(', ', $string) . ' ago' : 'just now';
}

Я пробовал много разных вещей, но ничего не получалось.

Как я могу применить минимальную разницу в 1 час?

-1

Решение

После того, как вы выяснили разницу, просто проверьте, составляет ли наибольшая разница только минуты или секунды. Если это так, верните минимум 1 час, который вам требуется.

// here is your foreach loop

// check if less than 1 hour, if so, return that
$keys = array_keys($string);
if ($keys[0] === 'i' || $keys[0] === 's') {
return 'less than 1 hour ago';
}

Попробуйте онлайн!
Я поместил время публикации вопроса в этом примере. Если вы посмотрите на него более чем через 1 час, вам придется изменить контрольный пример на DateTime, который меньше 1 часа назад по времени UTC.

Тестовые случаи. Сейчас UTC 2017-06-10 12:45:00.

time_elapsed_string("2017-06-10 12:11:19"); // less than 1 hour ago
time_elapsed_string("2017-06-10 11:44:00"); // 1 hour ago
time_elapsed_string("2017-06-10 11:44:00", true); // 1 hour, 1 minute ago
time_elapsed_string("2017-06-09 11:45:00", true); // 1 day, 1 hour ago
time_elapsed_string("2017-06-09 11:45:00"); // 1 day ago
1

Другие решения

days: Если объект DateInterval был создан DateTime :: diff (), то это общее количество дней между начальной и конечной датами. В противном случае дни будут ЛОЖНЫМИ. http://php.net/manual/en/class.dateinterval.php

Поскольку мы знаем, что оно не будет ложным, оно будет оцениваться как ложное, только когда 0.

if($diff->days) {
$diff->w = floor($diff->d / 7);
$diff->d -= $diff->w * 7;
} else /* less than a day's difference */ if(!$diff->h && ($diff->i || $diff->s)) /* less than an hour's difference */ {
$diff->h = 1;
$diff->i = 0;
$diff->s = 0;
}
1

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

Код: (демонстрация)

function time_elapsed_string($datetime){
$now=new DateTime;  // current datetime
$ago=new DateTime($datetime);  // user datetime
if($now<$ago){return "Unexpected future datetime value";}
$diff=$now->diff($ago);  // datetime difference
$diff->w=intval(floor($diff->d/7));  // add weeks to diff output
$diff->d-=$diff->w*7;  // reduce days based on weeks calculation
$units=[
'y'=>'year',
'm'=>'month',
'w'=>'week',
'd'=>'day',
'h'=>'hour'
];
$kept_diff=array_intersect_key((array)$diff,$units);  // omit unwanted elements of diff()'s output
if(!max($kept_diff)){  // if y, m, w, d, & h all = 0, show default
return 'default: 1 hour ago';  // inserted "default: " for demo.  Remove in production.
}else{
$diffs=array_filter(array_merge($units,$kept_diff)); // sort by $units order, then omit elements with 0 value
return current($diffs).' '.$units[key($diffs)].(current($diffs)>1?'s':'').' ago'; // return highest unit data in plain English
}
}
echo time_elapsed_string('2017-06-30 02:22:35');  // output: 3 weeks ago
0
По вопросам рекламы [email protected]