Wie verwende ich format () für die Dauer von moment.js?


211

Gibt es eine Möglichkeit, die moment.js- format Methode für Dauerobjekte zu verwenden? Ich kann es nirgendwo in den Dokumenten finden und es wird nicht als Attribut für Dauerobjekte angesehen.

Ich möchte in der Lage sein, etwas zu tun wie:

var diff = moment(end).unix() - moment(start).unix();
moment.duration(diff).format('hh:mm:ss')

Auch wenn es andere Bibliotheken gibt, die diese Art von Funktionalität problemlos aufnehmen können, wäre ich an Empfehlungen interessiert.

Vielen Dank!


5
moment.utc (duration.asMilliseconds ()). format ('hh: mm: ss'); - Eine Dauer ist ein Vektor. Indem Sie den Schwanz auf den Ursprung legen, können Sie die Datumsformatierung verwenden, um hh: mm: ss zu erhalten.
Paul Williams

moment.utc (moment.duration (23, 'Sekunden'). asMilliseconds ()). format ('hh: mm: ss') => "12:00:23" funktioniert nicht so gut
goldenratio

Ah, ich habe das Problem gefunden, HH:mm:sswerde 00:00:23in meinem vorherigen Beispiel geben.
Also

Antworten:


55

Wir versuchen, die Dauer in moment.js zu formatieren. Siehe https://github.com/timrwood/moment/issues/463

Einige andere Bibliotheken, die helfen könnten, sind http://countdownjs.org/ und https://github.com/icambron/twix.js


4
Ich freue mich auch auf die Formatierung der Dauer. Werfen Sie jetzt einen Blick auf die Countdowns, aber Twix scheint nur eine "intelligente" Formatierung zu ermöglichen, nicht viele Anpassungen.
Mpen

2
Twix arbeitet zwar hart an der intelligenten Formatierung, bietet jedoch zahlreiche Formatierungsoptionen, bis hin zu den beteiligten Token: github.com/icambron/twix.js/wiki/Formatting . Haftungsausschluss: Ich bin der Autor von Twix.

3
Countdown.js ist exzellent und der Autor ist super hilfreich (er hat gerade 2 Versionen am selben Tag veröffentlicht, aufgrund einiger Vorschläge, die ich gemacht habe)!
Ohad Schneider

5
Ich stimme ab, weil das Github-Problem, das in dieser Antwort verlinkt ist, nur ein nie endender Strom von Meinungen, Wünschen und Beschimpfungen ist, die nirgendwohin führen. Das Problem ist nach 4 Jahren immer noch offen, nichts Nützliches
bmaggi

29
Warum kann es nicht mit dem anderen .format identisch sein, das an anderer Stelle in der Bibliothek verwendet wird? Das ist Wahnsinn. 5 Jahre und es ist immer noch nicht fertig? Ja wirklich?!
kristopolous

164
// set up
let start = moment("2018-05-16 12:00:00"); // some random moment in time (in ms)
let end = moment("2018-05-16 12:22:00"); // some random moment after start (in ms)
let diff = end.diff(start);

// execution
let f = moment.utc(diff).format("HH:mm:ss.SSS");
alert(f);

Schauen Sie sich die JSFiddle an


3
Guter Ansatz. Obwohl es nicht funktioniert, wenn ich auch Tage anzeigen möchte: DDD HH:mm:ss.SSS(wo DDDist Tag des Jahres) wird angezeigt, 1wenn ich möchte 0. Irgendeine schnelle Lösung dafür?
Andrew Mao

1
Kein einfacher Weg. Ich habe dies getan jsfiddle.net/fhdd8/14 , was wahrscheinlich das ist, was Sie getan haben, aber ich glaube nicht, dass der Moment irgendetwas hat, das dies sofort tut
David Glass

49
Es macht keinen Sinn, 10 Billiarden Millisekunden als mm: ss anzuzeigen
Pier-Luc Gendreau

28
Dies funktioniert nicht länger als 24 Stunden (dh wenn ich 117 Stunden anzeigen wollte). sonst tolle lösung!
Phil

1
@Phil Sie können "D" oder "DD" verwenden, wenn Sie Tage anzeigen möchten.
Vinay

71

Konvertiere die Dauer in ms und dann in den Moment:

moment.utc(duration.as('milliseconds')).format('HH:mm:ss')

14
Dies funktioniert also nicht, wenn Ihre Dauer länger als 24 Stunden ist
. 24

4
@ S.Robijns eine nützliche Beobachtung, aber nur um für andere zu betonen - dies ist das erwartete Verhalten von .format('HH:mm:ss'). Siehe die Dokumente
Davnicwil

