Converti i secondi in giorni, ore, minuti e secondi


92

Vorrei convertire una variabile $uptimeche è secondi, in giorni, ore, minuti e secondi.

Esempio:

$uptime = 1640467;

Il risultato dovrebbe essere:

18 days 23 hours 41 minutes

Risposte:


214

Questo può essere ottenuto con la DateTimeclasse

Uso:

echo secondsToTime(1640467);
# 18 days, 23 hours, 41 minutes and 7 seconds

Funzione:

function secondsToTime($seconds) {
    $dtF = new \DateTime('@0');
    $dtT = new \DateTime("@$seconds");
    return $dtF->diff($dtT)->format('%a days, %h hours, %i minutes and %s seconds');
}

demo


@ Glavić Come aggiungerei il supporto per settimana e mese a questo?
socca1157

2
Assicurati di aggiungere la convalida alla funzione. if (vuoto ($ secondi)) {return false;}
un programmatore

4
@acoder: penso che questa funzione non dovrebbe occuparsi della convalida; la convalida dovrebbe essere impostata prima della chiamata della funzione. Tuttavia, la tua convalida è ancora sbagliata, perché ad esempio passerà anche l'alfabeto.
Glavić

2
Cosa @significa quando viene passato come argomento al DateTimecostruttore?
Ivanka Todorova

4
@IvankaTodorova: il valore dopo @è unix timestamp.
Glavić

44

Questa è la funzione riscritta per includere i giorni. Ho anche cambiato i nomi delle variabili per rendere il codice più facile da capire ...

/** 
 * Convert number of seconds into hours, minutes and seconds 
 * and return an array containing those values 
 * 
 * @param integer $inputSeconds Number of seconds to parse 
 * @return array 
 */ 

function secondsToTime($inputSeconds) {

    $secondsInAMinute = 60;
    $secondsInAnHour  = 60 * $secondsInAMinute;
    $secondsInADay    = 24 * $secondsInAnHour;

    // extract days
    $days = floor($inputSeconds / $secondsInADay);

    // extract hours
    $hourSeconds = $inputSeconds % $secondsInADay;
    $hours = floor($hourSeconds / $secondsInAnHour);

    // extract minutes
    $minuteSeconds = $hourSeconds % $secondsInAnHour;
    $minutes = floor($minuteSeconds / $secondsInAMinute);

    // extract the remaining seconds
    $remainingSeconds = $minuteSeconds % $secondsInAMinute;
    $seconds = ceil($remainingSeconds);

    // return the final array
    $obj = array(
        'd' => (int) $days,
        'h' => (int) $hours,
        'm' => (int) $minutes,
        's' => (int) $seconds,
    );
    return $obj;
}

Fonte: CodeAid () - http://codeaid.net/php/convert-seconds-to-hours-minutes-and-seconds-(php)


Sarebbe bello includere la fonte
Martin.

saresti così gentile da aggiungere giorni a questa funzione?
knittledan

@knittledan, non sembra così :)
AO_

1
@ hsmoore.com Sono andato avanti e ho capito $ days = floor ($ seconds / (60 * 60 * 24)); // estrae le ore $ divisor_for_hours = $ secondi% (60 * 60 * 24); $ ore = floor ($ divisor_for_hours / (60 * 60));
knittledan

1
Non funziona come previsto per giorni. È necessario sottrarre ($ giorni * 24) da $ ore, altrimenti le ore nei giorni verranno conteggiate due volte in $ giorni e $ ore. es. input 100000 => 1 giorno e 27 ore. Dovrebbe essere di 1 giorno e 3 ore.
finiteloop

30

Basato sulla risposta di Julian Moreno, ma modificato per dare la risposta come una stringa (non un array), include solo gli intervalli di tempo richiesti e non assume il plurale.

La differenza tra questa e la risposta più votata è:

Per 259264secondi, questo codice darebbe

3 giorni, 1 minuto, 4 secondi

Per 259264secondi, la risposta più votata (da Glavić) darebbe

3 giorni, 0 ore , 1 minuto s e 4 secondi

