【问题标题】:PHP — Convert milliseconds to Hours : Minutes : Seconds.fractionalPHP - 将毫秒转换为小时:分钟:Seconds.fractional
【发布时间】:2011-06-13 09:58:35
【问题描述】:

我有一个脚本,它以秒为单位(精确到小数秒的 2 个小数点):

$seconds_input = 23.75

然后我将其转换为毫秒:

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

然后我想像这样格式化它:

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

其中“x”是秒的小数(无论小数点后有多少位)。

有什么帮助吗?我似乎无法解决这个问题。我尝试使用 gmdate(),但它一直在减少小数秒。

谢谢。

【问题讨论】:

  • 只是想补充一点,这是为 FFMPEG 的 -ss 字段生成一个输入值。通过包含小数秒,它提高了目标帧的粒度,并为用户提供了他们在视频播放器中查看的几乎确切帧。再次感谢大家,你们为我节省了大量时间。

标签: php milliseconds seconds


【解决方案1】:

编辑:好吧,我有点仓促。这是执行您要求的一种方法:

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

【讨论】:

  • 当然不是唯一的方法,但它既聪明又简单。
  • 据我所知,他们说的是持续时间,而不是日期时间。
  • 这可能是个问题,但前提是持续时间超过 24 小时。
  • 是的,我一直在尝试这个,我得到 18:Dec:st.0。不过,我认为这是正确的方向,谢谢 ircmaxell。
  • 您需要确保 leading 零包含在毫秒字段中。 1 毫秒应该读取 .001,而不是 .1,这是上面的代码会产生的。
【解决方案2】:

我的看法

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

【讨论】:

  • 我喜欢 Stack Overflow。谢谢大家。我什至不确定我最喜欢哪一个。
  • 我是一个 php 菜鸟,我发现 @ircmaxell 并不适用于所有值。在我的例子中,ms 值是:1189107。我使用 ircmaxell 函数得到大约 23 小时,使用你的函数得到 00.19:49。
  • @Peter Bailey - 我认为第 6 行应该是:if ( $seconds >= 3600 ) - 即如果 $seconds 大于 或等于 3600。这将确保正好 1 小时 -即 3600 秒,输出为01:00:00 而不是00:00:00,无需此调整。谢谢你的功能 - 我正在使用它看门狗日志记录 Drupal 站点的一些性能监控。
【解决方案3】:

我的可读性要差得多,所以它必须更好。 :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);

【讨论】:

    【解决方案4】:

    如果你真的想使用日期函数来做你是对的,你必须在外部处理毫秒,仅基于秒时间戳。

    你可以这样做:

    <?
    $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,您可能最终会放弃这些日子。

    在您的情况下,我会说您使用 floor 来获取秒数的方法是正确的,然后您可能应该只使用这样的模运算:

    <?
    $totalsecs = 86400*10;
    
    $secs = $totalsecs%60;
    
    echo "secs: $secs \n";
    
    $minutes = ($totalsecs - $secs) % (60*60);
    ?>
    

    等等..

    【讨论】:

      猜你喜欢
      • 2018-11-16
      • 2012-09-27
      • 1970-01-01
      • 2013-01-12
      • 2016-06-29
      • 2014-05-21
      • 1970-01-01
      • 2015-05-06
      相关资源
      最近更新 更多