PHP — Convert milliseconds to Hours : Minutes : Seconds.fractional

后端 未结 4 707
长情又很酷
长情又很酷 2020-12-30 04:56

I\'ve got a script that takes in a value in seconds (to 2 decimal points of fractional seconds):

$seconds_input = 23.75

I then convert it t

相关标签:
4条回答
  • 2020-12-30 05:10

    My take

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

    And then the test

    $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;
    }
    

    which yields

    00:00:23
    00:00:23.75
    00:00:23.75123456789
    34293:33:09.75
    
    0 讨论(0)
  • 2020-12-30 05:14

    Edit: Well, I was a bit hasty. Here's one way to do what you're asking:

    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 讨论(0)
  • 2020-12-30 05:19

    Mine is much less readable, so it must be better. :p

    Basically the same idea as @ircmaxell's version. It does trim the trailing '0's and even will skip the last '.' separator if milliseconds are 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);
    
    0 讨论(0)
  • 2020-12-30 05:31

    if you really want to do it using date function you are right, you have to deal with milliseconds externally, is only based on second-timestamps.

    you could do something like this:

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

    but be aware of the hour-overflow, if your hours exceed 24 you will probably end up discarding the days.

    in your case i would say your approach with floor to get the seconds is correct, and then you should probably just use modulo arithmetics like this:

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

    ?> and so on..

    0 讨论(0)
提交回复
热议问题