Comment trouver le temps écoulé depuis un horodatage comme 2010-04-28 17:25:43
, le texte final devrait être comme xx Minutes Ago
/xx Days Ago
La plupart des réponses semblent centrées sur la conversion de la date d'une chaîne en heure. Il semble que vous pensiez surtout à insérer la date dans le format "il y a 5 jours", etc., n'est-ce pas?
Voici comment j'y arriverais:
$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':'');
}
}
Je n'ai pas testé cela, mais ça devrait marcher.
Le résultat ressemblerait à
event happened 4 days ago
ou
event happened 1 minute ago
à votre santé
Voulez-vous partager la fonction php qui résulte en un Facebook grammaticalement correct comme un format de temps lisible par l'homme.
Exemple:
echo get_time_ago(strtotime('now'));
Résultat:
il y a moins d'une minute
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';
}
}
Je pense avoir une fonction qui devrait faire ce que vous voulez:
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);
}
Appliquez-le simplement à la différence entre time()
et strtotime('2010-04-28 17:25:43')
comme suit:
print time2string(time()-strtotime('2010-04-28 17:25:43')).' ago';
Si vous utilisez la classe php Datetime, vous pouvez utiliser:
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') . ')';
}
Soyez averti, la majorité des exemples calculés mathématiquement ont une limite stricte de 2038-01-18
dates et ne fonctionnera pas avec des dates fictives.
Comme il y avait un manque d'exemples basés sur DateTime
et DateInterval
, je souhaitais fournir une fonction polyvalente qui réponde aux besoins du PO et à d'autres souhaitant des périodes écoulées composées, telles que 1 month 2 days ago
. Outre de nombreux autres cas d'utilisation, tels qu'une limite pour afficher la date au lieu du temps écoulé ou pour filtrer des parties du résultat du temps écoulé.
De plus, la majorité des exemples supposent que le temps écoulé correspond à l'heure actuelle, la fonction ci-dessous permettant de la remplacer par la date de fin souhaitée.
/**
* 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;
}
Une chose à noter - les intervalles récupérés pour les valeurs de filtre fournies ne sont pas reportés à la période suivante. Le filtre affiche simplement la valeur résultante des périodes fournies et ne recalcule pas les périodes pour afficher uniquement le total du filtre souhaité.
tilisation
Pour le besoin du PO d'afficher la période la plus haute (à partir du 2015-02-24).
echo elapsedTimeString('2010-04-26');
/** 4 years ago */
Pour afficher des périodes composées et fournir une date de fin personnalisée (notez le manque de temps fourni et des dates fictives) .
echo elapsedTimeString('1920-01-01', '2500-02-24', null, false);
/** 580 years 1 month 23 days ago */
Pour afficher le résultat des périodes filtrées (l'ordre du tableau n'a pas d'importance) .
echo elapsedTimeString('2010-05-26', '2012-02-24', null, ['month', 'year']);
/** 1 year 8 months ago */
Pour afficher la date de début au format fourni (par défaut, Y-m-d) si la limite est atteinte.
echo elapsedTimeString('2010-05-26', '2012-02-24', '1 year');
/** 2010-05-26 */
Il y a beaucoup d'autres cas d'utilisation. Il peut également être facilement adapté pour accepter des horodatages Unix et/ou des objets DateInterval pour les arguments de début, de fin ou de limite.
J'ai aimé le code de Mithun, mais je l'ai légèrement modifié pour lui donner des réponses plus raisonnables.
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;
}
}
Afin d’améliorer la réponse de @arnorhs, j’ai ajouté la possibilité d’obtenir un résultat plus précis, par exemple, si vous vouliez des années, des mois, des jours et des heures depuis que l’utilisateur a rejoint le groupe.
J'ai ajouté un nouveau paramètre pour vous permettre de spécifier le nombre de points de précision que vous souhaitez obtenir.
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';
}
Essayez l'une de ces pensions:
https://github.com/salavert/time-ago-in-words
https://github.com/jimmiw/php-time-ago
Je viens juste de commencer à utiliser ce dernier, le truc, mais pas de repli de type stackoverflow à la date exacte lorsque la date en question est trop éloignée, ni de support pour les dates futures - et l'API est un peu funky, mais au moins ça fonctionne apparemment parfaitement et est maintenu ...
Utilisez celui-ci et vous pouvez obtenir le
$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');
Reportez-vous à cette http://ca2.php.net/manual/fr/dateinterval.format.php
Une option qui fonctionnera avec n’importe quelle version de PHP) est de faire ce qui a déjà été suggéré, qui ressemble à ceci:
$eventTime = '2010-04-28 17:25:43';
$age = time() - strtotime($eventTime);
Cela vous donnera l'âge en secondes. De là, vous pouvez l'afficher comme bon vous semble.
Un problème avec cette approche, cependant, est qu’elle ne tient pas compte des décalages temporels causés par DST. Si ce n'est pas une préoccupation, alors allez-y. Sinon, vous voudrez probablement utiliser la méthode diff () dans la classe DateTime . Malheureusement, ce n'est une option que si vous êtes au moins PHP 5.3.
Pour connaître le temps écoulé, j’utilise habituellement time()
au lieu de date()
et des horodatages formatés. Ensuite, obtenez la différence entre cette dernière valeur et la valeur antérieure et formatez en conséquence. time()
n'est pas un remplacement différent de date()
, mais cela aide totalement à calculer le temps écoulé.
exemple:
La valeur de time()
ressemble à ceci 1274467343
incrémente chaque seconde. Donc, vous pourriez avoir $erlierTime
avec la valeur 1274467343
et $latterTime
avec la valeur 1274467500
, alors faites juste $latterTime - $erlierTime
pour obtenir le temps écoulé en secondes.
Convertissez [save_date] en horodatage. Obtenir l'horodatage actuel.
horodatage en cours - horodatage [save_date].
Ensuite, vous pouvez le formater avec date ();
Vous pouvez normalement convertir la plupart des formats de date en horodatages avec la fonction strtotime ().
J'ai dû faire cela récemment - espérons que cela aidera quelqu'un. Il ne répond pas à toutes les possibilités, mais répondait à mes besoins pour un projet.
https://github.com/duncanheron/Twitter_date_format
https://github.com/duncanheron/Twitter_date_format/blob/master/Twitter_date_format.php
Ici, je me sers d’une fonction personnalisée pour trouver le temps écoulé depuis une date et une heure.
echo Datetodays ('2013-7-26 17:01:10'); function Datetodays ($ d) { $ date_start = $ d; $ date_end = date ('Ymd H: i: s'); définir ('SECONDE', 1); définir ('MINUTE', DEUXIÈME * 60); définir ('HEURE', MINUTE * 60); définir ('JOUR', HEURE * 24); définir ('SEMAINE', JOUR * 7); $ t1 = strtotime ($ date_start); $ t2 = strtotime ($ date_end); if ($ t1> $ t2) { $ diffrence = $ t1 - $ t2; } autre { $ diffrence = $ t2 - $ t1; } //écho "
". $ date_end." ". $ date_start." ". $ diffrence; $ results ['major'] = array (); // nombre entier représentant le plus grand nombre dans la relation date-heure $ results1 = array (); $ string = ''; $ résultats ['majeur'] ['semaines'] = étage ($ diffrence/SEMAINE); $ résultats ['majeur'] [ 'days'] = sol ($ diffrence/DAY); $ résultats ['majeur'] ['heures'] = sol ($ diffrence/HEURE); $ résultats ['majeur' ] ['minutes'] = sol ($ diffrence/MINUTE); $ résultats ['majeur'] ['secondes'] = sol ($ diffrence/SECONDE); //print_r($results); // Logique: // Étape 1: Prenez le résultat principal et transformez-le en secondes brutes (moins le nombre de secondes de la différence ) // ex: $ result = = $ résultats ['majeur'] ['semaines'] * SEMAINE) // Étape 2: Soustrayez le plus petit nombre (le résultat) de la différence ( temps total) // ex: $ minor_result = $ difference - $ result // Étape 3: Prenez le temps résultant en secondes et convertissez-le au format mineur // ex: floor ($ minor_result/DAY) $ Results1 ['weeks' ] = sol ($ diffrence/SEMAINE); $ résultats1 ['jours'] = sol (($ diffrence - ($ résultats ['majeur'] ['semaines'] * SEMAINE))/JOUR) ); $ results1 ['hours'] = floor ((($ diffrence - ($ results ['majeur'] ['days'] * JOUR))/HEURE)); $ resultats1 ['minutes'] = sol ((($ diffrence - ($ resultats ['majeur'] ['heures'] * HOUR))/MINUTE)); $ resultats1 ['secondes'] = sol ((($ diffrence - ($ résultats ['majeur'] ['minutes'] * MINUTE)))/DEUXIÈME)); //print_r($ Results1); if ($ results1 ['weeks']! = 0 && $ results1 ['days'] == 0) { if ($ results1 ['weeks'] == 1) { $ string = $ results1 ['weeks']. 'week ago'; } else { if ($ results1 ['weeks'] == 2) { $ string = $ results1 ['weeks']. 'semaines précédentes'; } else { $ string = 'il y a 2 semaines'; } } } elseif ($ results1 [ 'weeks']! = 0 && $ results1 ['days']! = 0) { if ($ results1 ['weeks'] == 1) { $ string = $ results1 [ 'semaines'] . 'week ago'; } else { if ($ results1 ['weeks'] == 2) { $ string = $ results1 ['weeks']. 'semaines précédentes'; } else { $ string = 'il y a 2 semaines'; } } } elseif ($ results1 [ 'weeks'] == 0 && $ results1 ['days']! = 0) { if ($ results1 ['days'] == 1) { $ string = $ results1 [ 'journées'] . 'day ago'; } else { $ string = $ results1 ['days']. 'days ago'; } } elseif ($ results1 ['days']! = 0 && $ results1 ['hours']! = 0) { $ string = $ résultats1 ['jours']. 'jour et'. $ résultats1 ['heures']. 'hours ago'; } elseif ($ results1 ['days'] == 0 && $ results1 ['hours']! = 0) { if ($ results1 ['hours'] == 1) { $ String = $ results1 ['hours']. 'hour ago'; } else { $ string = $ results1 ['hours']. 'hours ago'; } } elseif ($ results1 ['hours']! = 0 && $ results1 ['minutes']! = 0) { $ string = $ résultats1 ['heures']. 'heure et'. $ résultats1 ['minutes']. 'minutes ago'; } elseif ($ résultats1 ['heures'] == 0 && $ résultats1 ['minutes']! = 0) { if ($ résultats1 ['minutes'] == 1) { $ String = $ results1 ['minutes']. 'minute ago'; } else { $ string = $ results1 ['minutes']. 'minutes ago'; } } elseif ($ results1 ['minutes']! = 0 && $ results1 ['secondes']! = 0) { $ string = $ résultats1 ['minutes']. 'minute et'. $ résultats1 ['secondes']. 'seconds ago'; } elseif ($ results1 ['minutes'] == 0 && $ results1 ['secondes']! = 0) { if ($ results1 ['secondes'] == 1) { $ String = $ results1 ['secondes']. 'second ago'; } else { $ string = $ results1 ['seconds']. 'seconds ago'; } } renvoie $ string; } ?>
Improvisation à la fonction "humanTiming" par arnorhs. Il calculerait une traduction "complètement étirée" de chaîne temporelle en version texte lisible par l'homme. Par exemple, dire comme "1 semaine 2 jours 1 heure 28 minutes 14 secondes"
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);
}
Vous pouvez obtenir une fonction pour cette forme directement WordPress) ici
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;
}
Écrit moi-même
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.';
}
}
}