Domanda

    

Questa domanda ha già una risposta qui:

         

Come trovare il tempo trascorso dal momento che un timbro di data e ora come 2010-04-28 17:25:43, out finale inserire il testo dovrebbe essere come xx Minutes Ago / xx Days Ago

È stato utile?

Soluzione

La maggior parte delle risposte sembrano concentra intorno conversione della data da una stringa in tanto. Sembra che stai pensando di ottenere per lo più la data nel formato '5 giorni fa', ecc .. giusto?

Questo è come mi piacerebbe andare a fare che:

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

}

non ho ancora testato, ma dovrebbe funzionare.

Il risultato sarà simile

event happened 4 days ago

o

event happened 1 minute ago

applausi

Altri suggerimenti

Vuoi funzione PHP quota che si traduce in grammaticalmente corretta Facebook come formato ora leggibile.

Esempio:

echo get_time_ago(strtotime('now'));

Risultato:

meno di 1 minuto fa

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

Credo di avere una funzione che dovrebbe fare quello che vuoi:

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

È sufficiente applicarlo alla differenza tra time() e strtotime('2010-04-28 17:25:43') come:

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

Se si utilizza la classe php Datetime si potrebbe usare:

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

Attenzione, la maggior parte degli esempi matematicamente calcolati hanno un limite rigido di date 2038-01-18 e non funzionerà con date di fantasia.

Come c'era una mancanza di DateTime e esempi basati DateInterval, Ho voluto fornire una funzione polivalente che soddisfa necessità del PO e altri che vogliono composto trascorsi periodi, come 1 month 2 days ago. Insieme con un gruppo di altri casi d'uso, come un limite per visualizzare la data invece del tempo trascorso, o per filtrare porzioni del risultato tempo trascorso.

Inoltre la maggior parte degli esempi assumere trascorsi è dal momento attuale, in cui la sotto funzione consente per essere sovrascritto con la data finale desiderata.

/**
 * 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 da notare - gli intervalli recuperati per i valori filtro in dotazione non riporto per il prossimo periodo. Il filtro visualizza solo il valore risultante dei periodi forniti e non ricalcola i periodi per visualizzare solo il totale filtro desiderato.


Utilizzo

Per necessità del PO di visualizzare il periodo di più alta (come del 2015/02/24).

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

Per visualizzare periodi composti e fornire una data di fine personalizzato (si noti la mancanza di tempo in dotazione e le date di fantasia) .

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

Per visualizzare il risultato di periodi filtrati (ordinamento di matrice non importa) .

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

Per visualizzare la data di inizio nel formato fornito (predefinito Y-m-d) se viene raggiunto il limite.

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

Ci sono mucchio di altri casi d'uso. Può anche essere facilmente adattato per accettare unix timestamp e / o DateInterval oggetti per l'avvio, fine, o argomenti limite.

mi piaceva il codice di Mithun, ma ho ottimizzato un po 'per renderlo dare risposte più ragionevoli.

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;

    }
}

Per migliorare @arnorhs risposta che ho aggiunto nella capacità di avere un risultato più preciso quindi se si voleva anni, mesi, giorni e ore per esempio in quanto l'utente si è unito.

Ho aggiunto un nuovo parametro che consente di specificare il numero di punti di precisione che si desidera di essere tornato.

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 possibilità che lavorerò con qualsiasi versione di PHP è quello di fare ciò che è già stato suggerito, che è qualcosa di simile:

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

che vi darà l'età in pochi secondi. Da lì, è possibile visualizzarlo tuttavia si desidera.

Un problema con questo approccio, tuttavia, è che non prenderà in considerazione le cause salti temporali per l'ora legale. Se questo non è un problema, quindi andare per esso. In caso contrario, probabilmente si vorrà utilizzare il metodo () diff nel DateTime classe . Purtroppo, questa è solo un'opzione se siete su almeno PHP 5.3.

Usa questa uno e si può ottenere il

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

Fare riferimento questo http://ca2.php.net/manual/en/dateinterval.format.php

Provare una di queste operazioni pronti contro termine:

https://github.com/salavert/time-ago-in-words

https://github.com/jimmiw/php-time-ago

Ho appena iniziato a utilizzare questi ultimi, fa il trucco, ma nessun fallback StackOverflow in stile sulla data esatta in cui la data in questione è troppo lontano, né v'è il supporto per le date future - e l'API è un po 'eccentrico, ma almeno funziona apparentemente senza problemi ed è mantenuto ...

Converti [saved_date] per timestamp. Ottenere timestamp corrente.

timestamp corrente -. [Saved_date] timestamp

Poi si può formattare con la data ();

normalmente è possibile convertire la maggior parte formati di data al timestamp con la funzione strtotime ().

Per scoprire il tempo trascorso io di solito uso time() invece di date() e marche temporali formattati. Quindi ottenere la differenza tra il secondo valore e il valore precedente e il formato di conseguenza. time() non è un sostituto per diversamente date() ma aiuta totalmente nel calcolo del tempo trascorso.

Esempio:

Il valore di time() sembra qualcosa di simile con incrementi 1274467343 ogni secondo. Così si potrebbe avere $erlierTime con 1274467343 valore e $latterTime con valore 1274467500, poi basta fare $latterTime - $erlierTime per ottenere il tempo trascorso in secondi.

scritto il mio

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

Qui sto usando funzione personalizzata per trovare il tempo trascorso dal momento che un tempo data.

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

È possibile ottenere una funzione per questo direttamente formano file core di WordPress diano un'occhiata qui

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

L'improvvisazione alla funzione "humanTiming" di arnorhs. Sarebbe calcola una traduzione "completamente allungata" della stringa di tempo alla versione testo leggibile. Ad esempio, per dire che come "1 settimana 2 giorni 1 ora 28 minuti e 14 secondi"

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

dovuto fare questo di recente - speriamo che questo aiuta qualcuno. Esso non è adatto per tutte le possibilità, ma soddisfatto le mie esigenze per un progetto.

https://github.com/duncanheron/twitter_date_format

https://github.com/duncanheron/twitter_date_format/blob/master/ twitter_date_format.php

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top