Wie kann ich die Sekunden in eine HH-MM-SS
Zeichenfolge mit JavaScript?
Antworten
Zu viele Anzeigen?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í :
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
- Um die Stunden zu erhalten, dividiert man die Gesamtsekunden durch 3600 und addiert das Ergebnis.
- Um die Minuten zu erhalten, teilen Sie Restbetrag um 60 zu erhöhen und den Wert zu senken.
- 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]