Cómo convertir segundos a HH: mm: ss en moment.js


94

¿Cómo puedo convertir segundos a HH:mm:ss?

En este momento estoy usando la función a continuación

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

Esto funciona en Chrome, pero en Firefox durante 12 segundos, 01:00:12 me gustaría usar moment.js para la compatibilidad entre navegadores.

Intenté esto pero no funciona

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

¿Qué estoy haciendo mal?

EDITAR

Me las arreglé para encontrar una solución sin moment.js que es la siguiente

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

Todavía tengo curiosidad por saber cómo puedo hacerlo en moment.js



@mplungjan Perdón por no haber mencionado que ya leí esa publicación. Necesito renderizar una tabla con millones de filas y la solución es demasiado lenta. la segunda respuesta es exactamente lo que he escrito en mi pregunta pero me da problemas en
Firefox

2
@QuentinTanioartino ¿Entonces 4 operadores matemáticos triviales son un problema para la tarea de mutar DOM para millones de elementos? ¿Está seguro de que comprende correctamente el problema de rendimiento?
zerkms

@zerkms bien, sé que mis clases DAO deben reescribirse para servir los datos ya convertidos. Este es un problema del que soy consciente. Dijo que estoy bastante contento con el rendimiento actual de mi primer intento, pero cuando tengo 5 operaciones matemáticas para una conversión que ralentiza un poco el sistema. Sí, estoy de acuerdo con usted en que esta es solo una solución TEMPORAL rápida
QGA

@QuentinTanioartino "eso ralentiza un poco el sistema" --- "un poco" no es lo que piensas sobre el rendimiento. ¿Es un cuello de botella? ¿Se ha demostrado que es un cuello de botella? Si no, ¿qué le impulsa a optimizar esta misma operación?
zerkms

Respuestas:


81

Desde esta publicación , probaría esto para evitar problemas de salto.

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

No ejecuté jsPerf, pero creo que esto es más rápido que crear nuevos objetos de fecha un millón de veces

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
Muchas gracias, solución muy inteligente
QGA

1
El segundo, es extremadamente rápido
QGA

1
Puede hacer esto en el segundo ejemplo: return [horas, minutos, segundos] .filter (t => t) .map (pad) .join (":")
Onno Faber

@OnnoFaber ¿Cuál crees que es el más rápido? concatenación o un filtro más un mapa? También podríamos hacerlo`${pad(hours)}:${pad(minutes)}:${pad(secs)}`
mplungjan

De todas las respuestas anteriores, la más simple es la de mplungjan , pero tiene un error que muestra números aleatorios si el valor tiene milisegundos (por ejemplo: 17.3 s). Basado en su código, propongo lo siguiente: function pad (num) {return ("0" + num) .slice (-2); } / ** * @return {cadena} * / exportar función predeterminada renderUserTime (segundos) {dejar minutos = Math.floor (segundos / 60); const outputSecs = Math.round (segundos% 60); let hours = Math.floor (minutos / 60); const outputMinutes = Math.round (minutos% 60); return `$ {pad (horas)}: $ {pad (outputMi
Alberto Soto

98

Esto es similar a la respuesta a la que mplungjan hace referencia en otra publicación, pero más 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>

Sufre de las mismas advertencias, por ejemplo, si los segundos superan un día (86400), no obtendrá lo que espera.


1
gracias, creo que esta es una necesidad muy común, abre una solicitud de extracción a moment.js deberían incorporarla.
Morris S

Gracias @Sophie. Pocos lugares mencionan utc (), que es exactamente lo que se necesitaba en mi caso.
pmont

25

Puede usar el complemento de formato de duración 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>

Ver también este violín

Upd: Para evitar recortar valores menores a 60 segundos, use { trim: false }:

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

Hay una compensación que debe examinarse con su respuesta y la respuesta de @ sophie. Aunque técnicamente su solución mostrará una duración de "Tiempo" como hh: mm: ss, requiere el complemento adicional. La de Sophie es una "Fecha" del punto actual en el tiempo formateada a hh: mm: ss. Si eliminó el "utc" de Sophie, podría devolver información incorrecta, ya que usa la época como fecha y no el momento actual. Ambas respuestas funcionan. Solo algo para pensar y comprender.
Michael

Si bien aquí el uso de CDN y otras cosas podría agregar una mayor latencia, generalmente es peligroso pensar en "incluir otra biblioteca" como una compensación negativa frente a la implementación del código usted mismo. Esta es una trampa en la que veo caer a muchos desarrolladores y finalmente terminan con un código menos mantenible.
cytinus

por alguna razón, si los segundos son <60, simplemente termina sin formatear
Daniel Lizik

@DanielLizik, solo agrega {trim: false}. Por ejemplo: 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

¿Cómo usar correctamente las duraciones de moment.js? | Utilice moment.duration () en los códigos

Primero, necesita importar momenty moment-duration-format.

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

Luego, use la función de duración. Apliquemos el ejemplo anterior: 28800 = 8 am.

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

🎉Bueno, no tiene el error de tipo anterior. 🤔 ¿Obtiene un valor correcto a las 8:00 am? No…, el valor que obtienes es 8:00 a. El formato Moment.js no funciona como se supone.

💡La solución es transformar segundos en milisegundos y usar la hora UTC.

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

Está bien, ahora llegamos a las 8:00 am. Si desea 8 am en lugar de 8:00 am para el tiempo integral, necesitamos hacer RegExp

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

1

Hasta las 24 hrs. Como Duration.formatestá en desuso, con moment@2.23.0

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

1

Mi solución para cambiar segundos (número) a formato de cadena (por ejemplo: 'mm: ss'):

const formattedSeconds = moment().startOf('day').seconds(S).format('mm:ss');

Escriba sus segundos en lugar de 'S' en el ejemplo. Y simplemente use 'formattedSeconds' donde lo necesite.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.