PHP Как найти время, истеченное с даты? [Дубликат
-
04-10-2019 - |
Вопрос
Этот вопрос уже имеет ответ здесь:
Как найти время, истеченное с даты 2010-04-28 17:25:43
, финал введите текст должен быть как xx Minutes Ago
/xx Days Ago
Решение
Большинство ответов, кажется, сосредоточены вокруг преобразования даты из строки к времени. Кажется, вы в основном думаете о том, чтобы получить дату в формате «5 дней назад» и т. Д. .. Верно?
Вот как я бы пошел делать это:
$time = strtotime('2010-04-28 17:25:43');
echo 'event happened '.humanTiming($time).' ago';
function humanTiming ($time)
{
$time = time() - $time; // to get the time since that moment
$time = ($time<1)? 1 : $time;
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
foreach ($tokens as $unit => $text) {
if ($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
return $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');
}
}
Я не проверил это, но он должен работать.
Результат будет выглядеть как
event happened 4 days ago
или
event happened 1 minute ago
ваше здоровье
Другие советы
Хотите поделиться функцией PHP, которая приводит к грамматически правильным Facebook, например, для читаемого времени для чтения человека.
Пример:
echo get_time_ago(strtotime('now'));
Результат:
менее 1 минуты назад
function get_time_ago($time_stamp)
{
$time_difference = strtotime('now') - $time_stamp;
if ($time_difference >= 60 * 60 * 24 * 365.242199)
{
/*
* 60 seconds/minute * 60 minutes/hour * 24 hours/day * 365.242199 days/year
* This means that the time difference is 1 year or more
*/
return get_time_ago_string($time_stamp, 60 * 60 * 24 * 365.242199, 'year');
}
elseif ($time_difference >= 60 * 60 * 24 * 30.4368499)
{
/*
* 60 seconds/minute * 60 minutes/hour * 24 hours/day * 30.4368499 days/month
* This means that the time difference is 1 month or more
*/
return get_time_ago_string($time_stamp, 60 * 60 * 24 * 30.4368499, 'month');
}
elseif ($time_difference >= 60 * 60 * 24 * 7)
{
/*
* 60 seconds/minute * 60 minutes/hour * 24 hours/day * 7 days/week
* This means that the time difference is 1 week or more
*/
return get_time_ago_string($time_stamp, 60 * 60 * 24 * 7, 'week');
}
elseif ($time_difference >= 60 * 60 * 24)
{
/*
* 60 seconds/minute * 60 minutes/hour * 24 hours/day
* This means that the time difference is 1 day or more
*/
return get_time_ago_string($time_stamp, 60 * 60 * 24, 'day');
}
elseif ($time_difference >= 60 * 60)
{
/*
* 60 seconds/minute * 60 minutes/hour
* This means that the time difference is 1 hour or more
*/
return get_time_ago_string($time_stamp, 60 * 60, 'hour');
}
else
{
/*
* 60 seconds/minute
* This means that the time difference is a matter of minutes
*/
return get_time_ago_string($time_stamp, 60, 'minute');
}
}
function get_time_ago_string($time_stamp, $divisor, $time_unit)
{
$time_difference = strtotime("now") - $time_stamp;
$time_units = floor($time_difference / $divisor);
settype($time_units, 'string');
if ($time_units === '0')
{
return 'less than 1 ' . $time_unit . ' ago';
}
elseif ($time_units === '1')
{
return '1 ' . $time_unit . ' ago';
}
else
{
/*
* More than "1" $time_unit. This is the "plural" message.
*/
// TODO: This pluralizes the time unit, which is done by adding "s" at the end; this will not work for i18n!
return $time_units . ' ' . $time_unit . 's ago';
}
}
Я думаю, у меня есть функция, которая должна делать то, что вы хотите:
function time2string($timeline) {
$periods = array('day' => 86400, 'hour' => 3600, 'minute' => 60, 'second' => 1);
foreach($periods AS $name => $seconds){
$num = floor($timeline / $seconds);
$timeline -= ($num * $seconds);
$ret .= $num.' '.$name.(($num > 1) ? 's' : '').' ';
}
return trim($ret);
}
Просто примените его к разнице между time()
а также strtotime('2010-04-28 17:25:43')
как так:
print time2string(time()-strtotime('2010-04-28 17:25:43')).' ago';
Если вы используете класс PHP DateTime, вы можете использовать:
function time_ago(Datetime $date) {
$time_ago = '';
$diff = $date->diff(new Datetime('now'));
if (($t = $diff->format("%m")) > 0)
$time_ago = $t . ' months';
else if (($t = $diff->format("%d")) > 0)
$time_ago = $t . ' days';
else if (($t = $diff->format("%H")) > 0)
$time_ago = $t . ' hours';
else
$time_ago = 'minutes';
return $time_ago . ' ago (' . $date->format('M j, Y') . ')';
}
Быть предупрежденным, большинство математически рассчитанных примеров имеют жесткий предел 2038-01-18
Даты и не будут работать с вымышленными датами.
Как было отсутствие DateTime
а также DateInterval
На основе примеров я хотел обеспечить многоцелевую функцию, которая удовлетворяет потребности ОП и других, желающих составных периодов, таких как 1 month 2 days ago
. Отказ Наряду с кучей других случаев использования, такие как предел для отображения даты вместо прошедшего времени или фильтрованию порций истеченного результата времени.
Кроме того, большинство примеров предполагают прошедшие с текущего времени, где функция ниже позволяет его переопределить с нужной датой окончания.
/**
* multi-purpose function to calculate the time elapsed between $start and optional $end
* @param string|null $start the date string to start calculation
* @param string|null $end the date string to end calculation
* @param string $suffix the suffix string to include in the calculated string
* @param string $format the format of the resulting date if limit is reached or no periods were found
* @param string $separator the separator between periods to use when filter is not true
* @param null|string $limit date string to stop calculations on and display the date if reached - ex: 1 month
* @param bool|array $filter false to display all periods, true to display first period matching the minimum, or array of periods to display ['year', 'month']
* @param int $minimum the minimum value needed to include a period
* @return string
*/
function elapsedTimeString($start, $end = null, $limit = null, $filter = true, $suffix = 'ago', $format = 'Y-m-d', $separator = ' ', $minimum = 1)
{
$dates = (object) array(
'start' => new DateTime($start ? : 'now'),
'end' => new DateTime($end ? : 'now'),
'intervals' => array('y' => 'year', 'm' => 'month', 'd' => 'day', 'h' => 'hour', 'i' => 'minute', 's' => 'second'),
'periods' => array()
);
$elapsed = (object) array(
'interval' => $dates->start->diff($dates->end),
'unknown' => 'unknown'
);
if ($elapsed->interval->invert === 1) {
return trim('0 seconds ' . $suffix);
}
if (false === empty($limit)) {
$dates->limit = new DateTime($limit);
if (date_create()->add($elapsed->interval) > $dates->limit) {
return $dates->start->format($format) ? : $elapsed->unknown;
}
}
if (true === is_array($filter)) {
$dates->intervals = array_intersect($dates->intervals, $filter);
$filter = false;
}
foreach ($dates->intervals as $period => $name) {
$value = $elapsed->interval->$period;
if ($value >= $minimum) {
$dates->periods[] = vsprintf('%1$s %2$s%3$s', array($value, $name, ($value !== 1 ? 's' : '')));
if (true === $filter) {
break;
}
}
}
if (false === empty($dates->periods)) {
return trim(vsprintf('%1$s %2$s', array(implode($separator, $dates->periods), $suffix)));
}
return $dates->start->format($format) ? : $elapsed->unknown;
}
Одно следует отметить - извлеченные интервалы для прилагаемых значений фильтра не переносятся в следующий период. Фильтр просто отображает результирующее значение прилагаемых периодов и не пересчитывает периоды для отображения только желаемого фильтра.
Применение
Для ОП потребность в демонстрации высочайшего периода (по состоянию на 2015-02-24).
echo elapsedTimeString('2010-04-26');
/** 4 years ago */
Отображать составные периоды и подайте пользовательскую дату окончания (Обратите внимание на отсутствие поставленных временных и вымышленных дат).
echo elapsedTimeString('1920-01-01', '2500-02-24', null, false);
/** 580 years 1 month 23 days ago */
Отображать результат отфильтрованных периодов (упорядочение массива не имеет значения).
echo elapsedTimeString('2010-05-26', '2012-02-24', null, ['month', 'year']);
/** 1 year 8 months ago */
Чтобы отобразить дату начала в прилагаемом формате (по умолчанию YMD), если предел достигнут.
echo elapsedTimeString('2010-05-26', '2012-02-24', '1 year');
/** 2010-05-26 */
Есть куча других случаев использования. Он также может быть легко адаптирован для принятия временных метров Unix и / или DateInterval объектов для начала, конца или предельных аргументов.
Мне понравился код Митуна, но я немного настроил его, чтобы он дал больше разумных ответов.
function getTimeSince($eventTime)
{
$totaldelay = time() - strtotime($eventTime);
if($totaldelay <= 0)
{
return '';
}
else
{
$first = '';
$marker = 0;
if($years=floor($totaldelay/31536000))
{
$totaldelay = $totaldelay % 31536000;
$plural = '';
if ($years > 1) $plural='s';
$interval = $years." year".$plural;
$timesince = $timesince.$first.$interval;
if ($marker) return $timesince;
$marker = 1;
$first = ", ";
}
if($months=floor($totaldelay/2628000))
{
$totaldelay = $totaldelay % 2628000;
$plural = '';
if ($months > 1) $plural='s';
$interval = $months." month".$plural;
$timesince = $timesince.$first.$interval;
if ($marker) return $timesince;
$marker = 1;
$first = ", ";
}
if($days=floor($totaldelay/86400))
{
$totaldelay = $totaldelay % 86400;
$plural = '';
if ($days > 1) $plural='s';
$interval = $days." day".$plural;
$timesince = $timesince.$first.$interval;
if ($marker) return $timesince;
$marker = 1;
$first = ", ";
}
if ($marker) return $timesince;
if($hours=floor($totaldelay/3600))
{
$totaldelay = $totaldelay % 3600;
$plural = '';
if ($hours > 1) $plural='s';
$interval = $hours." hour".$plural;
$timesince = $timesince.$first.$interval;
if ($marker) return $timesince;
$marker = 1;
$first = ", ";
}
if($minutes=floor($totaldelay/60))
{
$totaldelay = $totaldelay % 60;
$plural = '';
if ($minutes > 1) $plural='s';
$interval = $minutes." minute".$plural;
$timesince = $timesince.$first.$interval;
if ($marker) return $timesince;
$first = ", ";
}
if($seconds=floor($totaldelay/1))
{
$totaldelay = $totaldelay % 1;
$plural = '';
if ($seconds > 1) $plural='s';
$interval = $seconds." second".$plural;
$timesince = $timesince.$first.$interval;
}
return $timesince;
}
}
Чтобы улучшить ответ на @arnorhs, я добавил в способности иметь более точный результат, поэтому если вы хотели, например, несколько месяцев, дней и часов, так как пользователь присоединился.
Я добавил новый параметр, чтобы позволить вам указать количество точек точности, которое вы хотите вернуть.
function get_friendly_time_ago($distant_timestamp, $max_units = 3) {
$i = 0;
$time = time() - $distant_timestamp; // to get the time since that moment
$tokens = [
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
];
$responses = [];
while ($i < $max_units && $time > 0) {
foreach ($tokens as $unit => $text) {
if ($time < $unit) {
continue;
}
$i++;
$numberOfUnits = floor($time / $unit);
$responses[] = $numberOfUnits . ' ' . $text . (($numberOfUnits > 1) ? 's' : '');
$time -= ($unit * $numberOfUnits);
break;
}
}
if (!empty($responses)) {
return implode(', ', $responses) . ' ago';
}
return 'Just now';
}
Один вариант, который будет работать с любой версией PHP, это делать то, что уже было предложено, что это что-то подобное:
$eventTime = '2010-04-28 17:25:43';
$age = time() - strtotime($eventTime);
Это даст вам возраст в считанные секунды. Оттуда вы можете показать это, однако, что вы хотите.
Однако одна проблема с таким подходом заключается в том, что она не учитывает время сдвигов времени на DST. Если это не проблема, то пойти на это. В противном случае вы, вероятно, захотите использовать Diff () Метод в классе DateTime. Отказ К сожалению, это только опция, если вы по меньшей мере, PHP 5.3.
Используйте это, и вы можете получить
$previousDate = '2013-7-26 17:01:10';
$startdate = new DateTime($previousDate);
$endDate = new DateTime('now');
$interval = $endDate->diff($startdate);
echo$interval->format('%y years, %m months, %d days');
Считайте этоhttp://ca2.php.net/manual/en/dateInterval.format.php.
Попробуйте одну из этих репо
https://github.com/salavert/ime-ag-in-words.
https://github.com/jimmiw/php-ime-ago.
Я только что начал использовать последнее, делает трюк, но никакой ответственности в стиле стека в точной дате, когда рассматриваемая дата слишком далеко, и не есть поддержка для будущих дат - и API немного фанк, но, по крайней мере, это Работает, казалось бы, безупречно и поддерживается ...
Преобразовать [Saved_date] на Timestamp. Получить текущий момент времени.
Текущий момент времени - [Saved_date] Timestamp.
Затем вы можете отформатировать его с датой ();
Вы можете нормально преобразовать большинство форматов даты на метки времени с функцией STRTOTIME ().
Узнать время, прошедшее, я обычно использую time()
вместо date()
и отформатированные метки времени. Затем получите разницу между последним значенным и более ранним значением и форматом соответственно. time()
по-разному не замена для date()
Но это полностью помогает при расчете прошедшего времени.
пример:
Значение time()
выглядит что-то вроде этого 1274467343
увеличивает каждую секунду. Так что вы могли бы иметь $erlierTime
со значением 1274467343
а также $latterTime
со значением 1274467500
, Тогда просто сделать $latterTime - $erlierTime
Чтобы получить время, прошедшее в считанные секунды.
Написал свой собственный
function getElapsedTime($eventTime)
{
$totaldelay = time() - strtotime($eventTime);
if($totaldelay <= 0)
{
return '';
}
else
{
if($days=floor($totaldelay/86400))
{
$totaldelay = $totaldelay % 86400;
return $days.' days ago.';
}
if($hours=floor($totaldelay/3600))
{
$totaldelay = $totaldelay % 3600;
return $hours.' hours ago.';
}
if($minutes=floor($totaldelay/60))
{
$totaldelay = $totaldelay % 60;
return $minutes.' minutes ago.';
}
if($seconds=floor($totaldelay/1))
{
$totaldelay = $totaldelay % 1;
return $seconds.' seconds ago.';
}
}
}
Здесь я использую пользовательскую функцию для поиска времени, прошедшего с даты.
echo datetodays ('2013-7-26 17:01:10'); Функция DateTodays ($ d) {$ date_start = $ d; $ date_end = дата ('ymd h: i: s'); определить («второй», 1); определить («минуту», второй * 60); определить (час ', минута * 60); Определите («день», час * 24); Определите («неделя», день * 7); $ t1 = Strtotime ($ date_start); $ t2 = Strtotime ($ date_end); Если ($ t1> $ t2) {$ diffrence = $ t1 - $ t2; } else {$ diffrence = $ t2 - $ t1; } // echo "
". $ date_end". ". $ date_start". «. $ diffrence; $ результаты ['major'] = массив (); // целое число, представляющее больший номер в дату временных отношений $ Results1 = Array (); $ string = ''; $ результаты ['major'] недели] = пол ($ Defrence / неделя); $ Результаты [«Основные»] [«дни»] = пол ($ Teffrence / день); $ результаты [«Основные»] [«часы»] = пол ($ Teffrence / Час); $ результаты [«основные»] [«минуты»] = этаж ($ DIFFRENCE / MING); $ РЕЗУЛЬТАТЫ [«Основные»] [«секунды»] = пол ($ diffrence / resty); // print_r ( $ Результаты); // логика: // Шаг 1: Возьмите основной результат и преобразоруйте его в Shar Seconds (это будет меньше количества секунд разницы) // EX: $ REVISTORY = ($ РЕЗВЕЛИТЬСЯ ] [«недели] * неделя) // Шаг 2: вычесть меньшее число (результат) из разницы (общее время) // ex: $ minor_result = $ разница - $ результат // Шаг 3: Возьмите в результате в результате секунды и преобразуйте его в незначительный формат // ex: этаж ($ minor_result / день) $ Результаты1 ['недели] = пол ($ diffrence / неделя); $ Results1 [' дни] = пол (( ($ результаты [«основные»] [«недели] * неделя)) / ДЕНЬ)); $ Results1 [«Часы»] = пол ((($ Diffrence - ($ результаты [«Основные»] [«дни»] * день)) / час)); $ Results1 [«минуты»] = этаж ((($ diffrence - ($ результаты [«основные»] [«часы»] * час)) / мин)); $ Results1 [«секунды»] = этаж ((($ diffrence - ($ результаты [«основные»] [«минуты»] * минута)) / секунду)); // print_r ($ Results1); Если ($ Results1 [«недели]! = 0 && $ РЕЗУЛЬТАТЫ1 [« Дни »] == 0) {Если ($ Results1 [« Недели] == 1) {$ String = $ Resultsex1 ['недели]. ' неделю назад'; } else {Если ($ Results1 ['недели] == 2) {$ String = $ Results1 [' недели]. «недели назад»; } else {$ string = '2 недель назад'; }}} elseif ($ Results1 [«недели]! = 0 && $ Results1 [« Дни »]! = 0) {Если ($ Results1 ['недели] == 1) {$ String = $ Results1 [' недели ']. ' неделю назад'; } else {Если ($ Results1 ['недели] == 2) {$ String = $ Results1 [' недели]. «недели назад»; } else {$ string = '2 недель назад'; }}} elseif ($ Results1 ['недели] == 0 && $ Results1 [«Дни»]! = 0) {Если ($ Results1 [' Days '] == 1) {$ String = $ Results1 [' Дни ']. «день назад»; } else {$ String = $ Результаты1 [«Дни»]. ' дней назад'; }} evelif ($ Results1 ['Дни']! = 0 && $ Результаты1 [«Часы»]! = 0) {$ String = $ Результаты1 [«Дни»]. «день и». $ Результаты1 [«Часы»]. ' несколько часов назад'; } Evelif ($ Results1 ['дни] == 0 && $ Results1 [«Часы»]! = 0) {Если ($ Results1 [«Часы] == 1) {$ String = $ Results1 [« Часы »] Отказ ' час назад'; } else {$ String = $ Results1 [«Часы»]. ' несколько часов назад'; }} evellif ($ Results1 [«Часы»]! = 0 && $ РЕЗУЛЬТАТЫ1 [«минуты»]! = 0) {$ String = $ Результаты1 [«Часы»]. «Час и». $ Результаты1 [«минуты»]. ' несколько минут назад'; } evellif ($ Results1 [«Часы»] == 0 && $ Results1 [«минуты»]! = 0) {Если ($ Results1 [«минуты] == 1) {$ String = $ Results1 [« минуты »] Отказ «минута назад»; } else {$ String = $ Результаты1 [«минуты»]. ' несколько минут назад'; }} elseif ($ Results1 [«минуты»]! = 0 && $ РЕЗУЛЬТАТЫ1 [«секунды»]! = 0) {$ String = $ Результаты1 [«минуты»]. «минута и». $ Results1 [«секунды». «секунд назад»; } elseif ($ Results1 ['minks'] == 0 && $ Результаты1 [«секунды»]! = 0) {Если ($ Results1 ['Second'] == 1) {$ String = $ Results1 ['Second's] Отказ «Во-вторых назад»; } else {$ String = $ Results1 ['Second's]. «секунд назад»; }} Вернуть $ строку; }?>
Вы можете получить функцию для этого непосредственно формы WordPress Core Files Посмотрите здесь
http://core.trac.wordpress.org/browser/tags/3.6/wp-includes/formatting.php#l2121.
function human_time_diff( $from, $to = '' ) {
if ( empty( $to ) )
$to = time();
$diff = (int) abs( $to - $from );
if ( $diff < HOUR_IN_SECONDS ) {
$mins = round( $diff / MINUTE_IN_SECONDS );
if ( $mins <= 1 )
$mins = 1;
/* translators: min=minute */
$since = sprintf( _n( '%s min', '%s mins', $mins ), $mins );
} elseif ( $diff < DAY_IN_SECONDS && $diff >= HOUR_IN_SECONDS ) {
$hours = round( $diff / HOUR_IN_SECONDS );
if ( $hours <= 1 )
$hours = 1;
$since = sprintf( _n( '%s hour', '%s hours', $hours ), $hours );
} elseif ( $diff < WEEK_IN_SECONDS && $diff >= DAY_IN_SECONDS ) {
$days = round( $diff / DAY_IN_SECONDS );
if ( $days <= 1 )
$days = 1;
$since = sprintf( _n( '%s day', '%s days', $days ), $days );
} elseif ( $diff < 30 * DAY_IN_SECONDS && $diff >= WEEK_IN_SECONDS ) {
$weeks = round( $diff / WEEK_IN_SECONDS );
if ( $weeks <= 1 )
$weeks = 1;
$since = sprintf( _n( '%s week', '%s weeks', $weeks ), $weeks );
} elseif ( $diff < YEAR_IN_SECONDS && $diff >= 30 * DAY_IN_SECONDS ) {
$months = round( $diff / ( 30 * DAY_IN_SECONDS ) );
if ( $months <= 1 )
$months = 1;
$since = sprintf( _n( '%s month', '%s months', $months ), $months );
} elseif ( $diff >= YEAR_IN_SECONDS ) {
$years = round( $diff / YEAR_IN_SECONDS );
if ( $years <= 1 )
$years = 1;
$since = sprintf( _n( '%s year', '%s years', $years ), $years );
}
return $since;
}
Импровизация к функции «гуманимирование» арноргами. Он рассчитал бы «полностью растянутый» перевод времени временной строки для читабельной текстовой версии человека. Например, чтобы сказать это как "1 неделя 2 дня 1 час 28 минут 14 секунд"
function humantime ($oldtime, $newtime = null, $returnarray = false) {
if(!$newtime) $newtime = time();
$time = $newtime - $oldtime; // to get the time since that moment
$tokens = array (
31536000 => 'year',
2592000 => 'month',
604800 => 'week',
86400 => 'day',
3600 => 'hour',
60 => 'minute',
1 => 'second'
);
$htarray = array();
foreach ($tokens as $unit => $text) {
if ($time < $unit) continue;
$numberOfUnits = floor($time / $unit);
$htarray[$text] = $numberOfUnits.' '.$text.(($numberOfUnits>1)?'s':'');
$time = $time - ( $unit * $numberOfUnits );
}
if($returnarray) return $htarray;
return implode(' ', $htarray);
}
Пришлось сделать это недавно - надеюсь, это кому-то поможет. Это не обслуживается для каждой возможности, но соответствует моим потребностям в проекте.
https://github.com/duncanheron/twitter_date_format.
https://github.com/duncanheron/twitter_date_format/blob/master/twitter_date_format.php.