Comment utiliser format () sur une durée moment.js?


211

Existe-t-il un moyen d'utiliser la méthode moment.js format sur des objets de durée? Je ne le trouve nulle part dans les documents et il ne semble pas être un attribut sur les objets de durée.

J'aimerais pouvoir faire quelque chose comme:

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

De plus, s'il existe d'autres bibliothèques pouvant facilement accueillir ce type de fonctionnalité, je serais intéressé par les recommandations.

Merci!


5
moment.utc (duration.asMilliseconds ()). format ('hh: mm: ss'); - Une durée est un vecteur. En mettant sa queue sur l'origine, vous pouvez utiliser le formatage de la date pour obtenir hh: mm: ss.
Paul Williams

moment.utc (moment.duration (23, 'seconds'). asMilliseconds ()). format ('hh: mm: ss') => "12:00:23" ne fonctionne pas si bien
goldenratio

Ah, j'ai trouvé le problème, HH:mm:ssdonnera 00:00:23dans mon exemple précédent. donc juste le mauvais boîtier de la partie Heures
goldenratio

Réponses:


55

Nous envisageons d'ajouter une sorte de formatage aux durées dans moment.js. Voir https://github.com/timrwood/moment/issues/463

Quelques autres bibliothèques qui pourraient aider sont http://countdownjs.org/ et https://github.com/icambron/twix.js


4
J'attends aussi avec impatience le formatage de la durée. Jetez un œil au compte à rebours maintenant, mais twix ne semble que faire un formatage "intelligent", pas beaucoup de personnalisation.
mpen

2
Bien que twix travaille dur pour effectuer un formatage intelligent, il dispose de nombreuses options de formatage, jusqu'aux jetons impliqués: github.com/icambron/twix.js/wiki/Formatting . Avertissement: je suis l'auteur de twix.

3
Countdown.js est excellent, et l'auteur est super utile (il vient de sortir 2 versions le même jour en raison de quelques suggestions que j'ai faites)!
Ohad Schneider

5
Im down-vote parce que le problème de github lié dans cette réponse n'est qu'un flux sans fin d'opinions, de souhaits et de discours qui ne mènent nulle part, le problème est toujours ouvert après 4 ans, rien d'utile
bmaggi

29
Pourquoi ne peut-il pas être identique aux autres .formats utilisés ailleurs dans la bibliothèque? C'est de la folie. 5 ans et ce n'est toujours pas fait? vraiment?!
kristopole

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

Jetez un œil au JSFiddle


