Come convertire i secondi in HH: mm: ss in moment.js


93

Come posso convertire i secondi in HH:mm:ss?

Al momento sto utilizzando la funzione sottostante

render: function (data){
     return new Date(data*1000).toTimeString().replace(/.*(\d{2}:\d{2}:\d{2}).*/, "$1");;
}

Funziona su Chrome, ma in Firefox per 12 secondi, vorrei 01:00:12 usare moment.js per la compatibilità cross browser

Ho provato questo ma non funziona

render: function (data){
         return moment(data).format('HH:mm:ss');
}

Che cosa sto facendo di sbagliato?

MODIFICARE

Sono riuscito a trovare una soluzione senza moment.js che è la seguente

return (new Date(data * 1000)).toUTCString().match(/(\d\d:\d\d:\d\d)/)[0];

Ancora curioso di sapere come posso farlo in moment.js



@mplungjan Scusa per non aver detto che ho già letto quel post. Ho bisogno di eseguire il rendering di una tabella con milioni di righe e la soluzione è troppo lenta. la seconda risposta è esattamente quella che ho scritto nella mia domanda ma mi dà problemi in firefox
QGA

2
@QuentinTanioartino quindi 4 banali operatori matematici è un problema per il compito di mutare DOM per milioni di elementi? Sei sicuro di aver compreso correttamente il problema delle prestazioni?
zerkms

@zerkms, so bene che le mie classi DAO devono essere riscritte per servire i dati già convertiti. Questo è un problema di cui sono a conoscenza. Ha detto che sono abbastanza soddisfatto delle attuali prestazioni del mio primo tentativo ma quando ho 5 operazioni matematiche per una conversione che rallenta un po 'il sistema. Sì, sono d'accordo con te che questa è solo una rapida soluzione TEMPORANEA
QGA

@QuentinTanioartino "che rallenta un po 'il sistema" --- "un po'" non è il tuo modo di ragionare sulle prestazioni. È un collo di bottiglia? È dimostrato di essere un collo di bottiglia? In caso contrario, cosa ti spinge a ottimizzare questa stessa operazione?
zerkms

Risposte:


79

Da questo post proverei questo per evitare problemi di salto

moment("2015-01-01").startOf('day')
    .seconds(s)
    .format('H:mm:ss');

Non ho eseguito jsPerf, ma penso che sia più veloce della creazione di nuovi oggetti data un milione di volte

function pad(num) {
    return ("0"+num).slice(-2);
}
function hhmmss(secs) {
  var minutes = Math.floor(secs / 60);
  secs = secs%60;
  var hours = Math.floor(minutes/60)
  minutes = minutes%60;
  return `${pad(hours)}:${pad(minutes)}:${pad(secs)}`;
  // return pad(hours)+":"+pad(minutes)+":"+pad(secs); for old browsers
}


2
Grazie mille, soluzione molto intelligente
QGA

1
Il secondo, è estremamente veloce
QGA

1
Puoi farlo nel secondo esempio: return [ore, minuti, secondi] .filter (t => t) .map (pad) .join (":")
Onno Faber

@OnnoFaber Quale pensi sia il più veloce? concatenazione o un filtro più una mappa? Potremmo anche fare`${pad(hours)}:${pad(minutes)}:${pad(secs)}`
mplungjan

Di tutte le risposte precedenti, la più semplice è quella di mplungjan , ma ha un errore che mostra numeri casuali se il valore ha millisecondi (ad esempio: 17,3 s). In base al suo codice, propongo quanto segue: function pad (num) {return ("0" + num) .slice (-2); } / ** * @return {stringa} * / export funzione predefinita renderUserTime (secondi) {let minutes = Math.floor (seconds / 60); const outputSecs = Math.round (secondi% 60); let hours = Math.floor (minutes / 60); const outputMinutes = Math.round (minuti% 60); return `$ {pad (hours)}: $ {pad (outputMi
Alberto Soto

94

Questo è simile alla risposta mplungjan a cui fa riferimento un altro post, ma più conciso:

const secs = 456;

const formatted = moment.utc(secs*1000).format('HH:mm:ss');

document.write(formatted);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

Soffre degli stessi avvertimenti, ad esempio se i secondi superano un giorno (86400), non otterrai ciò che ti aspetti.


1
grazie, penso che questa sia un'esigenza molto comune, apri una richiesta pull a moment.js dovrebbero incorporarla.
Morris S

Grazie @Sophie. Pochi luoghi menzionano utc (), che è esattamente ciò che era necessario nel mio caso.
pmont

24

Puoi utilizzare il plug -in formato durata del momento :

var seconds = 3820;
var duration = moment.duration(seconds, 'seconds');
var formatted = duration.format("hh:mm:ss");
console.log(formatted); // 01:03:40
<!-- Moment.js library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>

<!-- moment-duration-format plugin -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/1.3.0/moment-duration-format.min.js"></script>

Vedi anche questo Fiddle

Aggiornamento: per evitare il taglio per valori inferiori a 60 secondi, utilizzare { trim: false }:

var formatted = duration.format("hh:mm:ss", { trim: false }); // "00:00:05"

C'è un compromesso che deve essere considerato con la tua risposta e la risposta di @ sophie. Anche se tecnicamente la tua soluzione mostrerà una durata di "Time" come hh: mm: ss, richiede il plugin aggiuntivo. Quella di Sophie è una "Data" dall'ora corrente formattata in hh: mm: ss. Se rimuovi l '"utc" da Sophie, potrebbe restituire informazioni errate poiché utilizza l'epoca come data e non il punto nel tempo corrente. Entrambe le risposte funzionano. Solo qualcosa a cui pensare e capire.
Michael

Anche se qui l'utilizzo del CDN e quant'altro potrebbe aumentare la latenza, è generalmente pericoloso pensare di "includere un'altra libreria" come un compromesso negativo rispetto all'implementazione del codice. Questa è una trappola in cui vedo cadere molti sviluppatori e alla fine si ritrovano con codice meno gestibile.
cytinus

per qualche motivo se i secondi <60, allora finisce semplicemente non formattato
Daniel Lizik

@DanielLizik, aggiungi {trim: false}. Ad esempio: duration.format ("hh: mm: ss", {trim: false});
Oleksiy Kachynskyy

16
var seconds = 2000 ; // or "2000"
seconds = parseInt(seconds) //because moment js dont know to handle number in string format
var format =  Math.floor(moment.duration(seconds,'seconds').asHours()) + ':' + moment.duration(seconds,'seconds').minutes() + ':' + moment.duration(seconds,'seconds').seconds();

1

Come utilizzare correttamente le durate di moment.js? | Usa moment.duration () nei codici

Innanzitutto, devi importare momente moment-duration-format.

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

Quindi, usa la funzione di durata. Applichiamo l'esempio precedente: 28800 = 8 am.

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

🎉Bene, non hai l'errore di tipo sopra. 🤔 Ottieni un 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, ora arriviamo alle 8:00. Se vuoi le 8:00 invece delle 8:00 per il tempo integrale, dobbiamo eseguire RegExp

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

1

Fino a 24 ore. Poiché Duration.formatè deprecato, con moment@2.23.0

const seconds = 123;
moment.utc(moment.duration(seconds,'seconds').as('milliseconds')).format('HH:mm:ss');
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.