tiempo - fecha actual php
PHP ¿Cómo encontrar el tiempo transcurrido desde una fecha y hora? (17)
Esta pregunta ya tiene una respuesta aquí:
Cómo encontrar el tiempo transcurrido desde una marca de fecha y hora como 2010-04-28 17:25:43
, el texto final de salida debe ser como xx Minutes Ago
/ xx Days Ago
Aquí estoy usando una función personalizada para encontrar el tiempo transcurrido desde una fecha.
echo Datetodays(''2013-7-26 17:01:10'');
function Datetodays($d) {
$date_start = $d;
$date_end = date(''Y-m-d H:i:s'');
define(''SECOND'', 1);
define(''MINUTE'', SECOND * 60);
define(''HOUR'', MINUTE * 60);
define(''DAY'', HOUR * 24);
define(''WEEK'', DAY * 7);
$t1 = strtotime($date_start);
$t2 = strtotime($date_end);
if ($t1 > $t2) {
$diffrence = $t1 - $t2;
} else {
$diffrence = $t2 - $t1;
}
//echo "
".$date_end." ".$date_start." ".$diffrence;
$results[''major''] = array(); // whole number representing larger number in date time relationship
$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($results);
// Logic:
// Step 1: Take the major result and transform it into raw seconds (it will be less the number of seconds of the difference)
// ex: $result = ($results[''major''][''weeks'']*WEEK)
// Step 2: Subtract smaller number (the result) from the difference (total time)
// ex: $minor_result = $difference - $result
// Step 3: Take the resulting time in seconds and convert it to the minor format
// 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''] . '' week ago'';
} else {
if ($results1[''weeks''] == 2) {
$string = $results1[''weeks''] . '' weeks ago'';
} else {
$string = ''2 weeks ago'';
}
}
} elseif ($results1[''weeks''] != 0 && $results1[''days''] != 0) {
if ($results1[''weeks''] == 1) {
$string = $results1[''weeks''] . '' week ago'';
} else {
if ($results1[''weeks''] == 2) {
$string = $results1[''weeks''] . '' weeks ago'';
} else {
$string = ''2 weeks ago'';
}
}
} elseif ($results1[''weeks''] == 0 && $results1[''days''] != 0) {
if ($results1[''days''] == 1) {
$string = $results1[''days''] . '' day ago'';
} else {
$string = $results1[''days''] . '' days ago'';
}
} elseif ($results1[''days''] != 0 && $results1[''hours''] != 0) {
$string = $results1[''days''] . '' day and '' . $results1[''hours''] . '' 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 = $results1[''hours''] . '' hour and '' . $results1[''minutes''] . '' minutes ago'';
} elseif ($results1[''hours''] == 0 && $results1[''minutes''] != 0) {
if ($results1[''minutes''] == 1) {
$string = $results1[''minutes''] . '' minute ago'';
} else {
$string = $results1[''minutes''] . '' minutes ago'';
}
} elseif ($results1[''minutes''] != 0 && $results1[''seconds''] != 0) {
$string = $results1[''minutes''] . '' minute and '' . $results1[''seconds''] . '' seconds ago'';
} elseif ($results1[''minutes''] == 0 && $results1[''seconds''] != 0) {
if ($results1[''seconds''] == 1) {
$string = $results1[''seconds''] . '' second ago'';
} else {
$string = $results1[''seconds''] . '' seconds ago'';
}
}
return $string;
}
?>
Convierta [fecha_guardada] a marca de hora. Obtener la marca de tiempo actual.
marca de tiempo actual - [fecha_fecha] fecha y hora.
Luego puede formatearlo con date ();
Normalmente puede convertir la mayoría de los formatos de fecha a marcas de tiempo con la función strtotime ().
Creo que tengo una función que debería hacer lo que quieras:
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);
}
Simplemente aplíquelo a la diferencia entre time()
y strtotime(''2010-04-28 17:25:43'')
como tal:
print time2string(time()-strtotime(''2010-04-28 17:25:43'')).'' ago'';
Desea compartir la función de php que da como resultado un formato de tiempo gramaticalmente correcto como el de Facebook.
Ejemplo:
echo get_time_ago(strtotime(''now''));
Resultado:
hace menos de 1 minuto
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'';
}
}
Escribió mi propio
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.'';
}
}
}
Improvisación a la función "HumanTiming" por arnorhs. Calcularía una traducción "completamente estirada" de la cadena de tiempo a la versión de texto legible para el ser humano. Por ejemplo decirlo como "1 semana 2 días 1 hora 28 minutos 14 segundos"
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);
}
La mayoría de las respuestas parecen enfocadas en convertir la fecha de una cadena a otra. Parece que estás pensando principalmente en poner la fecha en el formato ''5 días atrás'', etc. ¿verdad?
Así es como voy a hacer eso:
$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'':'''');
}
}
No lo he probado, pero debería funcionar.
El resultado se vería así
event happened 4 days ago
o
event happened 1 minute ago
aclamaciones
Me gustó el código de Mithun, pero lo modifiqué un poco para que brindara respuestas más razonables.
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;
}
}
Para mejorar la respuesta de @arnorhs, he agregado la capacidad de obtener un resultado más preciso, por lo que si desea años, meses, días y horas, por ejemplo, desde que se unió el usuario.
Agregué un nuevo parámetro para permitirle especificar la cantidad de puntos de precisión que desea devolver.
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'';
}
Para saber el tiempo transcurrido usualmente uso time()
lugar de date()
y las marcas de tiempo formateadas. A continuación, obtenga la diferencia entre el último valor y el valor anterior y el formato en consecuencia. time()
no es un sustituto de la date()
pero es totalmente útil para calcular el tiempo transcurrido.
ejemplo:
El valor de time()
ve algo así como 1274467343
incrementos por segundo. Por lo tanto, podría tener $erlierTime
con el valor 1274467343
y $latterTime
con el valor 1274467500
, luego haga $latterTime - $erlierTime
para obtener el tiempo transcurrido en segundos.
Pruebe uno de estos repositorios:
https://github.com/salavert/time-ago-in-words
https://github.com/jimmiw/php-time-ago
Acabo de empezar a usar este último, lo hago, pero no hay un retorno al estilo en la fecha exacta cuando la fecha en cuestión está demasiado lejos, ni hay soporte para fechas futuras, y el API es un poco raro, pero al menos funciona aparentemente sin problemas y se mantiene ...
Puede obtener una función para esto directamente desde archivos de WordPress core echar un vistazo aquí
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;
}
Si usa la clase php Datetime, puede usar:
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'') . '')'';
}
Tenga cuidado, la mayoría de los ejemplos calculados matemáticamente tienen un límite 2038-01-18
fechas 2038-01-18
y no funcionarán con fechas ficticias.
Como DateInterval
ejemplos basados en DateTime
y DateInterval
, quise proporcionar una función multipropósito que satisfaga las necesidades del OP y otros que desean períodos transcurridos compuestos, como hace 1 month 2 days ago
. Junto con otros muchos casos de uso, como un límite para mostrar la fecha en lugar del tiempo transcurrido, o para filtrar porciones del resultado del tiempo transcurrido.
Además, la mayoría de los ejemplos suponen que transcurrido es de la hora actual, donde la función siguiente permite anularla con la fecha de finalización deseada.
/**
* 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;
}
Una cosa a tener en cuenta: los intervalos recuperados para los valores de filtro suministrados no se transfieren al siguiente período. El filtro simplemente muestra el valor resultante de los períodos suministrados y no recalcula los períodos para mostrar solo el total del filtro deseado.
Uso
Para la necesidad del OP de mostrar el período más alto (a partir de 2015-02-24).
echo elapsedTimeString(''2010-04-26'');
/** 4 years ago */
Para mostrar períodos compuestos y proporcionar una fecha de finalización personalizada (tenga en cuenta la falta de tiempo y las fechas ficticias) .
echo elapsedTimeString(''1920-01-01'', ''2500-02-24'', null, false);
/** 580 years 1 month 23 days ago */
Para mostrar el resultado de los períodos filtrados (no importa el orden de la matriz) .
echo elapsedTimeString(''2010-05-26'', ''2012-02-24'', null, [''month'', ''year'']);
/** 1 year 8 months ago */
Para mostrar la fecha de inicio en el formato suministrado (Ymd predeterminado) si se alcanza el límite.
echo elapsedTimeString(''2010-05-26'', ''2012-02-24'', ''1 year'');
/** 2010-05-26 */
Hay muchos otros casos de uso. También se puede adaptar fácilmente para aceptar marcas de tiempo Unix y / o objetos DateInterval para los argumentos de inicio, fin o límite.
Tuve que hacer esto recientemente, espero que esto ayude a alguien. No cubre todas las posibilidades, pero cumple con mis necesidades para un proyecto.
https://github.com/duncanheron/twitter_date_format
https://github.com/duncanheron/twitter_date_format/blob/master/twitter_date_format.php
Una opción que funcionará con cualquier versión de PHP es hacer lo que ya se sugirió, que es algo como esto:
$eventTime = ''2010-04-28 17:25:43'';
$age = time() - strtotime($eventTime);
Eso te dará la edad en segundos. Desde allí, puede mostrarlo como lo desee.
Un problema con este enfoque, sin embargo, es que no tendrá en cuenta los cambios de tiempo provocados por el horario de verano. Si eso no es una preocupación, entonces ve por ello. De lo contrario, es probable que desee utilizar el método diff () en la clase DateTime . Desafortunadamente, esta es solo una opción si tienes al menos PHP 5.3.
Usa este y puedes obtener
$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'');
Referir esto http://ca2.php.net/manual/en/dateinterval.format.php