Come posso usare format () per la durata di moment.js?


211

C'è un modo in cui posso usare il format metodo moment.js su oggetti duration? Non riesco a trovarlo da nessuna parte nei documenti e non vede essere un attributo sugli oggetti durata.

Mi piacerebbe poter fare qualcosa del tipo:

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

Inoltre, se ci sono altre librerie che possono facilmente accogliere questo tipo di funzionalità, sarei interessato a raccomandazioni.

Grazie!


5
moment.utc (duration.asMilliseconds ()) formato ( 'hh: mm: ss.'); - Una durata è un vettore. Mettendo la coda sull'origine è possibile utilizzare la formattazione della data per ottenere hh: mm: ss.
Paul Williams,

moment.utc (moment.duration (23, 'seconds'). asMilliseconds ()). format ('hh: mm: ss') => "12:00:23" non funziona così bene
goldenratio

Ah, ho trovato il problema, HH:mm:ssdarà 00:00:23nel mio esempio precedente. quindi solo l'involucro sbagliato nella parte Ore
goldenratio

Risposte:


55

Stiamo cercando di aggiungere una sorta di formattazione alle durate in moment.js. Vedi https://github.com/timrwood/moment/issues/463

Un altro paio di librerie che potrebbero essere d'aiuto sono http://countdownjs.org/ e https://github.com/icambron/twix.js


4
Non vedo l'ora di formattare la durata. Diamo un'occhiata ora countdownjs, ma twix sembra solo fare una formattazione "intelligente", non molta personalizzazione.
Aprire il

2
Mentre twix lavora duramente per eseguire la formattazione intelligente, ha molte opzioni di formattazione, fino ai token coinvolti: github.com/icambron/twix.js/wiki/Formatting . Disclaimer: sono l'autore di twix.

3
Countdown.js è eccellente e l'autore è molto utile (ha appena rilasciato 2 versioni nello stesso giorno a causa di alcuni suggerimenti che ho fatto)!
Ohad Schneider,

5
Sto votando al ribasso perché la questione github collegata a questa risposta è solo un flusso infinito di opinioni, desideri e ribelli che non portano dove, il problema è ancora aperto dopo 4 anni, niente di utile
bmaggi

29
Perché non può essere identico all'altro formato usato in altre parti della libreria? Questa è follia. 5 anni e non è ancora finito? veramente?!
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);

Dai un'occhiata al JSFiddle


3
Buon approccio. Anche se non funziona se voglio visualizzare anche i giorni: DDD HH:mm:ss.SSS(dov'è il DDDgiorno dell'anno) viene visualizzato 1quando voglio 0. Qualche soluzione rapida per questo?
Andrew Mao,

1
Nessun modo semplice. Ho fatto questo jsfiddle.net/fhdd8/14 , che è probabilmente quello che hai fatto, ma non credo che il momento abbia qualcosa che lo faccia fuori dalla scatola
David Glass,

49
Non ha senso visualizzare 10 quadrilioni di millisecondi come mm: ss
Pier-Luc Gendreau,

28
questo non funziona oltre le 24 ore (ovvero se volevo visualizzare 117 ore). altrimenti ottima soluzione!
Phil

1
@Phil puoi usare "D" o "DD" se vuoi mostrare i giorni.
Vinay,

71

converti la durata in ms e poi in moment:

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

14
Quindi questo non funziona se la durata è superiore alle 24h. Le 24h vengono reimpostate su 0h
S. Robijns il

4
@ S.Robijns un'utile osservazione, ma solo per sottolineare per gli altri - questo è il comportamento previsto di .format('HH:mm:ss'). Vedi la documentazione
davnicwil,

1
questa è la risposta migliore!
Magico

44

Usa questo plug-in Moment Duration Format .

Esempio:

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

1
Che la formattazione non funzioni correttamente, il lato della durata è buono ma se lo specifico hh:mm:mme ho solo 10 secondi, mostra 10invece di 00:00:10(anche con la finezza attivata) Se non è formattato ... allora dovrebbe essere chiamato qualcos'altro, i formati dovrebbero essere standardizzato.
Piotr Kula,

9
@ppumkin so che questo è vecchio ma se lo specifichi { trim: false }fermerà quel comportamento.
Carlos Martinez,