function secondsToTime($inputSeconds) {
    $secondsInAMinute = 60;
    $secondsInAnHour = 60 * $secondsInAMinute;
    $secondsInADay = 24 * $secondsInAnHour;

    // Extract days
    $days = floor($inputSeconds / $secondsInADay);

    // Extract hours
    $hourSeconds = $inputSeconds % $secondsInADay;
    $hours = floor($hourSeconds / $secondsInAnHour);

    // Extract minutes
    $minuteSeconds = $hourSeconds % $secondsInAnHour;
    $minutes = floor($minuteSeconds / $secondsInAMinute);

    // Extract the remaining seconds
    $remainingSeconds = $minuteSeconds % $secondsInAMinute;
    $seconds = ceil($remainingSeconds);

    // Format and return
    $timeParts = [];
    $sections = [
        'day' => (int)$days,
        'hour' => (int)$hours,
        'minute' => (int)$minutes,
        'second' => (int)$seconds,
    ];

    foreach ($sections as $name => $value){
        if ($value > 0){
            $timeParts[] = $value. ' '.$name.($value == 1 ? '' : 's');
        }
    }

    return implode(', ', $timeParts);
}

Spero che questo aiuti qualcuno.


1
Preferisco questo perché rimuove la "s", da "1 ore", e, nel mio caso, volevo rimuovere i giorni e avere solo un conteggio delle ore elevato, e questo metodo è stato molto facile da adattare a quello <3.
Ryan S

1
Molto bello Luca, tenendolo compatto e pulito!
VoidZA

19

Ecco una semplice funzione PHP di 8 righe che converte un numero di secondi in una stringa leggibile dall'uomo incluso il numero di mesi per grandi quantità di secondi:

Funzione PHP seconds2human ()

function seconds2human($ss) {
$s = $ss%60;
$m = floor(($ss%3600)/60);
$h = floor(($ss%86400)/3600);
$d = floor(($ss%2592000)/86400);
$M = floor($ss/2592000);

return "$M months, $d days, $h hours, $m minutes, $s seconds";
}

2
Semplice ma efficiente. Anche se non mi è piaciuto il pezzo "Mesi".
Francisco Presencia

1
Dovresti includere il codice nella tua risposta, non collegare a un'altra pagina. Non c'è modo di accertare che il sito web a cui ti stai collegando sarà ancora lì domani
Zachary Weixelbaum

11
gmdate("d H:i:s",1640467);

Il risultato sarà 19 23:41:07. Quando è solo un secondo in più del giorno normale, aumenta il valore del giorno per 1 giorno. Questo è il motivo per cui mostra 19. Puoi esplodere il risultato per le tue esigenze e risolvere il problema.


Puoi anche migliorare questo codice in questo modo: $uptime = gmdate("y m d H:i:s", 1640467); $uptimeDetail = explode(" ",$uptime); echo (string)($uptimeDetail[0]-70).' year(s) '.(string)($uptimeDetail[1]-1).' month(s) '.(string)($uptimeDetail[2]-1).' day(s) '.(string)$uptimeDetail[3];questo ti darà anche informazioni su anno e mese.
Caner SAYGIN

Per evitare l'errore di +1 giorno, sottrarre semplicemente (24 * 60 * 60) dal timestamp della sorgente in secondi.
andreszs,

9

Ci sono alcune ottime risposte qui, ma nessuna ha soddisfatto le mie esigenze. Ho costruito sulla risposta di Glavic per aggiungere alcune funzionalità extra di cui avevo bisogno;

  • Non stampare zeri. Quindi "5 minuti" invece di "0 ore, 5 minuti"
  • Gestisci correttamente il plurale invece di utilizzare per impostazione predefinita la forma plurale.
  • Limitare l'uscita a un determinato numero di unità; Quindi "2 mesi, 2 giorni" invece di "2 mesi, 2 giorni, 1 ora, 45 minuti"

Puoi vedere una versione in esecuzione del codice here.

function secondsToHumanReadable(int $seconds, int $requiredParts = null)
{
    $from     = new \DateTime('@0');
    $to       = new \DateTime("@$seconds");
    $interval = $from->diff($to);
    $str      = '';

    $parts = [
        'y' => 'year',
        'm' => 'month',
        'd' => 'day',
        'h' => 'hour',
        'i' => 'minute',
        's' => 'second',
    ];

    $includedParts = 0;

    foreach ($parts as $key => $text) {
        if ($requiredParts && $includedParts >= $requiredParts) {
            break;
        }

        $currentPart = $interval->{$key};

        if (empty($currentPart)) {
            continue;
        }

        if (!empty($str)) {
            $str .= ', ';
        }

        $str .= sprintf('%d %s', $currentPart, $text);

        if ($currentPart > 1) {
            // handle plural
            $str .= 's';
        }

        $includedParts++;
    }

    return $str;
}

