PHP – конвертировать миллисекунды в часы: минуты: секунды.

У меня есть сценарий, который принимает значение в секундах (до 2 десятичных знаков дробных секунд):

$seconds_input = 23.75 

Затем я конвертирую его в миллисекунды:

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

И тогда я хочу отформатировать его так:

 H:M:Sx // --> 0:0:23.75 

Где «х» – это доля второго (сколько бы ни было после десятичного числа мест).

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

Благодарю.

    Мой прием

     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 

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

     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'); } 

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

    В основном та же идея, что и версия 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); 

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

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

     <? $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); 

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