3
Questo è quello che preferisco usare: supponi di avere una durata, come quella const duration = moment.duration(value, 'seconds');che posso essere formattata usando: moment.utc(duration.as('milliseconds')).format('HH:mm:ss').toString();
Evgeny Bobkin

1
@EvgenyBobkin che non funzionerà se la tua durata è più lunga di un giorno, la libreria lo gestirà comunque
reggaeguitar

16

Usa questa riga di codice:

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

8
Se la durata è> di 86400 '' (ovvero 24h), questo non funzionerà.
Lorenzo Tassone,

È lo stesso in Excel, rotolerà alle 24 ore. Questa è un'ottima soluzione se sei a conoscenza della limitazione delle 24 ore.
Eman4real,

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

1
In generale, le risposte sono molto più utili se includono una spiegazione di ciò che il codice è destinato a fare e perché risolve il problema senza introdurre altri. (Questo post è stato segnalato da almeno un utente, presumibilmente perché pensavano che una risposta senza spiegazioni dovesse essere cancellata.)
Nathan Tuggy,

1
Spiegazione o no, questo è ciò che ha fatto per me. Grazie :)
dmmd

Non è necessaria la spiegazione. Il documento Moment.js può mostrare come questa soluzione è stata raggiunta.
coffekid,

2
Inutili. Come la maggior parte delle altre risposte a questa domanda, restituisce ore parziali nella durata e non ore totali. Ad esempio, restituisce 12:00 per la durata del momento. Durata ({giorni: 2, ore: 12})
Neutrino

1
moment.duration (diff) .asMilliseconds () è eccessivo. Puoi semplicemente usare diff, è già in millisecondi.
kristopolous,

12

Lo scenario migliore per il mio caso d'uso particolare è stato:

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

Ciò migliora la risposta di @ Wilson poiché non accede alla proprietà interna privata _data.


Grazie @TaeKwonJoe
Kamlesh,

11

Non hai bisogno di .formato. Usa durate come questa:

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

Ho trovato questa soluzione qui: https://github.com/moment/moment/issues/463

MODIFICARE:

E con imbottitura per secondi, minuti e ore:

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
Questo non include gli zeri iniziali se duration.seconds () è inferiore a 10, tuttavia ...
carpiediem,

Cosa succederà se hai più di un secondo di un'ora? Va bene che hai più di 60 secondi?
shaedrich,

Gli zeri iniziali funzionano, ma duration = moment.duration(7200, 'seconds'); withPadding(duration);diranno "00:00".
Shaedrich,

@shaedrich Ho aggiornato di nuovo la mia risposta per includere le ore; se hai bisogno di giorni, settimane, anche tu puoi aggiungerli alla matrice
ni-ko-o-kin,