1
mi ha aiutato molto
Manojkiran.A

Creerò la funzione in base al tuo modo in laravel
Manojkiran.A

8

Breve, semplice, affidabile:

function secondsToDHMS($seconds) {
    $s = (int)$seconds;
    return sprintf('%d:%02d:%02d:%02d', $s/86400, $s/3600%24, $s/60%60, $s%60);
}

3
Ulteriori spiegazioni farebbero molto in questa risposta, ad esempio cosa rappresentano le costanti intere e come funziona la formattazione delle stringhe con sprintf.

1
Vorrei fare sprintf ('% dd:% 02dh:% 02dm:% 02ds', $ s / 86400, $ s / 3600% 24, $ s / 60% 60, $ s% 60); solo per essere ancora più humnan (es: 0d: 00h: 05m: 00s). Ma probabilmente la migliore soluzione qui.
Ricardo Martins

6

L'approccio più semplice sarebbe quello di creare un metodo che restituisca un DateInterval da DateTime :: diff del tempo relativo in $ secondi dall'ora corrente $ now che puoi quindi concatenare e formattare. Per esempio:-

public function toDateInterval($seconds) {
    return date_create('@' . (($now = time()) + $seconds))->diff(date_create('@' . $now));
}

Ora concatena la chiamata al metodo a DateInterval :: format

echo $this->toDateInterval(1640467)->format('%a days %h hours %i minutes'));

Risultato:

18 days 23 hours 41 minutes

3

Sebbene sia una domanda piuttosto vecchia, si possono trovare utili questi (non scritti per essere veloci):

function d_h_m_s__string1($seconds)
{
    $ret = '';
    $divs = array(86400, 3600, 60, 1);

    for ($d = 0; $d < 4; $d++)
    {
        $q = (int)($seconds / $divs[$d]);
        $r = $seconds % $divs[$d];
        $ret .= sprintf("%d%s", $q, substr('dhms', $d, 1));
        $seconds = $r;
    }

    return $ret;
}

function d_h_m_s__string2($seconds)
{
    if ($seconds == 0) return '0s';

    $can_print = false; // to skip 0d, 0d0m ....
    $ret = '';
    $divs = array(86400, 3600, 60, 1);

    for ($d = 0; $d < 4; $d++)
    {
        $q = (int)($seconds / $divs[$d]);
        $r = $seconds % $divs[$d];
        if ($q != 0) $can_print = true;
        if ($can_print) $ret .= sprintf("%d%s", $q, substr('dhms', $d, 1));
        $seconds = $r;
    }

    return $ret;
}

function d_h_m_s__array($seconds)
{
    $ret = array();

    $divs = array(86400, 3600, 60, 1);

    for ($d = 0; $d < 4; $d++)
    {
        $q = $seconds / $divs[$d];
        $r = $seconds % $divs[$d];
        $ret[substr('dhms', $d, 1)] = $q;

        $seconds = $r;
    }

    return $ret;
}

echo d_h_m_s__string1(0*86400+21*3600+57*60+13) . "\n";
echo d_h_m_s__string2(0*86400+21*3600+57*60+13) . "\n";

$ret = d_h_m_s__array(9*86400+21*3600+57*60+13);
printf("%dd%dh%dm%ds\n", $ret['d'], $ret['h'], $ret['m'], $ret['s']);

risultato:

0d21h57m13s
21h57m13s
9d21h57m13s

3
function seconds_to_time($seconds){
     // extract hours
    $hours = floor($seconds / (60 * 60));

    // extract minutes
    $divisor_for_minutes = $seconds % (60 * 60);
    $minutes = floor($divisor_for_minutes / 60);

    // extract the remaining seconds
    $divisor_for_seconds = $divisor_for_minutes % 60;
    $seconds = ceil($divisor_for_seconds);

    //create string HH:MM:SS
    $ret = $hours.":".$minutes.":".$seconds;
    return($ret);
}

