Chciałbym zamienić zmienną, $uptime
która jest sekundami, na dni, godziny, minuty i sekundy.
Przykład:
$uptime = 1640467;
Wynik powinien być:
18 days 23 hours 41 minutes
Można to osiągnąć z DateTime
klasą
Posługiwać się:
echo secondsToTime(1640467);
# 18 days, 23 hours, 41 minutes and 7 seconds
Funkcjonować:
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');
}
@
oznacza przekazanie jako argument doDateTime
konstruktora?@
to unix timestamp.Jest to funkcja przepisana na dni. Zmieniłem też nazwy zmiennych, aby kod był łatwiejszy do zrozumienia ...
/** * 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; }
Źródło: CodeAid () - http://codeaid.net/php/convert-seconds-to-hours-minutes-and-seconds-(php)
źródło
Na podstawie odpowiedzi Juliana Moreno, ale zmieniono ją tak, aby odpowiedź była podawana jako ciąg (nie tablica), zawiera tylko wymagane przedziały czasowe i nie przyjmuje liczby mnogiej.
Różnica między tą a najwyższą głosowaną odpowiedzią to:
Dla
259264
sekund, kod ten dałbyDla
259264
sekund, najwyższa głosowało odpowiedź (o Glavic) dałobyfunction 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); }
Mam nadzieję, że to komuś pomoże.
źródło
Oto prosta 8-liniowa funkcja PHP, która konwertuje liczbę sekund na czytelny dla człowieka ciąg, w tym liczbę miesięcy dla dużej ilości sekund:
Funkcja 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"; }
źródło
gmdate("d H:i:s",1640467);
Wynik będzie 19 23:41:07. Gdy jest to tylko jedna sekunda dłużej niż normalny dzień, zwiększa wartość dnia o 1 dzień. Dlatego pokazuje 19. Możesz eksplodować wynik dla swoich potrzeb i naprawić to.
źródło
$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];
To również da ci informacje o roku i miesiącu.Jest tu kilka bardzo dobrych odpowiedzi, ale żadna z nich nie zaspokoiła moich potrzeb. I zbudowany na odpowiedź Glavic użytkownika , aby dodać kilka dodatkowych funkcji, że jest to potrzebne;
Możesz zobaczyć działającą wersję kodu 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; }
źródło
Krótki, prosty, niezawodny:
function secondsToDHMS($seconds) { $s = (int)$seconds; return sprintf('%d:%02d:%02d:%02d', $s/86400, $s/3600%24, $s/60%60, $s%60); }
źródło
Najprostszym podejściem byłoby utworzenie metody, która zwraca DateInterval z DateTime :: diff czasu względnego w sekundach od bieżącego czasu $ now, którą można następnie łączyć i formatować. Na przykład:-
public function toDateInterval($seconds) { return date_create('@' . (($now = time()) + $seconds))->diff(date_create('@' . $now)); }
Teraz połącz wywołanie metody w łańcuch DateInterval :: format
echo $this->toDateInterval(1640467)->format('%a days %h hours %i minutes'));
Wynik:
18 days 23 hours 41 minutes
źródło
Chociaż jest to dość stare pytanie - mogą się przydać te (nie napisane jako szybkie):
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']);
wynik:
0d21h57m13s 21h57m13s 9d21h57m13s
źródło
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); }
źródło
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);
źródło
Rozwiązanie, które powinno wykluczać wartości 0 i ustawiać prawidłowe wartości w liczbie pojedynczej / mnogiej
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); } }
źródło
rozszerzona wersja doskonałego rozwiązania Glavića , posiadająca walidację liczb całkowitych, rozwiązanie problemu 1 s i dodatkowe wsparcie przez lata i miesiące, kosztem mniej przyjaznego przetwarzania komputerowego na korzyść bycia bardziej przyjaznym dla człowieka:
<?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"
źródło
Można użyć napisanej przeze mnie klasy interwału. Może być również używany w odwrotny sposób.
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');
Więcej informacji tutaj https://github.com/LubosRemplik/CakePHP-Interval
źródło
Z 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
źródło
Nie wiem, dlaczego niektóre z tych odpowiedzi są absurdalnie długie lub złożone. Oto przykład używający klasy DateTime . Coś podobnego do odpowiedzi radzserga. Spowoduje to wyświetlenie tylko niezbędnych jednostek, a ujemne czasy będą miały przyrostek „temu” ...
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
EDYCJA: Jeśli chcesz skondensować powyższy przykład, aby użyć mniej zmiennych / spacji (kosztem czytelności), oto alternatywna wersja, która robi to samo:
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; }
źródło
$thetime
W zamian zawijaj , np.isset($thetime)
Oto kod, którego lubię używać w celu uzyskania czasu trwania między dwiema datami. Akceptuje dwie daty i daje ładną, strukturalną odpowiedź.
To jest nieco zmodyfikowana wersja kodu znalezionego tutaj .
<?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'; }
Źródło: https://gist.github.com/ozh/8169202
źródło
Wszystko w jednym rozwiązaniu. Nie podaje jednostek z zerami. Wyprodukuje tylko określoną liczbę jednostek (domyślnie 3). Dość długi, może niezbyt elegancki. Definicje są opcjonalne, ale mogą się przydać w dużym projekcie.
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; }
Możesz głosować negatywnie, ale pamiętaj, aby wypróbować to w swoim kodzie. To może być właśnie to, czego potrzebujesz.
źródło
Rozwiązanie dla tego, którego używałem (do czasów, kiedy uczyłem się PHP) bez żadnych funkcji:
$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";
Chociaż było to stare pytanie, nowi uczniowie, którzy się z nim spotkają, mogą uznać tę odpowiedź za przydatną.
źródło
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)
źródło
Edytuję jeden z kodów, aby działał dobrze, gdy pojawia się wartość ujemna.
floor()
funkcja nie podaje poprawnej liczby, gdy wartość jest ujemna. Musimy więc użyćabs()
funkcji przed użyciem jej wfloor()
funkcji.$inputSeconds
zmienna może być różnicą między aktualnym znacznikiem czasu a wymaganą datą./** * 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; }
źródło
Odmiana odpowiedzi @ Glavić - ta ukrywa wiodące zera dla krótszych wyników i używa liczby mnogiej w odpowiednich miejscach. Eliminuje również niepotrzebną precyzję (np. Jeśli różnica czasu przekracza 2 godziny, prawdopodobnie nie obchodzi Cię, ile minut lub sekund).
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
źródło
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. }
Wartość $ pochodzi z bazy danych. Ten kod jest w Codeigniter. $ SESSION służy do przechowywania subskrypcji użytkowników. jest to obowiązkowe. Użyłem go w moim przypadku, możesz użyć, co chcesz.
źródło
$value
bierze? Dlaczego chciałeś wprowadzić sesję? W jaki sposób zwraca to właściwy ciąg dla sekund, minut i godzin?Jest to funkcja, której użyłem w przeszłości do odejmowania daty od innej związanej z Twoim pytaniem, moim głównym założeniem było sprawdzenie, ile dni, godzin, minut i sekund pozostało do wygaśnięcia produktu:
$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";
źródło