1
if (duration.asDays() > 0) { return 'at least one day';- lo sto leggendo correttamente?
Stephen Paul,

8

Io uso:

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

E ottengo "09:30" in var str.


Grande! Funziona così ... come
diavolo

4
Evita questa soluzione, _dataè una proprietà interna e può cambiare senza preavviso.
Druska,

1
Purtroppo non funzionerà sempre come previsto: moment(moment.duration(1200000)._data).format('hh:mm:ss')tornerà alle 12:20 anziché alle 00:20
Anna R

2
@AnnaR hè compreso tra 1 e 12, quindi è piuttosto prevedibile. Usa Hinvece documenti - token ora
barbsan

Questo è sbagliato, non solo se ignori GIORNI, quindi 1 giorno e 1 ora verranno visualizzati come 01:00. Inoltre stai ignorando completamente i fusi orari, una soluzione migliore, ma non sarà completamoment.utc(...).format("HH:mm");
Gil Epshtain,

5

se diff è un momento

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

Questo non sembra affidabile di fronte a fusi orari e simili. Lo usi in produzione?
Keith

la domanda non fa menzione dei fusi orari.
Kieran,

3
Tutti vivono in un fuso orario. Il momento (0) si registra sempre come 12:00 AM in ogni fuso orario?
Keith

Sto semplicemente chiedendo se il codice nella tua risposta funziona o meno perché sono scettico. Ho scritto un sacco di codice che funziona con le date, in molti linguaggi di programmazione. Sulla base della mia esperienza, sembra che il tuo codice funzionerebbe solo in determinati fusi orari, ma lo sto chiedendo perché forse c'è qualcosa che non so su come Javascript rappresenti le date vicino all'epoca di Unix.
Keith

1
la seconda riga creerà un momento dall'inizio del tempo (1970). Questo non lo farà.
Kumarharsh,

5

Se sei disposto a utilizzare una libreria javascript diversa, numeral.js può formattare i secondi come segue (l'esempio è per 1000 secondi):

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

sicuramente la strada da percorrere. come previsto.
Piotr Kula,

4

Uso la classica funzione di formattazione in questi casi:

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

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

Questo è un trucco perché il diff dell'ora viene trattato come una data del momento standard, una data dell'epoca in anticipo, ma non importa per il nostro obiettivo e non è necessario alcun plug-in


4

Se devono essere visualizzate tutte le ore (più di 24) e se "0" prima delle ore non è necessario, la formattazione può essere eseguita con una breve riga di codice:

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

4

Basato sulla risposta di 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

Non credo sia molto leggibile. Quale problema vuoi risolvere qui? Qual è il tuo caso d'uso?
Ni-Ko-o-Kin

Ho aggiornato di nuovo la mia risposta per occuparmi di più di un giorno. Funziona bene per il mio caso d'uso.
Ni-Ko-o-Kin

2
Il problema è che nella maggior parte dei casi la soluzione non è ideale perché contiene troppi zeri iniziali. Chi vuole che venga restituito "00: 00: 00: 00: 01"? La mia soluzione è "scalabile" e aggiunge tutti gli zeri iniziali necessari.
shaedrich,

Funziona perfettamente. Uscita molto semplice. Se non ci sono giorni, non ci saranno zeri per i giorni visualizzati ecc.
Hasan Sefa Ozalp

3

Per formattare la durata del momento in stringa

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

se usi angolare aggiungi questo ai tuoi filtri:

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

esempio di utilizzo

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

Davvero molto bello. Stavo cercando un "bel formato" come questo. Grazie!
riketscience,

3

La mia soluzione che non coinvolge altre librerie e funziona con 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

Che ne dici di javascript nativo?

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

Usa il formato della durata del momento .

Client Framework (es: React)

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

stampe:

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

Puoi usare numeral.js per formattare la durata:

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

0

Questo può essere usato per ottenere i primi due caratteri come ore e gli ultimi due come minuti. La stessa logica può essere applicata ai secondi.

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


Se inserisci il codice come frammento, sarai in grado di testare il metodo e mostrare un po 'di output sulla console.
DJDaveMark,

Cosa certa! Appena aggiornato con frammento per test rapidi.
José Luis Raffalli,

0

moment.duration(x).format()è stato deprecato. È possibile utilizzare moment.utc(4366589).format("HH:mm:ss")per ottenere la risposta desiderata.

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

Come utilizzare correttamente le durate moment.js? | Usa moment.duration () nel codice

Per prima cosa devi importare momente moment-duration-format.

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

Quindi, utilizzare la funzione di durata. Facciamo l'esempio sopra: 28800 = 8 am.

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

EllBeh, non hai un errore di tipo sopra. 🤔Hai il valore corretto alle 8:00? No ..., il valore che ottieni è 8:00 a. Il formato Moment.js non funziona come dovrebbe.

💡La soluzione è trasformare i secondi in millisecondi e utilizzare l'ora UTC.

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

Bene, adesso arriviamo alle 8:00. Se vuoi 8:00 anziché 8:00 per il tempo integrale, dobbiamo fare RegExp

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

0

Ho dovuto farlo per lavoro come requisito per visualizzare le ore in questo formato. All'inizio ho provato questo.

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

Tuttavia, qualsiasi cosa oltre le 24 ore e le ore si resettano a 0. Ma i minuti e i secondi erano accurati. Quindi ho usato solo quella parte per i minuti e i secondi.

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

Ora tutto ciò di cui ho bisogno sono le ore totali.

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

E per ottenere quel formato che tutti noi desideriamo, basta incollarlo insieme.

var formatted = hours + ":" + minutesSeconds

se totalMillisecondsè 894600000questo tornerà 249:30:00.

Spero che abbia aiutato. Lascia qualsiasi domanda nei commenti. ;)


-1

Se usi Angular> 2, ho creato una Pipe ispirata alla risposta @ 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 : "");
  }
}

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.