1
Das ist die beste Antwort!
Magico

44

Verwenden Sie dieses Plugin Moment Duration Format .

Beispiel:

moment.duration(123, "minutes").format("h:mm");

1
Diese Formatierung funktioniert nicht richtig, die Dauer ist gut, aber wenn ich spezifiziere hh:mm:mmund nur 10 Sekunden habe, wird sie 10anstelle von 00:00:10(auch bei aktivierter Vorlänge) angezeigt. Wenn sie nicht formatiert ist ... dann sollte sie etwas anderes heißen, sollten Formate sein standardisiert.
Piotr Kula

9
@ppumkin Ich weiß, dass dies alt ist, aber wenn Sie angeben { trim: false }, wird es dieses Verhalten stoppen.
Carlos Martinez

3
Dies ist, was ich am liebsten benutze: Angenommen, Sie haben eine Dauer, wie const duration = moment.duration(value, 'seconds');ich sie formatieren kann mit: moment.utc(duration.as('milliseconds')).format('HH:mm:ss').toString();
Evgeny Bobkin

1
@ EvgenyBobkin, der nicht funktioniert, wenn Ihre Dauer länger als ein Tag ist, die Bibliothek wird es jedoch behandeln
reggaeguitar

16

Verwenden Sie diese Codezeile:

moment.utc(moment.duration(4500, "seconds").asMilliseconds()).format("HH:mm:ss")

8
Wenn die Dauer> von 86400 '' (dh 24 Stunden) ist, funktioniert dies nicht.
Lorenzo Tassone

Es ist das gleiche in Excel, es wird um 24 Uhr rollen. Dies ist eine großartige Problemumgehung, wenn Sie sich der 24-Stunden-Beschränkung bewusst sind.
Eman4real

15
var diff = moment(end).unix() - moment(start).unix();
moment.utc(moment.duration(diff).asMilliseconds()).format("HH:mm:ss.SSS");

1
Im Allgemeinen sind Antworten viel hilfreicher, wenn sie eine Erklärung enthalten, was der Code tun soll und warum dies das Problem löst, ohne andere einzuführen. (Dieser Beitrag wurde von mindestens einem Benutzer markiert, vermutlich weil er dachte, eine Antwort ohne Erklärung sollte gelöscht werden.)
Nathan Tuggy

1
Erklärunglos oder nicht, das hat es für mich getan. Danke :)
dmmd

Erklärung ist nicht erforderlich. Moment.js doc kann zeigen, wie diese Lösung erreicht wurde.
Coffekid

2
Nutzlos. Wie die meisten anderen Antworten auf diese Frage werden Teilstunden in der Dauer nicht Gesamtstunden zurückgegeben. ZB kehrt 12:00 für die Dauer moment.duration ({Tage: 2, Stunden: 12})
Neutrino

1
moment.duration (diff) .asMilliseconds () ist zu groß. Sie können nur diff verwenden, es ist bereits in Millisekunden.
kristopolous

12

Das beste Szenario für meinen speziellen Anwendungsfall war:

var duration = moment.duration("09:30"),
    formatted = moment.utc(duration.asMilliseconds()).format("HH:mm");

Dies verbessert die Antwort von @ Wilson, da nicht auf die privaten internen Eigenschaften _data zugegriffen wird.


Vielen Dank, dass Sie @TaeKwonJoe
Kamlesh

11

Sie brauchen kein .format. Verwenden Sie die Dauer wie folgt:

const duration = moment.duration(83, 'seconds');
console.log(duration.minutes() + ':' +duration.seconds());
// output: 1:23

Ich habe diese Lösung hier gefunden: https://github.com/moment/moment/issues/463

BEARBEITEN:

Und mit Polsterung für Sekunden, Minuten und Stunden:

const withPadding = (duration) => {
    if (duration.asDays() > 0) {
        return 'at least one day';
    } else {
        return [
            ('0' + duration.hours()).slice(-2),
            ('0' + duration.minutes()).slice(-2),
            ('0' + duration.seconds()).slice(-2),
        ].join(':')
    }
}

withPadding(moment.duration(83, 'seconds'))
// 00:01:23

withPadding(moment.duration(6048000, 'seconds'))
// at least one day

2
Dies schließt keine führenden Nullen ein, wenn duration.seconds () kleiner als 10 ist ...
carpiediem

Was passiert, wenn Sie mehr Sekunden als eine Stunde haben? Ist es in Ordnung, dass Sie dann mehr als 60 Sekunden haben?
Shaedrich

