402 Stimmen

Sekunden in HH-MM-SS mit JavaScript konvertieren?

Wie kann ich die Sekunden in eine HH-MM-SS Zeichenfolge mit JavaScript?

26voto

Dima L. Punkte 3143

Hier ist eine einfache Funktion zur Konvertierung von Zeiten, die helfen könnte

function formatSeconds(seconds) {
    var date = new Date(1970,0,1);
    date.setSeconds(seconds);
    return date.toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");
}

19voto

Waggers Punkte 606

Das ist der Trick:

function secondstotime(secs)
{
    var t = new Date(1970,0,1);
    t.setSeconds(secs);
    var s = t.toTimeString().substr(0,8);
    if(secs > 86399)
        s = Math.floor((t - Date.parse("1/1/70")) / 3600000) + s.substr(2);
    return s;
}

(Entnommen aus aquí )

15voto

Sheelpriy Punkte 1645
var  timeInSec = "661"; //even it can be string

String.prototype.toHHMMSS = function () { 
   /* extend the String by using prototypical inheritance */
    var seconds = parseInt(this, 10); // don't forget the second param
    var hours   = Math.floor(seconds / 3600);
    var minutes = Math.floor((seconds - (hours * 3600)) / 60);
    seconds = seconds - (hours * 3600) - (minutes * 60);

    if (hours   < 10) {hours   = "0"+hours;}
    if (minutes < 10) {minutes = "0"+minutes;}
    if (seconds < 10) {seconds = "0"+seconds;}
    var time    = hours+':'+minutes+':'+seconds;
    return time;
}

alert("5678".toHHMMSS());   // "01:34:38"
console.log(timeInSec.toHHMMSS());   //"00:11:01"

wir können diese Funktion viel kürzer und knackiger machen, aber das verringert die Lesbarkeit, also werden wir sie so einfach wie möglich und so stabil wie möglich schreiben.

oder Sie können diese Funktion überprüfen aquí :

12voto

Petr Újezdský Punkte 1152

Ich denke, die allgemeinste (und kryptischste) Lösung könnte so aussehen

function hms(seconds) {
  return [3600, 60]
    .reduceRight(
      (pipeline, breakpoint) => remainder =>
        [Math.floor(remainder / breakpoint)].concat(pipeline(remainder % breakpoint)),
      r => [r]
    )(seconds)
    .map(amount => amount.toString().padStart(2, '0'))
    .join('-');
}

Oder um die kürzeste Version zu kopieren und einzufügen

function hms(seconds) {
  return [3600, 60]
    .reduceRight(
      (p, b) => r => [Math.floor(r / b)].concat(p(r % b)),
      r => [r]
    )(seconds)
    .map(a => a.toString().padStart(2, '0'))
    .join('-');
}

Einige Beispielausgaben:

> hms(0)
< "00-00-00"

> hms(5)
< "00-00-05"

> hms(60)
< "00-01-00"

> hms(3785)
< "01-03-05"

> hms(37850)
< "10-30-50"

> hms(378500)
< "105-08-20"

Wie es funktioniert

Algorithmus

  1. Um die Stunden zu erhalten, dividiert man die Gesamtsekunden durch 3600 und addiert das Ergebnis.
  2. Um die Minuten zu erhalten, teilen Sie Restbetrag um 60 zu erhöhen und den Wert zu senken.
  3. Um Nachschlag zu erhalten, verwenden Sie einfach den Restbetrag.

Es wäre auch schön, wenn die einzelnen Beträge zur einfacheren Formatierung in einem Array gespeichert werden könnten.

Bei einer Eingabe von 3785s sollte die Ausgabe zum Beispiel wie folgt aussehen [1, 3, 5] Das sind 1 Stunde, 3 Minuten und 5 Sekunden.

Pipeline erstellen

Wenn Sie die Konstanten 3600 und 60 "Haltepunkte" nennen, können Sie diesen Algorithmus wie folgt in eine Funktion schreiben

function divideAndAppend(remainder, breakpoint, callback) {
  return [Math.floor(remainder / breakpoint)].concat(callback(remainder % breakpoint));
}

Es gibt ein Array zurück, in dem das erste Element der Betrag für den gegebenen Haltepunkt ist und der Rest des Arrays durch den Rückruf gegeben wird. Die Wiederverwendung der divideAndAppend in der Callback-Funktion erhalten Sie eine Pipeline von zusammengesetzten divideAndAppend Funktionen. Jede einzelne dieser berechnet den Betrag für jeden gegebenen Haltepunkt und fügt ihn an das Array an, um die gewünschte Ausgabe zu erzeugen.