3
Bonne approche. Bien que cela ne fonctionne pas si je veux aussi afficher les jours: DDD HH:mm:ss.SSS(où DDDest le jour de l'année) s'affiche 1quand je veux 0. Une solution rapide pour cela?
Andrew Mao

1
Pas facile. J'ai fait ce jsfiddle.net/fhdd8/14 , ce qui est probablement ce que vous avez fait, mais je ne pense pas que le moment ait quoi que ce soit qui le fasse hors de la boîte
David Glass

49
Cela n'a aucun sens d'afficher 10 quadrillions de millisecondes en mm: ss
Pier-Luc Gendreau

28
cela ne fonctionne pas depuis 24 heures (c'est-à-dire si je voulais afficher 117 heures). sinon excellente solution!
Phil

1
@Phil, vous pouvez utiliser "D" ou "DD" si vous souhaitez afficher les jours.
Vinay

71

convertir la durée en ms puis en moment:

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

14
Donc, cela ne fonctionne pas si votre durée est supérieure à 24h .. 24h est réinitialisé à 0h
S. Robijns

4
@ S.Robijns une observation utile mais juste pour souligner pour les autres - c'est le comportement attendu de .format('HH:mm:ss'). Voir les documents
davnicwil

1
C'est la meilleure réponse!
Magico

44

Utilisez ce plugin Moment Duration Format .

Exemple:

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

1
Cette mise en forme ne fonctionne pas correctement, le côté durée est bon, mais si je spécifie hh:mm:mmet que je n'ai que 10 secondes, il s'affiche à la 10place de 00:00:10(même avec forcelength activé). standardisé.
Piotr Kula

9
@ppumkin je sais que c'est vieux mais si vous spécifiez { trim: false }cela arrêtera ce comportement.
Carlos Martinez

3
Voici ce que je préfère utiliser: Supposons que vous ayez une durée, comme celle const duration = moment.duration(value, 'seconds');que je peux mettre en forme en utilisant: moment.utc(duration.as('milliseconds')).format('HH:mm:ss').toString();
Evgeny Bobkin

1
@EvgenyBobkin qui ne fonctionnera pas si votre durée est supérieure à une journée, la bibliothèque s'en chargera cependant
reggaeguitar

16

Utilisez cette ligne de code:

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

8
Si la durée est> de 86400 '' (soit 24h), cela ne fonctionnera pas.
Lorenzo Tassone

C'est la même chose dans Excel, il roulera à 24 heures. Il s'agit d'une excellente solution de contournement si vous êtes conscient de la limitation de 24 heures.
Eman4real

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

1
Généralement, les réponses sont beaucoup plus utiles si elles incluent une explication de ce que le code est censé faire et pourquoi cela résout le problème sans en introduire d'autres. (Ce message a été signalé par au moins un utilisateur, probablement parce qu'ils pensaient qu'une réponse sans explication devrait être supprimée.)
Nathan Tuggy

1
Sans explication ou non, c'est ce qui a fait pour moi. Merci :)
dmmd

Aucune explication n'est nécessaire. Le document Moment.js peut montrer comment cette solution a été réalisée.
coffekid

2
Inutile. Comme la plupart des autres réponses, cette question renvoie des heures partielles dans la durée et non des heures totales. Par exemple, renvoie 12:00 pour la durée moment.duration ({jours: 2, heures: 12})
Neutrino

1
moment.duration (diff) .asMilliseconds () est excessif. Vous pouvez simplement utiliser diff, c'est déjà en millisecondes.
kristopole

12

Le meilleur scénario pour mon cas d'utilisation particulier était:

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

Cela améliore la réponse de @ Wilson car il n'accède pas à la propriété interne privée _data.


Merci @TaeKwonJoe
Kamlesh

11

Vous n'avez pas besoin de .format. Utilisez des durées comme celle-ci:

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

J'ai trouvé cette solution ici: https://github.com/moment/moment/issues/463

ÉDITER:

Et avec rembourrage pour les secondes, les minutes et les heures:

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
Cela n'inclura pas les zéros non significatifs si duration.seconds () est inférieur à 10, cependant ...
carpiediem

Que se passera-t-il si vous avez plus de secondes qu'une heure? Est-ce bien, que vous ayez alors plus de 60 secondes?
shaedrich

Les zéros en tête fonctionnent, mais duration = moment.duration(7200, 'seconds'); withPadding(duration);diront "00:00".
shaedrich

@shaedrich J'ai de nouveau mis à jour ma réponse pour inclure les heures; si vous avez besoin de jours, de semaines, vous pouvez également les ajouter au tableau
ni-ko-o-kin

1
if (duration.asDays() > 0) { return 'at least one day';- est-ce que je lis bien?
Stephen Paul

8

J'utilise:

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

Et je reçois "09:30" dans var str.


Génial! Cela fonctionne juste ... comment
diable

4
Évitez cette solution, _dataest une propriété interne et peut changer sans avertissement.
Druska

1
Malheureusement, cela ne fonctionnera pas toujours comme prévu: moment(moment.duration(1200000)._data).format('hh:mm:ss')retournera à 12h20 au lieu de 00h20
Anna R

2
@AnnaR hest compris entre 1 et 12, donc c'est plutôt prévisible. Utilisez Hplutôt docs - jetons d'heure
barbsan

C'est faux, non seulement vous ignorez DAYS, donc 1 jour et 1 heure sera affiché comme 01:00. De plus, vous moment.utc(...).format("HH:mm");
ignorez

5

si diff est un moment

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

Cela ne semble pas fiable face aux fuseaux horaires et autres. L'utilisez-vous en production?
Keith

la question ne fait aucune mention de fuseaux horaires.
Kieran

3
Tout le monde vit dans un fuseau horaire. Le moment (0) s'enregistre-t-il toujours à 00h00 dans chaque fuseau horaire?
Keith

Je demande simplement si le code dans votre réponse fonctionne ou non parce que je suis sceptique. J'ai écrit beaucoup de code qui fonctionne avec des dates, dans de nombreux langages de programmation. D'après mon expérience, il semble que votre code ne fonctionnerait que dans certains fuseaux horaires - mais je demande parce qu'il y a peut-être quelque chose que je ne sais pas sur la façon dont Javascript représente les dates près de l'époque Unix.
Keith

1
la deuxième ligne créera un moment depuis le début des temps (1970). Cela ne suffira pas.
kumarharsh

5

Si vous êtes prêt à utiliser une autre bibliothèque javascript, numeral.js peut formater les secondes comme suit (l'exemple est pour 1000 secondes):

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

certainement la voie à suivre. comme prévu.
Piotr Kula

4

J'utilise la fonction de formatage classique dans ces cas:

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

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

Ceci est un hack car le différentiel horaire est traité comme une date standard, une date précoce, mais cela n'a pas d'importance pour notre objectif et vous n'avez pas besoin de plugin


4

Si toutes les heures doivent être affichées (plus de 24) et si "0" avant les heures n'est pas nécessaire, le formatage peut être effectué avec une courte ligne de code:

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

4

Basé sur la réponse de 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

Je ne pense pas que ce soit très lisible. Quel problème voulez-vous résoudre ici? Quelle est votre cas d'utilisation?
ni-ko-o-kin

J'ai mis à jour ma réponse à nouveau pour faire face à plus d'une journée. Cela fonctionne bien pour mon cas d'utilisation.
ni-ko-o-kin

2
Le problème est que dans la plupart des cas, votre solution n'est pas idéale car elle contient trop de zéros non significatifs. Qui veut que "00: 00: 00: 00: 01" soit retourné? Ma solution est "évolutive" et ajoute autant de zéros de tête que nécessaire.
shaedrich

Fonctionne parfaitement. Sortie très simple. S'il n'y a pas de jours, il n'y aura pas de zéros pour les jours affichés, etc.
Hasan Sefa Ozalp

3

Pour formater la durée du moment en chaîne

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

si vous utilisez angulaire, ajoutez ceci à vos filtres:

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

exemple d'utilisation

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

Très beau effectivement. Je cherchais un «joli format» comme celui-ci. Merci!
riketscience

3

Ma solution qui n'implique aucune autre bibliothèque et qui fonctionne avec diff> 24h

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

Et le javascript natif?

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

Utiliser le format moment-durée .

Cadre client (ex: React)

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

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

Serveur (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}`);

Tirages:

2 jours 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

Vous pouvez utiliser numeral.js pour formater votre durée:

numeral(your_duration.asSeconds()).format('00:00:00') // result: hh:mm:ss

0

Cela peut être utilisé pour obtenir les deux premiers caractères en heures et les deux derniers en minutes. La même logique peut être appliquée aux secondes.

/**
     * 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>


Si vous insérez le code sous forme d'extrait, vous serez en mesure de tester la méthode et d'afficher une sortie sur la console.
DJDaveMark

Chose sûre! Juste mis à jour avec un extrait pour des tests rapides.
José Luis Raffalli

0

moment.duration(x).format()est obsolète. Vous pouvez utiliser moment.utc(4366589).format("HH:mm:ss")pour obtenir la réponse souhaitée.

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

Comment utiliser correctement les durées de moment.js? | Utilisez moment.duration () dans le code

Vous devez d'abord importer momentet moment-duration-format.

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

Ensuite, utilisez la fonction de durée. Appliquons l'exemple ci-dessus: 28800 = 8 h.

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

EllEh bien, vous n'avez pas d'erreur de type ci-dessus. 🤔Avez-vous une bonne valeur à 8h00? Non…, la valeur que vous obtenez est de 8 h 00. Le format Moment.js ne fonctionne pas comme il est censé le faire.

💡La solution consiste à transformer les secondes en millisecondes et à utiliser le temps UTC.

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

Très bien, nous obtenons 8h00 maintenant. Si vous voulez 8 h au lieu de 8 h pour le temps intégral, nous devons faire RegExp

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

0

J'avais besoin de le faire pour le travail comme une exigence pour afficher les heures dans ce format. Au début, j'ai essayé cela.

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

Cependant, plus de 24 heures et les heures sont remises à 0. Mais les minutes et les secondes étaient précises. J'ai donc utilisé uniquement cette partie pour les minutes et les secondes.

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

Maintenant, tout ce dont j'ai besoin est le nombre total d'heures.

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

Et pour obtenir ce format que nous voulons tous, il suffit de le coller ensemble.

var formatted = hours + ":" + minutesSeconds

si totalMillisecondsc'est 894600000cela reviendra 249:30:00.

J'espère que cela a aidé. Laissez des questions dans les commentaires. ;)


-1

Si vous utilisez Angular> 2, j'ai créé un Pipe inspiré par @ hai-alaluf.

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

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.