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!

mvanveen
la source
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

bois de timbre
la source
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

David Glass
la source
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')
Sagiv Ofek
la source
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");
kayz1
la source
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")
NFpeter
la source
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");
Eric Saboia
la source
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.

TaeKwonJoe
la source
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
ni-ko-o-kin
la source
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.

Wilson
la source
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);
Kieran
la source
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'
GChorn
la source
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

Les bretelles
la source
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')
ov
la source
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
shaedrich
la source
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");
}
Dineshkani
la source
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>
Hai Alaluf
la source
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))
Lorenzo Tassone
la source
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;
}
J. Allen
la source
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');
AryanJ-NYC
la source
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

davidhq
la source
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
Boîte à outils
la source
0

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

numeral(your_duration.asSeconds()).format('00:00:00') // result: hh:mm:ss
João Paulo
la source
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>

José Luis Raffalli
la source
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>

kindacoder
la source
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, '')
Farrukh Malik
la source
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. ;)

Zach Dyer
la source
-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 : "");
  }
}
0x29A
la source
-3

Cela fonctionne pour moi:

moment({minutes: 150}).format('HH:mm') // 01:30
Natan Augusto
la source
Retour "Date invalide"
themadmax
3
150 minutes n'est pas 1 heure 30 minutes.
Mark Brown