1
Ti mancano i giorni
Sam Tuke

3
function convert($seconds){
$string = "";

$days = intval(intval($seconds) / (3600*24));
$hours = (intval($seconds) / 3600) % 24;
$minutes = (intval($seconds) / 60) % 60;
$seconds = (intval($seconds)) % 60;

if($days> 0){
    $string .= "$days days ";
}
if($hours > 0){
    $string .= "$hours hours ";
}
if($minutes > 0){
    $string .= "$minutes minutes ";
}
if ($seconds > 0){
    $string .= "$seconds seconds";
}

return $string;
}

echo convert(3744000);

2

Soluzione che dovrebbe escludere i valori 0 e impostare valori singolari / plurali corretti

use DateInterval;
use DateTime;

class TimeIntervalFormatter
{

    public static function fromSeconds($seconds)
    {
        $seconds = (int)$seconds;
        $dateTime = new DateTime();
        $dateTime->sub(new DateInterval("PT{$seconds}S"));
        $interval = (new DateTime())->diff($dateTime);
        $pieces = explode(' ', $interval->format('%y %m %d %h %i %s'));
        $intervals = ['year', 'month', 'day', 'hour', 'minute', 'second'];
        $result = [];
        foreach ($pieces as $i => $value) {
            if (!$value) {
                continue;
            }
            $periodName = $intervals[$i];
            if ($value > 1) {
                $periodName .= 's';
            }
            $result[] = "{$value} {$periodName}";
        }
        return implode(', ', $result);
    }
}

1

una versione estesa dell'eccellente soluzione di Glavić , con convalida intera, risolvendo il problema di 1 se supporto aggiuntivo per anni e mesi, a scapito di essere meno amichevole per l'analisi del computer a favore di essere più amichevole per l'uomo:

<?php
function secondsToHumanReadable(/*int*/ $seconds)/*: string*/ {
    //if you dont need php5 support, just remove the is_int check and make the input argument type int.
    if(!\is_int($seconds)){
        throw new \InvalidArgumentException('Argument 1 passed to secondsToHumanReadable() must be of the type int, '.\gettype($seconds).' given');
    }
    $dtF = new \DateTime ( '@0' );
    $dtT = new \DateTime ( "@$seconds" );
    $ret = '';
    if ($seconds === 0) {
        // special case
        return '0 seconds';
    }
    $diff = $dtF->diff ( $dtT );
    foreach ( array (
            'y' => 'year',
            'm' => 'month',
            'd' => 'day',
            'h' => 'hour',
            'i' => 'minute',
            's' => 'second' 
    ) as $time => $timename ) {
        if ($diff->$time !== 0) {
            $ret .= $diff->$time . ' ' . $timename;
            if ($diff->$time !== 1 && $diff->$time !== -1 ) {
                $ret .= 's';
            }
            $ret .= ' ';
        }
    }
    return substr ( $ret, 0, - 1 );
}

var_dump(secondsToHumanReadable(1*60*60*2+1)); -> string(16) "2 hours 1 second"


1

È possibile utilizzare la classe di intervallo che ho scritto. Può essere utilizzato anche in modo opposto.

composer require lubos/cakephp-interval

$Interval = new \Interval\Interval\Interval();

// output 2w 6h
echo $Interval->toHuman((2 * 5 * 8 + 6) * 3600);

// output 36000
echo $Interval->toSeconds('1d 2h');

Maggiori informazioni qui https://github.com/LubosRemplik/CakePHP-Interval


1

Con DateInterval :

$d1 = new DateTime();
$d2 = new DateTime();
$d2->add(new DateInterval('PT'.$timespan.'S'));

$interval = $d2->diff($d1);
echo $interval->format('%a days, %h hours, %i minutes and %s seconds');

// Or
echo sprintf('%d days, %d hours, %d minutes and %d seconds',
    $interval->days,
    $interval->h,
    $interval->i,
    $interval->s
);

// $interval->y => years
// $interval->m => months
// $interval->d => days
// $interval->h => hours
// $interval->i => minutes
// $interval->s => seconds
// $interval->days => total number of days

0

Ecco un codice che mi piace usare allo scopo di ottenere la durata tra due date. Accetta due date e ti dà una bella risposta strutturata a frase.

