Преобразование секунд в дни, часы, минуты и секунды
Я хотел бы конвертировать переменную $uptime которая составляет секунды, в дни, часы, минуты и секунды.
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'); >
демонстрация
Это функция, переписанная для включения дней. Я также изменил имена переменных, чтобы сделать код более понятным …
/** * 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; >
Здесь это простая 8-строчная PHP-функция, которая преобразует несколько секунд в удобочитаемую строку, включая количество месяцев в течение большого количества секунд:
Функция PHP seconds2human ()
Основываясь на ответе Джулиана Морено, но изменился, чтобы дать ответ в виде строки (а не массива), включить только промежутки времени и не принимать множественное число.
Разница между этим и самым высоким проголосовавшим ответом:
За 259264 секунд этот код даст
В течение 259264 секунд самый высокий 259264 ответ (по Главичу) дал бы
3 дня, 0 часов , 1 минута с и 4 секунды
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); >
Я надеюсь, что это помогает кому-то.
Результат будет 19 23:41:07. Когда это на одну секунду больше, чем обычный день, увеличивается значение дня на 1 день. Вот почему он показывает 19. Вы можете взорвать результат для своих нужд и исправить это.
Хотя это довольно старый вопрос – можно найти эти полезные (не написанные быстро):
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); >
Самый простой подход – создать метод, который возвращает 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
расширенная версия превосходного решения Glavić , имеющая целую валидацию, решение 1-й проблемы и дополнительную поддержку в течение многих лет и месяцев, за счет того, что компьютерный синтаксический анализ менее дружелюбен в пользу более дружелюбного человека:
$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»
Короткие, простые, надежные:
function secondsToDHMS($seconds) < $s = (int)$seconds; return sprintf('%d:%02d:%02d:%02d', $s/86400, $s/3600%24, $s/60%60, $s%60); >
Решение, которое должно исключать 0 значений и устанавливать правильные значения единственного числа / множественного числа
use DateInterval; use DateTime; class TimeIntervalFormatter < public static function fromSeconds($seconds) < $seconds = (int)$seconds; $dateTime = new DateTime(); $dateTime->sub(new DateInterval("PTS")); $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[] = " "; > return implode(', ', $result); > >
Вот код, который мне нравится использовать для получения продолжительности между двумя датами. Он принимает две даты и дает вам хороший структурированный ответ.
Это немного измененная версия кода, найденного здесь .
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'; >
Все в одном решении. Не дает единиц с нулями. Будет производиться только количество единиц, которые вы укажете (по умолчанию – 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; >
Не стесняйтесь проголосовать, но обязательно попробуйте его в своем коде. Это может быть просто то, что вам нужно.
Можно использовать класс интервала, который я написал. Его можно использовать и наоборот.
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');
Это функция, которую я использовал в прошлом для вычитания даты из другой, связанной с вашим вопросом, мой принцип состоял в том, чтобы узнать, сколько дней, часов и секунд осталось до истечения срока действия продукта:
$expirationDate = strtotime("2015-01-12 20:08:23"); $toDay = strtotime(date('Ymd 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 hours minutes seconds";
Convert Seconds To Hours, Minutes in PHP
Say you’re running a process that runs in the background. It’s better to not let the user lose their patience and tell them when it will finish. But, you have the time remaining in seconds. If we show the user :
He/she (user) would have to take a calculator and convert it into minutes or hours. Or if the guy/gal is not a math genius, he would close the UI and say «What the Hell ?»
The primary point in UI is that
Mark my words : «You shouldn’t make the user angry».
Here is a simple function to convert seconds to hours, minutes and seconds separately or mixed together :
If you’re wondering why I chose secToHR as the function name, it’s the abbreviation of Seconds to Human Readable.
Or if you wanna display like this :
1 hour, 20 minutes remaining 10 minutes, 20 seconds remaining 15 seconds remaining
then, replace the return function with this :
return $hours > 0 ? "$hours hours, $minutes minutes remaining" : ($minutes > 0 ? "$minutes minutes, $seconds seconds remaining" : "$seconds seconds remaining");
BTW, I would suggest you do it like above ^, because it’s more user friendly.
Usage
/** * Function with 'h:m:s' form as return value */ echo secToHR(560); echo secToHR(10950); /** * Function with 'remaining' in return value */ echo secToHR();
And the corresponding outputs :
0:9:20 3:2:30 9 minutes, 20 seconds remaining 3 hours, 2 minutes remaining
I have used this in the Downloader App as I mentioned in the previous post.
How to Convert Seconds into Days, Hours and Minutes
I’m going to let you know how to turn second into date format in this quick tutorial, which is a common challenge for web development, in order to convert date into a certain date format.
We must translate the date from timetable to the desired data format by using the date function (timetamp, ‘date format’), to obtain the above results.
However here we convert seconds to a user-specific date format, like we would like to display below.
“14 days, six hours, 56 minutes, seven seconds”
The simple hours formula:
hours = seconds ÷ 3,600
The time in hours is equal to the time in seconds divided by 3,600. Since there are 3,600 seconds in one hour, that’s the conversion ratio used in the formula.
PHP Function to Convert seconds to Days, Hours, Minutes and Seconds
function secsToStr($secs) < if($secs>=86400)<$days=floor($secs/86400);$secs=$secs%86400;$r=$days.' day';if($days<>1)if($secs>0)> if($secs>=3600)<$hours=floor($secs/3600);$secs=$secs%3600;$r.=$hours.' hour';if($hours<>1)if($secs>0)> if($secs>=60)<$minutes=floor($secs/60);$secs=$secs%60;$r.=$minutes.' minute';if($minutes<>1)if($secs>0)> $r.=$secs.' second';if($secs<>1) return $r; >
Simple usage:
echo secsToStr(90360);
Output:
1 day, 1 hour, 6 minutes 0 seconds
Option 2:Convert Seconds to Days, Hours and Minutes
The following code is simple, for turning seconds independently or blended into days, hours and minutes.
function secToDaysHoursMinutes($seconds) < $days = floor($seconds/86400); $hours = floor(($seconds - $days*86400) / 3600); $minutes = floor(($seconds / 60) % 60); return "$days days:$hours hours:$minutes minutes"; >
We have passed a variable $seconds into this method. Then we converted the seconds into hours, minutes, and seconds respectively.
Simple usage:
echo secToDaysHoursMinutes(90360);
Output:
1 days:1 hours:6 minutes