Frage

Ich habe ein Skript, das in Sekunden einen Wert aufnimmt (auf 2 Dezimalpunkte mit fraktionalen Sekunden):

$seconds_input = 23.75

Ich konvertiere es dann in Millisekunden:

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

Und dann möchte ich es so formatieren:

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

Wo 'x' der Bruch der zweiten ist (viele Orte nach der Dezimalzahl sind es auch).

Irgendeine Hilfe? Ich kann mich nicht darum kümmern. Ich habe versucht, gmdate () zu verwenden, aber es hat die Bruchsekunden immer wieder abgelehnt.

Vielen Dank.

War es hilfreich?

Lösung

Meine Einstellung

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

Und dann der 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;
}

welche ergibt

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

Andere Tipps

Bearbeiten: Nun, ich war ein bisschen voreilig. Hier ist eine Möglichkeit, das zu tun, was Sie fragen:

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

Meins ist viel weniger lesbar, also muss es besser sein. :p

Grundsätzlich die gleiche Idee wie die Version von @ircmaxell. Es schneidet die nachverfolgenden "0" und wird sogar das letzte "überspringen". Trennzeichen Wenn Millisekunden 0 sind.

<?

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

Wenn Sie es wirklich mit der Datumsfunktion ausführen möchten, müssen Sie sich extern mit Millisekunden befassen, basiert nur auf zweiten Zahlen.

Sie könnten so etwas tun:

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

Aber seien Sie sich der Stunde über den Fluss bewusst, wenn Ihre Stunden 24 überschreiten, werden Sie wahrscheinlich die Tage verworfen.

In Ihrem Fall würde ich sagen, dass Ihr Ansatz mit dem Boden, um die Sekunden zu erhalten, korrekt ist, und dann sollten Sie wahrscheinlich nur Modulo -Arithmetika wie folgt verwenden:

<?
$totalsecs = 86400*10;

$secs = $totalsecs%60;

echo "secs: $secs \n";

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

?> Und so weiter ..

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top