Dann brauchen Sie auch den "finalen" Rückruf, der diese Pipeline beendet. Mit anderen Worten: Sie haben alle Haltepunkte verwendet und haben jetzt nur noch den Rest. Da Sie bereits die Antwort bei 3) haben, sollten Sie eine Art Identitätsfunktion verwenden, in diesem Fall remainder => [remainder] .

Sie können die Pipeline nun wie folgt schreiben

let pipeline = r3 => divideAndAppend(
    r3, 
    3600, 
    r2 => divideAndAppend(
        r2, 
        60, 
        r1 => [r1]));

> pipeline(3785)
< [1, 3, 5]

Cool, oder?

Verallgemeinerung mit for-Schleife

Jetzt können Sie mit einer variablen Anzahl von Haltepunkten verallgemeinern und eine for-Schleife erstellen, die die einzelnen Haltepunkte zusammensetzt divideAndAppend Funktionen in die Pipeline. Sie beginnen mit der Identitätsfunktion r1 => [r1] verwenden, dann die 60 Haltepunkt und verwenden Sie schließlich die 3600 Haltepunkt.

let breakpoints = [60, 3600];
let pipeline = r => [r];

for (const b of breakpoints) {
  const previousPipeline = pipeline;
  pipeline = r => divideAndAppend(r, b, previousPipeline);
}

> pipeline(3785)
< [1, 3, 5]

Verwendung von Array.prototype.reduce()

Jetzt können Sie diese for-Schleife in einen Reducer umschreiben, um kürzeren und funktionelleren Code zu erhalten. Mit anderen Worten, schreiben Sie die Funktionskomposition in den Reducer um.

let pipeline = [60, 3600].reduce(
  (ppln, b) => r => divideAndAppend(r, b, ppln),
  r => [r]
);

> pipeline(3785)
< [1, 3, 5]

Der Akkumulator ppln ist die Pipeline, und Sie setzen sie unter Verwendung der vorherigen Version zusammen. Die ursprüngliche Pipeline lautet r => [r] .

Sie können die Funktion nun einbinden divideAndAppend und verwenden Array.prototype.reduceRight was dasselbe ist wie [].reverse().reduce(...) um die Haltepunkte zu setzen Definitionen natürlicher zu gestalten.

let pipeline = [3600, 60]
    .reduceRight(
      (ppln, b) => r => [Math.floor(r / b)].concat(ppln(r % b)),
      r => [r]
    );

Das ist die endgültige Form. Dann wendet man einfach die Abbildung auf die Zeichenkette mit aufgefüllten 0's auf der linken Seite an und verbindet die Zeichenketten mit : Abscheider;

Mehr Verallgemeinerungen

Einbindung des Reduzierers in eine Funktion

function decompose(total, breakpoints) {
  return breakpoints.reduceRight(
    (p, b) => r => [Math.floor(r / b)].concat(p(r % b)),
    r => [r]
  )(total);
}

> decompose(3785, [3600, 60])
< [1, 3, 5]

haben Sie nun einen sehr allgemeinen Algorithmus, mit dem Sie arbeiten können. Zum Beispiel:

Konvertieren Sie leicht (die seltsamen) us-Längenstandards

In Anbetracht der Normen

Einheit

Abteilungen

1 Fuß

12 Zoll

1 Yard

3 Füße

1 Meile

1760 Yards

> decompose(123_456, [1760 * 3 * 12, 3 * 12, 12])
< [1, 1669, 1, 0]

123456 in = 1 mi, 1669 yd, 1 Fuß und 0 in

Sie können aber auch in dezimale oder binäre Darstellungen umwandeln

> decompose(123_456, [100_000, 10_000, 1000, 100, 10])
< [1, 2, 3, 4, 5, 6]

> decompose(127, [128, 64, 32, 16, 8, 4, 2])
< [0, 1, 1, 1, 1, 1, 1, 1]

Funktioniert auch mit Fließkomma-Haltepunkten

Da Javascript unterstützt mod Operator mit Fließkommazahlen verwenden, können Sie auch

> decompose(26.5, [20, 2.5])
< [1, 2, 1.5]

Der Grenzfall, dass es keine Haltepunkte gibt, ist natürlich auch abgedeckt

> decompose(123, [])
< [123]

10voto

Hung Vo Punkte 401

Versuchen Sie dies:

function toTimeString(seconds) {
  return (new Date(seconds * 1000)).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X