Questa è una versione leggermente modificata del codice trovato qui .

<?php

function dateDiff($time1, $time2, $precision = 6, $offset = false) {

    // If not numeric then convert texts to unix timestamps

    if (!is_int($time1)) {
            $time1 = strtotime($time1);
    }

    if (!is_int($time2)) {
            if (!$offset) {
                    $time2 = strtotime($time2);
            }
            else {
                    $time2 = strtotime($time2) - $offset;
            }
    }

    // If time1 is bigger than time2
    // Then swap time1 and time2

    if ($time1 > $time2) {
            $ttime = $time1;
            $time1 = $time2;
            $time2 = $ttime;
    }

    // Set up intervals and diffs arrays

    $intervals = array(
            'year',
            'month',
            'day',
            'hour',
            'minute',
            'second'
    );
    $diffs = array();

    // Loop thru all intervals

    foreach($intervals as $interval) {

            // Create temp time from time1 and interval

            $ttime = strtotime('+1 ' . $interval, $time1);

            // Set initial values

            $add = 1;
            $looped = 0;

            // Loop until temp time is smaller than time2

            while ($time2 >= $ttime) {

                    // Create new temp time from time1 and interval

                    $add++;
                    $ttime = strtotime("+" . $add . " " . $interval, $time1);
                    $looped++;
            }

            $time1 = strtotime("+" . $looped . " " . $interval, $time1);
            $diffs[$interval] = $looped;
    }

    $count = 0;
    $times = array();

    // Loop thru all diffs

    foreach($diffs as $interval => $value) {

            // Break if we have needed precission

            if ($count >= $precision) {
                    break;
            }

            // Add value and interval
            // if value is bigger than 0

            if ($value > 0) {

                    // Add s if value is not 1

                    if ($value != 1) {
                            $interval.= "s";
                    }

                    // Add value and interval to times array

                    $times[] = $value . " " . $interval;
                    $count++;
            }
    }

    if (!empty($times)) {

            // Return string with times

            return implode(", ", $times);
    }
    else {

            // Return 0 Seconds

    }

    return '0 Seconds';
}

Fonte: https://gist.github.com/ozh/8169202


0

Tutto in una soluzione. Non fornisce unità con zero. Produrrà solo il numero di unità specificato (3 per impostazione predefinita). Abbastanza lungo, forse non molto elegante. Le definizioni sono facoltative, ma potrebbero tornare utili in un grande progetto.

define('OneMonth', 2592000);
define('OneWeek', 604800);  
define('OneDay', 86400);
define('OneHour', 3600);    
define('OneMinute', 60);

function SecondsToTime($seconds, $num_units=3) {        
    $time_descr = array(
                "months" => floor($seconds / OneMonth),
                "weeks" => floor(($seconds%OneMonth) / OneWeek),
                "days" => floor(($seconds%OneWeek) / OneDay),
                "hours" => floor(($seconds%OneDay) / OneHour),
                "mins" => floor(($seconds%OneHour) / OneMinute),
                "secs" => floor($seconds%OneMinute),
                );  

    $res = "";
    $counter = 0;

    foreach ($time_descr as $k => $v) {
        if ($v) {
            $res.=$v." ".$k;
            $counter++;
            if($counter>=$num_units)
                break;
            elseif($counter)
                $res.=", ";             
        }
    }   
    return $res;
}

Sentiti libero di votare, ma assicurati di provarlo nel tuo codice. Potrebbe essere proprio quello di cui hai bisogno.


0

La soluzione per questo che ho usato (tornando ai giorni mentre imparavo PHP) senza alcuna funzione interna:

$days = (int)($uptime/86400); //1day = 86400seconds
$rdays = (uptime-($days*86400)); 
//seconds remaining after uptime was converted into days
$hours = (int)($rdays/3600);//1hour = 3600seconds,converting remaining seconds into hours
$rhours = ($rdays-($hours*3600));
//seconds remaining after $rdays was converted into hours
$minutes = (int)($rhours/60); // 1minute = 60seconds, converting remaining seconds into minutes
echo "$days:$hours:$minutes";

Sebbene questa fosse una vecchia domanda, i nuovi studenti che si imbattono in questo, potrebbero trovare utile questa risposta.


