Как найти время, прошедшее с даты 2010-04-28 17:25:43
времени, как 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';
Будьте осторожны, большинство математически рассчитанных примеров имеют жесткий предел 2038-01-18
дат и не будут работать с вымышленными датами.
Поскольку отсутствовали примеры DateTime
и DateInterval
, я хотел предоставить многоцелевую функцию, которая удовлетворяет потребностям OP и другим, желающим составные истекшие периоды, например 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 = 'Ym-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 для аргументов start, end или limit.
Если вы используете класс 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') . ')'; }
Мне понравился код Митхуна, но я немного изменил его, чтобы он дал более разумные ответы.
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) { 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/time-ago-in-words
https://github.com/jimmiw/php-time-ago
Я только начал использовать последний, делает трюк, но нет стиля stackoverflow-стиля в точную дату, когда указанная дата слишком далека, и нет поддержки будущих дат, – и API немного напуган, но, по крайней мере, это работает, казалось бы, безупречно и поддерживается …
Преобразуйте [saved_date] в метку времени. Получить текущую временную метку.
текущая временная метка – отметка времени [saved_date].
Затем вы можете отформатировать его с помощью date ();
Обычно вы можете конвертировать большинство форматов даты в метки времени с помощью функции 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 = date ('Ymd H: i: s'); define («SECOND», 1); define ('MINUTE', SECOND * 60); define ('HOUR', MINUTE * 60); define («ДЕНЬ», ЧАС * 24); определить («НЕДЕЛЯ», ДЕНЬ * 7); $ t1 = strtotime ($ date_start); $ t2 = strtotime ($ date_end); if ($ t1> $ t2) { $ diffrence = $ t1 - $ t2; } else { $ diffrence = $ t2 - $ t1; } // эхо "
"$ Date_end." "$ DATE_START." .»$ Разностное; $ results ['major'] = array (); // целое число, представляющее большее число в отношении времени даты $ results1 = array (); $ string = ''; $ results ['major'] ['weeks'] = floor ($ diffrence / WEEK); $ results ['major'] ['days'] = floor ($ diffrence / DAY); $ results ['major'] ['hours'] = floor ($ diffrence / HOUR); $ results ['major'] ['minutes'] = floor ($ diffrence / MINUTE); $ results ['major'] ['seconds'] = floor ($ diffrence / SECOND); // print_r ($ результатов); // Логика: // Шаг 1: Возьмите основной результат и преобразуйте его в необработанные секунды (это будет меньше количества секунд разницы) // ex: $ result = ($ results ['major'] ['weeks'] * WEEK) // Шаг 2: вычесть меньшее число (результат) из разности (общее время) // ex: $ minor_result = $ difference - $ result // Шаг 3: Возьмите полученное время в секундах и преобразуйте его в младший формат // ex: floor ($ minor_result / DAY) $ results1 ['weeks'] = floor ($ diffrence / WEEK); $ results1 ['days'] = floor ((($ diffrence - ($ results ['major'] ['weeks'] * WEEK)) / DAY)); $ results1 ['hours'] = floor ((($ diffrence - ($ results ['major'] ['days'] * DAY)) / HOUR)); $ results1 ['minutes'] = floor ((($ diffrence - ($ results ['major'] ['hours'] * HOUR)) / MINUTE)); $ results1 ['seconds'] = floor ((($ diffrence - ($ results ['major'] ['minutes'] * MINUTE) / SECOND)); // print_r ($ results1); if ($ results1 ['weeks']! = 0 && $ results1 ['days'] == 0) { if ($ results1 ['weeks'] == 1) { $ string = $ results1 ['weeks']. ' неделю назад'; } else { if ($ results1 ['weeks'] == 2) { $ string = $ results1 ['weeks']. «недели назад»; } else { $ string = '2 недели назад'; } } } elseif ($ results1 ['weeks']! = 0 && $ results1 ['days']! = 0) { if ($ results1 ['weeks'] == 1) { $ string = $ results1 ['weeks']. ' неделю назад'; } else { if ($ results1 ['weeks'] == 2) { $ string = $ results1 ['weeks']. «недели назад»; } else { $ string = '2 недели назад'; } } } elseif ($ results1 ['weeks'] == 0 && $ results1 ['days']! = 0) { if ($ results1 ['days'] == 1) { $ string = $ results1 ['days']. «день назад»; } else { $ string = $ results1 ['days']. ' дней назад'; } } elseif ($ results1 ['days']! = 0 && $ results1 ['hours']! = 0) { $ string = $ results1 ['days']. 'день и'. $ results1 ['hours']. ' несколько часов назад'; } elseif ($ results1 ['days'] == 0 && $ results1 ['hours']! = 0) { if ($ results1 ['hours'] == 1) { $ string = $ results1 ['hours']. ' час назад'; } else { $ string = $ results1 ['hours']. ' несколько часов назад'; } } elseif ($ results1 ['hours']! = 0 && $ results1 ['minutes']! = 0) { $ string = $ results1 ['hours']. «час и». $ results1 ['minutes']. ' минут назад'; } elseif ($ results1 ['hours'] == 0 && $ results1 ['minutes']! = 0) { if ($ results1 ['minutes'] == 1) { $ string = $ results1 ['minutes']. «минута назад»; } else { $ string = $ results1 ['minutes']. ' минут назад'; } } elseif ($ results1 ['minutes']! = 0 && $ results1 ['seconds']! = 0) { $ string = $ results1 ['minutes']. «минута» и «. $ results1 ['seconds']. «секунды назад»; } elseif ($ results1 ['minutes'] == 0 && $ results1 ['seconds']! = 0) { if ($ results1 ['seconds'] == 1) { $ string = $ results1 ['seconds']. «второй раз»; } else { $ string = $ results1 ['seconds']. «секунды назад»; } } return $ string; } ?>
Вы можете получить функцию для этой прямой формы файлов ядра WordPress.
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; }
Импровизация к функции «humanTiming» arnorhs. Он рассчитал бы «полностью растянутый» перевод временной строки в текстовую версию, доступную для человека. Например, сказать: «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