Risposte:
Questo può essere ottenuto con la DateTime
classe
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');
}
@
significa quando viene passato come argomento al DateTime
costruttore?
@
è unix timestamp.
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)
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 259264
secondi, questo codice darebbe
3 giorni, 1 minuto, 4 secondi
Per 259264
secondi, 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.
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:
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";
}
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.
$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.
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;
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;
}
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);
}
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
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
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);
}
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);
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);
}
}
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"
È 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
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
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';
}
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.
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.
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)
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.
$inputSeconds
variabile 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;
}
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
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;
}
$thetime
nel ritorno, ad esempio,isset($thetime)
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.
$value
viene? Perché mi hai chiesto di introdurre una sessione? In che modo restituisce la stringa corretta per secondi, minuti e ore?
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";