2011-01-21 12 views
10

Mam skrypt, który pobiera wartość w sekundach (do 2 punktów dziesiętne ułamków sekund):PHP - Konwersja milisekund do godziny: minuty: Seconds.fractional

$seconds_input = 23.75 

I następnie przekształcić go do milisekund:

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

A potem chcę sformatować go tak:

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

Gdzie 'x' jest fracti on of the second (jednak wiele miejsc po przecinku).

Każda pomoc? Nie mogę o tym myśleć. Próbowałem użyć polecenia gmdate(), ale nie odrywałem ułamków sekund.

Dzięki.

+0

http://us.php.net/manual/en/function.sprintf.php – scragz

+0

Chciałem tylko dodać, że było to wytwarzanie wartości wejściowej dla pola -ss FFMPEG. Uwzględniając ułamkowe sekundy, poprawia ziarnistość docelowej klatki i daje użytkownikowi prawie * dokładną * ramkę, którą oglądają w odtwarzaczu wideo. Jeszcze raz dziękuję wszystkim, oszczędziłeś mi mnóstwo czasu. – AJB

Odpowiedz

17

mój wziąć

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

a następnie testu

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

który daje

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

Uwielbiam przepełnienie stosu. Dziękuję wszystkim. Nie jestem nawet pewien, który najbardziej lubię. – AJB

+0

Jestem noob php, stwierdziłem, że @ ircmaxell nie działa dla wszystkich wartości. W moim przypadku wartość ms wynosiła: 1189107. Dostaję około 23 godzin używając funkcji ircmaxell i 00.19: 49 używając twojego. – zengr

17

Edytuj: Cóż, byłem trochę pochopny. Oto jeden sposób zrobienia tego, o co pytasz:

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

Z pewnością nie jest to jedyny sposób, ale jest inteligentny i łatwy. – GolezTrol

+0

Z tego, co gromadzę, mówią o czasie trwania, a nie datetime. – scragz

+0

To może być problem, ale tylko wtedy, gdy czas trwania przekracza 24 godziny. – GolezTrol

2

Moja jest znacznie mniej czytelna, więc musi być lepiej. : p

Zasadniczo ten sam pomysł co wersja @ ircmaxell. Zmniejsza to końcowe '0, a nawet pominie ostatnie'. ' separator jeśli milisekund są 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); 
+3

LOL @ * Mine jest dużo mniej czytelny, więc musi być lepiej. : p * ... – ircmaxell

+0

Uwielbiam przepełnienie stosu. Dziękuję wszystkim. Nie jestem nawet pewien, który najbardziej lubię. – AJB

1

jeśli naprawdę chcesz to zrobić za pomocą Funkcja daty masz rację, musisz poradzić sobie z dowcipem h milisekundy na zewnątrz opierają się tylko na second-timestampach.

mógłby zrobić coś takiego:

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

jednak zdawać sobie sprawę z godzinnym-przelewem, jeśli przekracza 24 godzin będzie prawdopodobnie skończyć wyrzuceniem dni.

w przypadku powiedziałbym swoje podejście z podłogi, aby uzyskać sekund jest poprawna, a następnie należy prawdopodobnie wystarczy użyć arytmetyki modulo tak:

<? 
$totalsecs = 86400*10; 

$secs = $totalsecs%60; 

echo "secs: $secs \n"; 

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

> i tak dalej ..

+0

Uwielbiam przepełnienie stosu. Dziękuję wszystkim. Nie jestem nawet pewien, który najbardziej lubię. – AJB

Powiązane problemy