0
a=int(input("Enter your number by seconds "))
d=a//(24*3600)   #Days
h=a//(60*60)%24  #hours
m=a//60%60       #minutes
s=a%60           #seconds
print("Days ",d,"hours ",h,"minutes ",m,"seconds ",s)

0

Sto modificando uno dei codici per farlo funzionare bene quando arriva un valore negativo. floor()la funzione non fornisce il conteggio corretto quando il valore è negativo. Quindi dobbiamo usare la abs()funzione prima di usarla nella floor()funzione. $inputSecondsvariabile può essere la differenza tra il timestamp corrente e la data richiesta.

/** 
 * Convert number of seconds into hours, minutes and seconds 
 * and return an array containing those values 
 * 
 * @param integer $inputSeconds Number of seconds to parse 
 * @return array 
 */ 

function secondsToTime($inputSeconds) {

    $secondsInAMinute = 60;
    $secondsInAnHour  = 60 * $secondsInAMinute;
    $secondsInADay    = 24 * $secondsInAnHour;

    // extract days
    $days = abs($inputSeconds / $secondsInADay);
    $days = floor($days);

    // extract hours
    $hourSeconds = $inputSeconds % $secondsInADay;
    $hours = abs($hourSeconds / $secondsInAnHour);
    $hours = floor($hours);

    // extract minutes
    $minuteSeconds = $hourSeconds % $secondsInAnHour;
    $minutes = abs($minuteSeconds / $secondsInAMinute);
    $minutes = floor($minutes);

    // extract the remaining seconds
    $remainingSeconds = $minuteSeconds % $secondsInAMinute;
    $seconds = abs($remainingSeconds);
    $seconds = ceil($remainingSeconds);

    // return the final array
    $obj = array(
        'd' => (int) $days,
        'h' => (int) $hours,
        'm' => (int) $minutes,
        's' => (int) $seconds,
    );
    return $obj;
}

0

Una variazione sulla risposta di @ Glavić: questa nasconde gli zeri iniziali per risultati più brevi e utilizza i plurali nei posti corretti. Rimuove anche la precisione non necessaria (ad esempio, se la differenza di orario è superiore a 2 ore, probabilmente non ti interessa quanti minuti o secondi).

function secondsToTime($seconds)
{
    $dtF = new \DateTime('@0');
    $dtT = new \DateTime("@$seconds");
    $dateInterval = $dtF->diff($dtT);
    $days_t = 'day';
    $hours_t = 'hour';
    $minutes_t = 'minute';
    $seconds_t = 'second';
    if ((int)$dateInterval->d > 1) {
        $days_t = 'days';
    }
    if ((int)$dateInterval->h > 1) {
        $hours_t = 'hours';
    }
    if ((int)$dateInterval->i > 1) {
        $minutes_t = 'minutes';
    }
    if ((int)$dateInterval->s > 1) {
        $seconds_t = 'seconds';
    }


    if ((int)$dateInterval->d > 0) {
        if ((int)$dateInterval->d > 1 || (int)$dateInterval->h === 0) {
            return $dateInterval->format("%a $days_t");
        } else {
            return $dateInterval->format("%a $days_t, %h $hours_t");
        }
    } else if ((int)$dateInterval->h > 0) {
        if ((int)$dateInterval->h > 1 || (int)$dateInterval->i === 0) {
            return $dateInterval->format("%h $hours_t");
        } else {
            return $dateInterval->format("%h $hours_t, %i $minutes_t");
        }
    } else if ((int)$dateInterval->i > 0) {
        if ((int)$dateInterval->i > 1 || (int)$dateInterval->s === 0) {
            return $dateInterval->format("%i $minutes_t");
        } else {
            return $dateInterval->format("%i $minutes_t, %s $seconds_t");
        }
    } else {
        return $dateInterval->format("%s $seconds_t");
    }

}
php > echo secondsToTime(60);
1 minute
php > echo secondsToTime(61);
1 minute, 1 second
php > echo secondsToTime(120);
2 minutes
php > echo secondsToTime(121);
2 minutes
php > echo secondsToTime(2000);
33 minutes
php > echo secondsToTime(4000);
1 hour, 6 minutes
php > echo secondsToTime(4001);
1 hour, 6 minutes
php > echo secondsToTime(40001);
11 hours
php > echo secondsToTime(400000);
4 days