Führende Nullen funktionieren, duration = moment.duration(7200, 'seconds'); withPadding(duration);sagen aber "00:00".
Shaedrich

@shaedrich Ich habe meine Antwort erneut aktualisiert, um Stunden einzuschließen. Wenn Sie auch Tage, Wochen benötigen, können Sie diese dem Array hinzufügen
ni-ko-o-kin

1
if (duration.asDays() > 0) { return 'at least one day'; - lese ich das richtig
Stephen Paul

8

Ich benutze:

var duration = moment.duration("09:30");
var str = moment(duration._data).format("HH:mm");

Und ich bekomme "09:30" in var str.


Toll! Das funktioniert einfach ... wie um alles in der Welt bist du darauf gekommen :)
Vanthome

4
Vermeiden Sie diese Lösung, _dataist eine interne Eigenschaft und kann sich ohne Vorwarnung ändern.
Druska

1
Leider wird es nicht immer wie erwartet funktionieren: moment(moment.duration(1200000)._data).format('hh:mm:ss')wird 12:20 statt 00:20 zurückkehren
Anna R

2
@AnnaR hliegt im Bereich von 1-12, ist also ziemlich zu erwarten. Verwenden Sie Hstattdessen docs - Stunde Token
Barbansan

Dies ist falsch, nicht nur, dass Sie TAGE ignorieren, sondern 1 Tag und 1 Stunde werden als 01:00 angezeigt. Zusätzlich ignorieren Sie völlig Zeitzonen, um eine bessere Lösung, aber auch keinen vollständig man wird moment.utc(...).format("HH:mm");
Gil Epshtain

5

wenn diff ein Moment ist

var diff = moment(20111031) - moment(20111010);
var formated1 = moment(diff).format("hh:mm:ss");
console.log("format 1: "+formated1);

Dies scheint angesichts von Zeitzonen und dergleichen nicht zuverlässig zu sein. Verwenden Sie dies in der Produktion?
Keith

In der Frage werden keine Zeitzonen erwähnt.
Kieran

3
Jeder lebt in einer Zeitzone. Wird Moment (0) in jeder Zeitzone immer als 00:00 Uhr registriert?
Keith

Ich frage nur, ob der Code in Ihrer Antwort funktioniert oder nicht, weil ich skeptisch bin. Ich habe viel Code geschrieben, der mit Datumsangaben in vielen Programmiersprachen funktioniert. Aufgrund meiner Erfahrung scheint Ihr Code nur in bestimmten Zeitzonen zu funktionieren - aber ich frage, weil ich möglicherweise nicht weiß, wie Javascript Daten in der Nähe der Unix-Epoche darstellt.
Keith

1
Die zweite Zeile wird einen Moment ab Beginn der Zeit (1970) erzeugen. Das geht nicht.
Kumarshar

5

Wenn Sie bereit sind, eine andere Javascript-Bibliothek zu verwenden, kann numeral.js Sekunden wie folgt formatieren (Beispiel: 1000 Sekunden):

var string = numeral(1000).format('00:00');
// '00:16:40'

definitiv der richtige Weg. wie erwartet.
Piotr Kula

4

In diesen Fällen verwende ich die klassische Formatfunktion:

var diff = moment(end).unix() - moment(start).unix();

//use unix function instead of difference
moment.unix(diff).format('hh:mm:ss')

Dies ist ein Hack, da der Zeitunterschied als Standard-Moment-Datum behandelt wird, als Datum einer frühen Epoche, aber es spielt für unser Ziel keine Rolle und Sie benötigen kein Plugin


4

Wenn alle Stunden angezeigt werden müssen (mehr als 24) und wenn '0' vor Stunden nicht erforderlich ist, kann die Formatierung mit einer kurzen Codezeile erfolgen:

Math.floor(duration.as('h')) + moment.utc(duration.as('ms')).format(':mm:ss')

4

Basierend auf der Antwort von ni-ko-o-kin :

meassurements = ["years", "months", "weeks", "days", "hours", "minutes", "seconds"];
withPadding = (duration) => {
    var step = null;
    return meassurements.map((m) => duration[m]()).filter((n,i,a) => {
        var nonEmpty = Boolean(n);
        if (nonEmpty || step || i >= a.length - 2) {
            step = true;
        }
        return step;
    }).map((n) => ('0' + n).slice(-2)).join(':')
}

duration1 = moment.duration(1, 'seconds');
duration2 = moment.duration(7200, 'seconds');
duration3 = moment.duration(604800, 'seconds');

