Pregunta

Cómo encontrar el tiempo transcurrido desde que un sello de fecha y hora como 2010-04-28 17:25:43, último out texto de palabras debe ser como xx Minutes Ago / xx Days Ago

¿Fue útil?

Solución

La mayoría de las respuestas parecen centra en la conversión de la fecha a partir de una cadena a tiempo. Parece que está sobre todo pensando en conseguir la fecha en el formato 'Hace 5 días', etc .. ¿verdad?

Así es como me gustaría ir sobre hacer lo siguiente:

$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 he probado esto, pero debería funcionar.

El resultado será similar

event happened 4 days ago

o

event happened 1 minute ago

aplausos

Otros consejos

¿Quieres función php acción, que da como resultado gramaticalmente correcta Facebook como formato de hora legible por humanos.

Ejemplo:

echo get_time_ago(strtotime('now'));

Resultados:

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';
    }
}

Creo que tengo una función que debe hacer lo que quiera:

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 se aplica a la diferencia entre time() y strtotime('2010-04-28 17:25:43') como así:

print time2string(time()-strtotime('2010-04-28 17:25:43')).' ago';

Si se utiliza la clase de fecha y hora php 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 en cuenta, la mayoría de los ejemplos calculados matemáticamente tiene un límite estricto de las fechas 2038-01-18 y no funcionará con las fechas de ficción.

Como había una falta de DateTime y ejemplos basados ??DateInterval, quería proporcionar una función polivalente que satisface la necesidad de OP y otros compuestos que desean transcurrieron períodos, como 1 month 2 days ago. Junto con un montón de otros casos de uso, tales como un límite para mostrar la fecha en lugar del tiempo transcurrido, o para filtrar porciones del resultado tiempo transcurrido.

Además la mayoría de los ejemplos asumen transcurrido es a partir del momento actual, en el siguiente función permite para que sea reemplazado con la fecha final deseado.

/**
 * 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 la nota - los intervalos de los valores recuperados filtro suministrado no se traspasan al siguiente período. El filtro simplemente muestra el valor resultante de los períodos suministrados y no vuelve a calcular los períodos para mostrar solamente el total de filtro deseado.


Uso

Para las necesidades de la OP de mostrar el período más alto (a partir del 02/24/2015).

echo elapsedTimeString('2010-04-26');
/** 4 years ago */

Para mostrar períodos compuestos y suministrar una fecha de finalización de encargo (tenga en cuenta la falta de tiempo suministrado y fechas de ficción) .

echo elapsedTimeString('1920-01-01', '2500-02-24', null, false);
/** 580 years 1 month 23 days ago */

Para mostrar el resultado de periodos filtrados (orden de la matriz no importa) .

echo elapsedTimeString('2010-05-26', '2012-02-24', null, ['month', 'year']);
/** 1 year 8 months ago */

Para visualizar la fecha de inicio en el formato suministrado (por defecto Y-m-d) si se alcanza el límite.

echo elapsedTimeString('2010-05-26', '2012-02-24', '1 year');
/** 2010-05-26 */

Hay montón de otros casos de uso. Es también puede ser fácilmente adaptado para aceptar UNIX marcas de tiempo y / o objetos DateInterval para el inicio, fin o argumentos límite.

Me gusta el código de Mithun, pero ajustado un poco para que sea dar 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 @arnorhs respuesta que he añadido en la capacidad de tener un resultado más preciso lo que si quería años, meses, días y horas, por ejemplo, ya que el usuario se unió.

He añadido un nuevo parámetro que le permite especificar el número de puntos de precisión que desea han regresado.

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';
}

Una opción que va a trabajar con cualquier versión de PHP es hacer lo que ya se ha sugerido, que es algo como esto:

$eventTime = '2010-04-28 17:25:43';
$age = time() - strtotime($eventTime);

Esto le dará la edad en cuestión de segundos. A partir de ahí, se puede visualizar sin embargo que usted desea.

Un problema con este enfoque, sin embargo, es que no va a tener en cuenta los cambios de tiempo por causas DST. Si eso no es una preocupación, a continuación, ir a por ello. De lo contrario, es probable que desee utilizar el método diff () en el DateTime clase. Por desgracia, esto es sólo una opción si estás en al menos PHP 5.3.

Usar este uno y se puede obtener la

    $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');

Consulte este http://ca2.php.net/manual/en/dateinterval.format.php

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, hace el truco, pero ningún repliegue de estilo stackoverflow en fecha exacta en la fecha en cuestión es demasiado lejos, ni hay soporte para fechas futuras - y la API es un poco raro, pero al menos aparentemente funciona perfectamente y se mantiene ...

Convert [saved_date] a marca de tiempo. Obtener fecha y hora actual.

fecha y hora actual -. [Saved_date] marca de tiempo

A continuación, puede darle formato con fecha ();

Normalmente se puede convertir la mayoría de formatos de fecha a las marcas de tiempo con la función strtotime ().

Para saber el tiempo transcurrido que suelen utilizar en lugar de time() date() y marcas de tiempo con formato. A continuación, obtener la diferencia entre este último valor y el valor anterior y el formato en consecuencia. time() no es diferente de un reemplazo para date() pero totalmente ayuda a la hora de calcular el tiempo transcurrido.

ejemplo:

El valor de time() ve algo como esto incrementos 1274467343 cada segundo. Lo que podría tener $erlierTime con valor 1274467343 y $latterTime con valor 1274467500, a continuación, sólo hacer $latterTime - $erlierTime para obtener el tiempo transcurrido en segundos.

escribir mi propia

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.';
        }
    }
}

Aquí estoy usando la función personalizada para encontrar el tiempo transcurrido desde la fecha y hora.

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; } ?>

Se puede obtener una función para este formulario directamente archivos del núcleo de WordPress miren 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;
}

La improvisación a la función "humanTiming" por arnorhs. Se calcularía una traducción "totalmente estirado" de cadena de tiempo a la versión de texto legible por humanos. Por ejemplo, para decirlo como "1 semana 2 días 1 hora 28 minutos y 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);
}

tenía que hacer esto recientemente - espero que esto ayude a alguien. Que no está pensado para todas las posibilidades, pero satisfizo 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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top