Como converter segundos em HH: mm: ss em moment.js

93

Como posso converter segundos em HH:mm:ss?

No momento estou usando a função abaixo

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

Isso funciona no Chrome, mas no firefox por 12 segundos, eu entendi 01:00:12 que gostaria de usar o moment.js para compatibilidade entre navegadores

Eu tentei isso mas não funciona

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

O que estou fazendo de errado?

EDITAR

Consegui encontrar uma solução sem moment.js que é a seguinte

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

Ainda curioso para saber como posso fazer isso no moment.js

QGA
fonte
@mplungjan Desculpe por não ter mencionado que já li aquele post. Preciso renderizar uma tabela com milhões de linhas e a solução é muito lenta. a segunda resposta é exatamente o que escrevi na minha pergunta, mas me dá problemas no firefox
QGA
2
@QuentinTanioartino então 4 operadores matemáticos triviais é um problema para a tarefa de transformar DOM para milhões de elementos? Tem certeza de que entendeu o problema de desempenho corretamente?
zerkms de
@zerkms bem, eu sei que minhas classes DAO devem ser reescritas para servir os dados já convertidos. Este é um problema do qual estou ciente. Disse que estou bastante feliz com o desempenho atual da minha primeira tentativa, mas quando tenho 5 operações matemáticas para uma conversão isso torna o sistema um pouco mais lento. Sim, concordo com você que esta é apenas uma solução TEMPORÁRIA rápida
QGA
@QuentinTanioartino "que retarda o sistema um pouco" --- "um pouco" não é como você raciocina sobre o desempenho. É um gargalo? Está provado ser um gargalo? Se não, o que o leva a otimizar essa operação?
zerkms de

Respostas:

79

A partir desta postagem, eu tentaria isso para evitar problemas de salto

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

Eu não executei jsPerf, mas acho que isso é mais rápido do que criar novos objetos de data um milhão de vezes

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
}

mplungjan
fonte
2
Muito obrigado, solução muito inteligente
QGA
1
O segundo, é extremamente rápido
QGA
1
Você poderia fazer isso no segundo exemplo: return [horas, minutos, segundos] .filter (t => t) .map (pad) .join (":")
Onno Faber
@OnnoFaber O que você acha que é o mais rápido? concatenação ou um filtro mais um mapa? Também poderíamos fazer`${pad(hours)}:${pad(minutes)}:${pad(secs)}`
mplungjan
De todas as respostas anteriores, a mais simples é a de mplungjan , mas há um erro que mostra números aleatórios se o valor tiver milissegundos (por exemplo: 17,3 s). Baseado em seu código, proponho o seguinte: function pad (num) {return ("0" + num) .slice (-2); } / ** * @return {string} * / função padrão de exportação renderUserTime (segundos) {let minutes = Math.floor (seconds / 60); const outputSecs = Math.round (segundos% 60); deixe horas = Math.floor (minutos / 60); const outputMinutes = Math.round (minutos% 60); retornar `$ {pad (horas)}: $ {pad (outputMi
Alberto Soto

94

Isso é semelhante à resposta mplungjan referenciada em outra postagem, mas mais concisa:

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>

Ele sofre das mesmas ressalvas, por exemplo, se os segundos excederem um dia (86400), você não obterá o que espera.


1
obrigado, acho que essa é uma necessidade muito comum, abra uma solicitação de pull para moment.js, eles devem incorporá-la.
Morris S

Obrigado @Sophie. Poucos lugares mencionam utc (), que é exatamente o que era necessário no meu caso.
pmont,

24

Você pode usar o plugin de formato de duração de 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>

Veja também este Fiddle

Upd: Para evitar o corte de valores menores que 60 segundos, use { trim: false }:

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

Há uma compensação que precisa ser analisada com sua resposta e a resposta de @sophie. Embora tecnicamente sua solução exiba uma duração de "Tempo" como hh: mm: ss, ela requer o plug-in extra. Sophie é uma "Data" do ponto atual no tempo formatado para hh: mm: ss. Se você removeu o "utc" do de Sophie, ele poderia retornar informações incorretas, pois usa a época como a data e não o ponto atual no tempo. Ambas as respostas funcionam. Apenas algo para pensar e entender.
Michael

Embora aqui o uso de CDN e outros enfeites possa aumentar a latência, geralmente é perigoso pensar em "incluir outra biblioteca" como uma compensação negativa em relação à implementação de código você mesmo. Essa é uma armadilha na qual vejo muitos desenvolvedores cair e, no final das contas, acabam com um código menos sustentável.
cytinus

por alguma razão, se segundos <60, então ele acaba sem
formatação

@DanielLizik, basta adicionar {trim: false}. Por exemplo: 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();
yehonatan yehezkel
fonte
1

Como usar corretamente as durações de moment.js? | Use moment.duration () em códigos

Primeiro, você precisa importar momente moment-duration-format.

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

Então, use a função de duração. Vamos aplicar o exemplo acima: 28800 = 8h.

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

🎉Bem, você não tem erro de tipo acima. 🤔Você obteve um valor correto às 8h? Não…, o valor que você obtém é 8:00 a. O formato Moment.js não está funcionando como deveria.

💡A solução é transformar segundos em milissegundos e usar o horário UTC.

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

Tudo bem, agora temos 8h. Se você quiser 8h em vez de 8h para horário integral, precisamos fazer RegExp

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

Até 24 horas. Como Duration.formatestá obsoleto, com [email protected]

const seconds = 123;
moment.utc(moment.duration(seconds,'seconds').as('milliseconds')).format('HH:mm:ss');
dev adgh1
fonte