withPadding(duration1); // 00:01
withPadding(duration2); // 02:00:00
withPadding(duration3); // 01:07:00:00:00

Ich denke nicht, dass es sehr lesbar ist. Welches Problem möchten Sie hier lösen? Was ist Ihr Anwendungsfall?
Ni-Ko-O-Kin

Ich habe meine Antwort erneut aktualisiert, um mehr als einen Tag zu bewältigen. Es funktioniert gut für meinen Anwendungsfall.
Ni-Ko-O-Kin

2
Das Problem ist, dass Ihre Lösung in den meisten Fällen nicht ideal ist, weil sie zu viele führende Nullen enthält. Wer möchte "00: 00: 00: 00: 01" zurückbekommen? Meine Lösung ist "skalierbar" und fügt genauso viele führende Nullen wie nötig hinzu.
Shaedrich

Funktioniert perfekt. Sehr einfache Ausgabe. Wenn keine Tage vorhanden sind, werden für Tage usw. keine Nullen angezeigt.
Hasan Sefa Ozalp

3

Zum Formatieren der Momentdauer in einen String

var duration = moment.duration(86400000); //value in milliseconds
var hours = duration.hours();
var minutes = duration.minutes();
var seconds = duration.seconds();
var milliseconds = duration.milliseconds();

var date = moment().hours(hours).minutes(minutes).seconds(seconds).millisecond(milliseconds);
if (is12hr){
    return date.format("hh:mm:ss a");
}else{
    return date.format("HH:mm:ss");
}

3

Wenn Sie Winkel verwenden, fügen Sie dies Ihren Filtern hinzu:

.filter('durationFormat', function () {
    return function (value) {
        var days = Math.floor(value/86400000);
        value = value%86400000;
        var hours = Math.floor(value/3600000);
        value = value%3600000;
        var minutes = Math.floor(value/60000);
        value = value%60000;
        var seconds = Math.floor(value/1000);
        return (days? days + ' days ': '') + (hours? hours + ' hours ': '') + (minutes? minutes + ' minutes ': '') + (seconds? seconds + ' seconds ': '')
    }
})

Anwendungsbeispiel

<div> {{diff | durationFormat}} </div>

Wirklich sehr nett. Ich suchte nach einem "hübschen Format" wie diesem. Vielen Dank!
Riketscience

3

Meine Lösung, die keine andere Bibliothek beinhaltet und mit diff> 24h funktioniert

var momentInSeconds = moment.duration(n,'seconds')
console.log(("0" + Math.floor(momentInSeconds.asHours())).slice(-2) + ':' + ("0" + momentInSeconds.minutes()).slice(-2) + ':' + ("0" + momentInSeconds.seconds()).slice(-2))

1

Wie wäre es mit nativem Javascript?

var formatTime = function(integer) {
    if(integer < 10) {
        return "0" + integer; 
    } else {
        return integer;
    }
}

function getDuration(ms) {
    var s1 = Math.floor(ms/1000);
    var s2 = s1%60;
    var m1 = Math.floor(s1/60);
    var m2 = m1%60;
    var h1 = Math.floor(m1/60);
    var string = formatTime(h1) +":" + formatTime(m2) + ":" + formatTime(s2);
    return string;
}

1

Verwenden Sie das Moment-Dauer-Format .

Client Framework (Beispiel: Reagieren)

import moment from 'moment';
import momentDurationFormatSetup from 'moment-duration-format';
momentDurationFormatSetup(moment);

const breakLengthInMinutes = moment.duration(breakLengthInSeconds, 's').format('m');

Server (node.js)

const moment = require("moment-timezone");
const momentDurationFormatSetup = require("moment-duration-format");

momentDurationFormatSetup(moment);

const breakLengthInMinutes = moment.duration(breakLengthInSeconds, 's').format('m');

0
const duration = moment.duration(62, 'hours');
const n = 24 * 60 * 60 * 1000;
const days = Math.floor(duration / n);
const str = moment.utc(duration % n).format('H [h] mm [min] ss [s]');
console.log(`${days > 0 ? `${days} ${days == 1 ? 'day' : 'days'} ` : ''}${str}`);

Drucke:

2 Tage 14 h 00 min 00 s


0
import * as moment from 'moment'
var sleep = require('sleep-promise');

(async function () {
    var t1 = new Date().getTime();
    await sleep(1000); 
    var t2 = new Date().getTime();
    var dur = moment.duration(t2-t1); 
    console.log(`${dur.hours()}h:${dur.minutes()}m:${dur.seconds()}s`);
})();
0h:0m:1s


0

