Я хотел бы преобразовать переменную, $uptime
которая представляет собой секунды, в дни, часы, минуты и секунды.
Пример:
$uptime = 1640467;
Результат должен быть:
18 days 23 hours 41 minutes
Этого можно добиться с помощью DateTime
класса
Использование:
echo secondsToTime(1640467);
# 18 days, 23 hours, 41 minutes and 7 seconds
Функция:
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');
}
@
означает передача в качестве аргументаDateTime
конструктору?@
- это временная метка unix.Эта функция переписана и теперь включает дни. Я также изменил имена переменных, чтобы код было легче понять ...
/** * 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; }
Источник: CodeAid () - http://codeaid.net/php/convert-seconds-to-hours-minutes-and-seconds-(php)
источник
На основе ответа Джулиана Морено, но измененного, чтобы дать ответ в виде строки (а не массива), включать только требуемые временные интервалы и не предполагать множественное число.
Разница между этим ответом и ответом, получившим наибольшее количество голосов:
На
259264
несколько секунд этот код дастНа
259264
несколько секунд ответ , получивший наибольшее количество голосов (Главича) , дал бы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); }
Я надеюсь, что это помогает кому-то.
источник
Вот простая 8-строчная функция PHP, которая преобразует количество секунд в удобочитаемую строку, включая количество месяцев для большого количества секунд:
Функция 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"; }
источник
gmdate("d H:i:s",1640467);
Результат будет 19 23:41:07. Когда он всего на одну секунду больше обычного дня, значение дня увеличивается на 1 день. Вот почему отображается 19. Вы можете изменить результат под свои нужды и исправить это.
источник
$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];
Это также даст вам информацию о году и месяце.Здесь есть несколько очень хороших ответов, но ни один из них не удовлетворил мои потребности. Я построил на ответе Главича, чтобы добавить некоторые дополнительные функции, которые мне нужны;
Вы можете увидеть работающую версию кода 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; }
источник
Коротко, просто, надежно:
function secondsToDHMS($seconds) { $s = (int)$seconds; return sprintf('%d:%02d:%02d:%02d', $s/86400, $s/3600%24, $s/60%60, $s%60); }
источник
Самый простой подход - создать метод, который возвращает DateInterval из DateTime :: diff относительного времени в $ секундах от текущего времени $ now, которое затем можно связать и отформатировать. Например:-
public function toDateInterval($seconds) { return date_create('@' . (($now = time()) + $seconds))->diff(date_create('@' . $now)); }
Теперь свяжите вызов вашего метода с DateInterval :: format
echo $this->toDateInterval(1640467)->format('%a days %h hours %i minutes'));
Результат:
18 days 23 hours 41 minutes
источник
Хотя это довольно старый вопрос - можно найти эти полезные (написанные не для быстрой работы):
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']);
результат:
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);
источник
Решение, которое должно исключить 0 значений и установить правильные значения в единственном / множественном числе
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); } }
источник
расширенная версия отличного решения Glavić , имеющая целочисленную проверку, решение проблемы 1 с и дополнительную поддержку в течение многих лет и месяцев, за счет того, что она менее дружественна к компьютерному синтаксическому анализу в пользу более дружественной к человеку:
<?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"
источник
Можно использовать записанный мной интервальный класс. Его можно использовать и наоборот.
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');
Подробнее здесь https://github.com/LubosRemplik/CakePHP-Interval
источник
С 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
источник
Я не знаю, почему некоторые из этих ответов смехотворно длинные или сложные. Вот тот, который использует класс DateTime . Вроде как ответ Радзерг. Это отобразит только необходимые единицы, а отрицательное время будет иметь суффикс «назад» ...
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
РЕДАКТИРОВАТЬ: если вы хотите сократить приведенный выше пример, чтобы использовать меньше переменных / пространства (за счет удобочитаемости), вот альтернативная версия, которая делает то же самое:
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
в ответ, например,isset($thetime)
Вот код, который мне нравится использовать для определения продолжительности между двумя датами. Он принимает две даты и дает хороший структурированный ответ.
Это немного измененная версия кода, найденного здесь .
<?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'; }
Источник: https://gist.github.com/ozh/8169202
источник
Все в одном решении. Не дает единиц с нулями. Будет производиться только указанное вами количество единиц (по умолчанию 3). Довольно долго, возможно, не очень элегантно. Определения не являются обязательными, но могут пригодиться в большом проекте.
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; }
Не стесняйтесь голосовать против, но обязательно попробуйте это в своем коде. Возможно, это именно то, что вам нужно.
источник
Решение для этого, которое я использовал (во времена изучения PHP) без каких-либо встроенных функций:
$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";
Хотя это был старый вопрос, новые учащиеся, столкнувшиеся с ним, могут найти этот ответ полезным.
источник
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)
источник
Я редактирую один из кодов, чтобы он работал хорошо, когда приходит отрицательное значение.
floor()
функция не дает правильного подсчета, когда значение отрицательное. Поэтому нам нужно использоватьabs()
функцию, прежде чем использовать ее вfloor()
функции.$inputSeconds
переменная может быть разницей между текущей отметкой времени и требуемой датой./** * 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; }
источник
Вариант ответа @ Glavić - этот скрывает ведущие нули для более коротких результатов и использует множественное число в правильных местах. Это также устраняет ненужную точность (например, если разница во времени превышает 2 часа, вам, вероятно, все равно, сколько минут или секунд).
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
источник
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. }
Значение $ поступает из базы данных. Этот код находится в Codeigniter. $ SESSION используется для хранения подписок пользователей. это обязательно. Я использовал его в своем случае, вы можете использовать все, что хотите.
источник
$value
взялось? Зачем вам нужно вводить сеанс? Как это возвращает правильную строку для секунд, минут и часов?Это функция, которую я использовал в прошлом для вычитания даты из другой даты, связанной с вашим вопросом, мой принцип заключался в том, чтобы узнать, сколько дней, часов, минут и секунд осталось до истечения срока годности продукта:
$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";
источник