0

Non so perché alcune di queste risposte siano ridicolmente lunghe o complesse. Eccone uno che utilizza la classe DateTime . Un po 'simile alla risposta di Radzserg. Questo mostrerà solo le unità necessarie e i tempi negativi avranno il suffisso 'fa' ...

function calctime($seconds = 0) {

    $datetime1 = date_create("@0");
    $datetime2 = date_create("@$seconds");
    $interval = date_diff($datetime1, $datetime2);

    if ( $interval->y >= 1 ) $thetime[] = pluralize( $interval->y, 'year' );
    if ( $interval->m >= 1 ) $thetime[] = pluralize( $interval->m, 'month' );
    if ( $interval->d >= 1 ) $thetime[] = pluralize( $interval->d, 'day' );
    if ( $interval->h >= 1 ) $thetime[] = pluralize( $interval->h, 'hour' );
    if ( $interval->i >= 1 ) $thetime[] = pluralize( $interval->i, 'minute' );
    if ( $interval->s >= 1 ) $thetime[] = pluralize( $interval->s, 'second' );

    return isset($thetime) ? implode(' ', $thetime) . ($interval->invert ? ' ago' : '') : NULL;
}

function pluralize($count, $text) {
    return $count . ($count == 1 ? " $text" : " ${text}s");
}

// Examples:
//    -86400 = 1 day ago
//     12345 = 3 hours 25 minutes 45 seconds
// 987654321 = 31 years 3 months 18 days 4 hours 25 minutes 21 seconds

EDIT: se vuoi condensare l'esempio sopra per usare meno variabili / spazio (a scapito della leggibilità), ecco una versione alternativa che fa la stessa cosa:

function calctime($seconds = 0) {
    $interval = date_diff(date_create("@0"),date_create("@$seconds"));

    foreach (array('y'=>'year','m'=>'month','d'=>'day','h'=>'hour','i'=>'minute','s'=>'second') as $format=>$desc) {
        if ($interval->$format >= 1) $thetime[] = $interval->$format . ($interval->$format == 1 ? " $desc" : " {$desc}s");
    }

    return isset($thetime) ? implode(' ', $thetime) . ($interval->invert ? ' ago' : '') : NULL;
}

Potresti voler aggiungere sicurezza alla funzione calctime per proteggerti da 0 secondi. Il codice corrente genera un errore. Avvolgere $thetimenel ritorno, ad esempio,isset($thetime)
Verme di

Grazie per il suggerimento, hai ragione sull'errore (non posso credere di essermi perso). Ho aggiornato il codice di conseguenza!
Jason

-1
foreach ($email as $temp => $value) {
    $dat = strtotime($value['subscription_expiration']); //$value come from mysql database
//$email is an array from mysqli_query()
    $date = strtotime(date('Y-m-d'));

    $_SESSION['expiry'] = (((($dat - $date)/60)/60)/24)." Days Left";
//you will get the difference from current date in days.
}

$ value proviene dal database. Questo codice è in Codeigniter. $ SESSION viene utilizzato per memorizzare le sottoscrizioni degli utenti. è obbligatorio. L'ho usato nel mio caso, puoi usare quello che vuoi.


1
Puoi aggiungere qualche altra spiegazione al tuo codice? Da dove $valueviene? Perché mi hai chiesto di introdurre una sessione? In che modo restituisce la stringa corretta per secondi, minuti e ore?
Nico Haase,

Risposta di @NicoHaase aggiornata.
Tayyab Hayat

-2

Questa è una funzione che ho utilizzato in passato per sottrarre una data da un'altra relativa alla tua domanda, il mio principio era di ottenere quanti giorni, ore, minuti e secondi mancano alla scadenza di un prodotto:

$expirationDate = strtotime("2015-01-12 20:08:23");
$toDay = strtotime(date('Y-m-d H:i:s'));
$difference = abs($toDay - $expirationDate);
$days = floor($difference / 86400);
$hours = floor(($difference - $days * 86400) / 3600);
$minutes = floor(($difference - $days * 86400 - $hours * 3600) / 60);
$seconds = floor($difference - $days * 86400 - $hours * 3600 - $minutes * 60);

echo "{$days} days {$hours} hours {$minutes} minutes {$seconds} seconds";
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.