2011-01-21 10 views
10

У меня есть скрипт, который принимает в значении в секундах (до 2 десятичных точек доли секунды):PHP - Преобразование миллисекунд до нескольких часов: минуты: Seconds.fractional

$seconds_input = 23.75 

Я затем преобразовать его в миллисекунды:

$milliseconds = $seconds_input * 1000; // --> 23750 

И тогда я хочу, чтобы отформатировать его следующим образом:

H:M:S.x // --> 0:0:23.75 

Где 'х' является fracti на втором (однако много мест после десятичного числа).

Любая помощь? Кажется, я не могу обдумать это. Я попытался использовать gmdate(), но он продолжал отрываться от дробных секунд.

Спасибо.

+0

http://us.php.net/manual/en/function.sprintf.php – scragz

+0

Просто хотелось добавить, что это было для создания входного значения для поля -ss FFMPEG. Включая дробные секунды, он улучшает гранулярность целевого кадра и дает пользователю почти точный * кадр, который они ищут в видеоплеере. Еще раз спасибо, вы спасли мне тонну времени. – AJB

ответ

17

Моя принять

function formatSeconds($seconds) 
{ 
    $hours = 0; 
    $milliseconds = str_replace("0.", '', $seconds - floor($seconds)); 

    if ($seconds > 3600) 
    { 
    $hours = floor($seconds/3600); 
    } 
    $seconds = $seconds % 3600; 


    return str_pad($hours, 2, '0', STR_PAD_LEFT) 
     . gmdate(':i:s', $seconds) 
     . ($milliseconds ? ".$milliseconds" : '') 
    ; 
} 

, а затем тест

$testData = array(
    23,    // Seconds, w/o millis 
    23.75,   // Seconds, w/millis 
    23.75123456789, // Lots of millis 
    123456789.75 // Lots of seconds 
); 

foreach ($testData as $seconds) 
{ 
    echo formatSeconds($seconds), PHP_EOL; 
} 

, который дает

00:00:23 
00:00:23.75 
00:00:23.75123456789 
34293:33:09.75 
+1

Я люблю переполнение стека. Спасибо всем. Я даже не уверен, какой из них мне больше всего нравится. – AJB

+0

Я php noob, я обнаружил, что @ ircmaxell не работает для всех значений. В моем случае значение ms было: 1189107. Я получаю около 23 часов, используя функцию ircmaxell и 00.19: 49, используя ваши. – zengr

17

Редактировать: Ну, я был немного поспешным. Вот один из способов сделать то, что вы просите:

function formatMilliseconds($milliseconds) { 
    $seconds = floor($milliseconds/1000); 
    $minutes = floor($seconds/60); 
    $hours = floor($minutes/60); 
    $milliseconds = $milliseconds % 1000; 
    $seconds = $seconds % 60; 
    $minutes = $minutes % 60; 

    $format = '%u:%02u:%02u.%03u'; 
    $time = sprintf($format, $hours, $minutes, $seconds, $milliseconds); 
    return rtrim($time, '0'); 
} 
+0

Конечно, не единственный способ, но он умный и легкий. – GolezTrol

+0

Из того, что я собираю, они говорят о длительности, хотя, а не о времени. – scragz

+0

Это может быть проблемой, но только если продолжительность составляет более 24 часов. – GolezTrol

2

Шахта гораздо менее читаема, поэтому она должна быть лучше. : p

В принципе та же идея, что и версия ircmaxell. Он обрезает конечные «0» и даже пропустит последний ». Сепаратор если миллисекунды 0.

<? 

function format_period($seconds_input) 
{ 
    $hours = (int)($minutes = (int)($seconds = (int)($milliseconds = (int)($seconds_input * 1000))/1000)/60)/60; 
    return $hours.':'.($minutes%60).':'.($seconds%60).(($milliseconds===0)?'':'.'.rtrim($milliseconds%1000, '0')); 
} 

echo format_period(23.75); 
+3

LOL @ * Mine гораздо менее читабельна, поэтому должно быть лучше. : p * ... – ircmaxell

+0

Я люблю переполнение стека. Спасибо всем. Я даже не уверен, какой из них мне больше всего нравится. – AJB

1

, если вы действительно хотите сделать это с помощью функция даты вы правы, вам нужно иметь дело с остроумием h миллисекунд извне, основано только на секундах.

вы могли бы сделать что-то вроде этого:

<? 
$input = "23.75"; 
$seconds = floor($input); 
$date = DateTime::createFromFormat('s', floor($seconds)); 
$ms = ($input-$seconds); 
if($ms == 0) { 
$ms = ""; 
} else { 
$ms = ltrim($ms,"0,"); 
} 
echo $date->format('H:i:s').$ms; 

, но быть в курсе час-переливом, если ваши часы превышает 24 вы, вероятно, в конечном итоге отбрасывая дни.

в вашем случае я бы сказал, ваш подход с пола, чтобы получить секунд правильно, и тогда вы, вероятно, следует использовать только по модулю арифметика, как это:

<? 
$totalsecs = 86400*10; 

$secs = $totalsecs%60; 

echo "secs: $secs \n"; 

$minutes = ($totalsecs - $secs) % (60*60); 

> и так далее ..

+0

Я люблю переполнение стека. Спасибо всем. Я даже не уверен, какой из них мне больше всего нравится. – AJB