PHP - конвертировать миллисекунды в часы: минуты: секунды. - PullRequest
10 голосов
/ 21 января 2011

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

$seconds_input = 23.75

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

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

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

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

Где 'x' - это доля секунды (однако после десятичной точки есть много мест).

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

Спасибо.

Ответы [ 4 ]

20 голосов
/ 21 января 2011

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

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');
}
17 голосов
/ 22 января 2011

Мой дубль

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
3 голосов
/ 22 января 2011

Мой намного менее читабелен, поэтому он должен быть лучше. : 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);
1 голос
/ 22 января 2011

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

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

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

?> и т. д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...