Dies kann verwendet werden, um die ersten beiden Zeichen als Stunden und die letzten zwei als Minuten abzurufen. Dieselbe Logik kann auf Sekunden angewendet werden.

/**
     * PT1H30M -> 0130
     * @param {ISO String} isoString
     * @return {string} absolute 4 digit number HH:mm
     */

    const parseIsoToAbsolute = (isoString) => {
    
      const durations = moment.duration(isoString).as('seconds');
      const momentInSeconds = moment.duration(durations, 'seconds');
    
      let hours = momentInSeconds.asHours().toString().length < 2
        ? momentInSeconds.asHours().toString().padStart(2, '0') : momentInSeconds.asHours().toString();
        
      if (!Number.isInteger(Number(hours))) hours = '0'+ Math.floor(hours);
    
      const minutes = momentInSeconds.minutes().toString().length < 2
        ? momentInSeconds.minutes().toString().padEnd(2, '0') : momentInSeconds.minutes().toString();
    
      const absolute = hours + minutes;
      return absolute;
    };
    
    console.log(parseIsoToAbsolute('PT1H30M'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>


Wenn Sie den Code als Snippet einfügen, können Sie die Methode testen und der Konsole eine Ausgabe anzeigen.
DJDaveMark

Sichere Sache! Gerade mit Snippet für schnelle Tests aktualisiert.
José Luis Raffalli

0

moment.duration(x).format()wurde veraltet. Sie können verwenden moment.utc(4366589).format("HH:mm:ss"), um die gewünschte Antwort zu erhalten.

console.log(moment.utc(4366589).format("HH:mm:ss"))
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>


0

Wie verwende ich die Dauer von moment.js richtig? | Verwenden Sie moment.duration () im Code

Zuerst müssen Sie importieren momentund moment-duration-format.

import moment from 'moment';
import 'moment-duration-format';

Verwenden Sie dann die Dauerfunktion. Wenden wir das obige Beispiel an: 28800 = 8 Uhr.

moment.duration(28800, "seconds").format("h:mm a");

🎉Nun, Sie haben oben keinen Tippfehler. »Erhalten Sie um 8:00 Uhr einen richtigen Wert? Nein…, der Wert, den Sie erhalten, ist 8:00 a. Das Format von Moment.j funktioniert nicht wie vorgesehen.

💡Die Lösung besteht darin, Sekunden in Millisekunden umzuwandeln und die UTC-Zeit zu verwenden.

moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a')

Gut, wir bekommen jetzt 8:00 Uhr. Wenn Sie 8 Uhr statt 8 Uhr für die Gesamtzeit möchten, müssen wir RegExp durchführen

const time = moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a');
time.replace(/:00/g, '')

0

Ich musste dies für die Arbeit tun, um die Stunden in diesem Format anzuzeigen. Zuerst habe ich es versucht.

moment.utc(totalMilliseconds).format("HH:mm:ss")

Jedoch alles über 24 Stunden und die Stunden auf 0 zurückgesetzt. Aber die Minuten und Sekunden waren genau. Also habe ich nur diesen Teil für die Minuten und Sekunden verwendet.

var minutesSeconds = moment.utc(totalMilliseconds).format("mm:ss")

Jetzt brauche ich nur noch die Gesamtstunden.

var hours = moment.duration(totalMilliseconds).asHours().toFixed()

Und um das Format zu erhalten, das wir alle wollen, kleben wir es einfach zusammen.

var formatted = hours + ":" + minutesSeconds

Wenn dies der Fall totalMillisecondsist, wird 894600000dies zurückkehren 249:30:00.

Hoffe das hat geholfen. Hinterlassen Sie Fragen in den Kommentaren. ;)


-1

Wenn Sie Angular> 2 verwenden, habe ich eine Pipe erstellt, die von der Antwort @ hai-alaluf inspiriert ist.

import {Pipe, PipeTransform} from "@angular/core";

@Pipe({
  name: "duration",
})

export class DurationPipe implements PipeTransform {

  public transform(value: any, args?: any): any {

    // secs to ms
    value = value * 1000;
    const days = Math.floor(value / 86400000);
    value = value % 86400000;
    const hours = Math.floor(value / 3600000);
    value = value % 3600000;
    const minutes = Math.floor(value / 60000);
    value = value % 60000;
    const seconds = Math.floor(value / 1000);
    return (days ? days + " days " : "") +
      (hours ? hours + " hours " : "") +
      (minutes ? minutes + " minutes " : "") +
      (seconds ? seconds + " seconds " : "") +
      (!days && !hours && !minutes && !seconds ? 0 : "");
  }
}

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.