Как преобразовать секунды в ЧЧ: мм: сс в moment.js

94

Как преобразовать секунды в HH:mm:ss?

На данный момент я использую функцию ниже

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

Это работает на Chrome, но в firefox в течение 12 секунд я понимаю, 01:00:12 что хотел бы использовать moment.js для кроссбраузерной совместимости

Я пробовал это, но не работает

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

Что я делаю не так?

РЕДАКТИРОВАТЬ

Мне удалось найти решение без moment.js, которое выглядит следующим образом

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

Все еще любопытно, как я могу это сделать в moment.js

QGA
источник
@mplungjan Извините, что не упомянул, что уже прочитал этот пост. Мне нужно отобразить таблицу с миллионами строк, и решение там слишком медленное. второй ответ - это именно то, что я написал в своем вопросе, но вызывает у меня проблемы в firefox
QGA
2
@QuentinTanioartino, так что 4 тривиальных математических оператора - это проблема для задачи мутации DOM для миллионов элементов? Вы уверены, что правильно понимаете проблему с производительностью?
zerkms
@zerkms хорошо, я знаю, что мои классы DAO должны быть переписаны, чтобы обслуживать уже преобразованные данные. Это проблема, о которой я знаю. Сказал, что я вполне доволен текущими показателями моей первой попытки, но когда у меня есть 5 математических операций для преобразования, которое немного замедляет работу системы. Да, я согласен с вами, что это просто ВРЕМЕННОЕ решение
QGA
@QuentinTanioartino ", который немного замедляет работу системы" --- "немного" - это не то, что вы думаете о производительности. Это узкое место? Является ли это доказанный быть узким местом? Если нет - что побуждает оптимизировать именно эту операцию?
zerkms

Ответы:

81

Из этого поста я бы попробовал это, чтобы избежать проблем с прыжками

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

Я не запускал jsPerf, но думаю, что это быстрее, чем создание новых объектов даты в миллион раз.

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
источник
2
Большое спасибо, очень умное решение
QGA
1
Второй, очень быстрый
QGA
1
Вы можете сделать это во втором примере: return [часы, минуты, секунды] .filter (t => t) .map (pad) .join (":")
Онно Фабер
@OnnoFaber Как вы думаете, что самое быстрое? конкатенация или фильтр плюс карта? Мы тоже могли бы сделать`${pad(hours)}:${pad(minutes)}:${pad(secs)}`
mplungjan
Из всех предыдущих ответов самым простым является mplungjan , но в нем есть ошибка, которая показывает случайные числа, если значение имеет миллисекунды (например: 17,3 с). Основываясь на его коде, я предлагаю следующее: function pad (num) {return ("0" + num) .slice (-2); } / ** * @return {строка} * / экспортировать функцию по умолчанию renderUserTime (секунды) {let minutes = Math.floor (секунды / 60); const outputSecs = Math.round (секунд% 60); let hours = Math.floor (минут / 60); const outputMinutes = Math.round (минут% 60); return `$ {pad (hours)}: $ {pad (outputMi
Альберто Сото,

98

Это похоже на ответ mplungjan, на который ссылается другой пост, но более краткий:

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>

Он страдает теми же недостатками, например, если секунды превышают один день (86400), вы не получите того, чего ожидаете.


1
спасибо, я думаю, что это очень распространенная потребность, откройте запрос на перенос в moment.js, они должны его включить.
Morris S

Спасибо, @Sophie. В некоторых местах упоминается utc (), что как раз и было необходимо в моем случае.
pmont

25

Вы можете использовать плагин формата момента времени :

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>

См. Также эту скрипку

Upd: Чтобы избежать обрезки значений менее 60 секунд, используйте { trim: false }:

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

Есть компромисс, на который нужно смотреть с вашим ответом и ответом @sophie. Хотя технически ваше решение будет отображать продолжительность «Время» в формате чч: мм: сс, для этого требуется дополнительный плагин. Софи - это «Дата» от текущего момента времени в формате чч: мм: сс. Если вы удалите «utc» из Sophie's, он может вернуть неверную информацию, поскольку в качестве даты используется эпоха, а не текущий момент времени. Оба ответа работают. Просто нужно подумать и понять.
Майкл

Хотя здесь использование CDN и прочего может увеличить задержку, обычно опасно думать о «включении другой библиотеки» как о негативном компромиссе по сравнению с реализацией кода самостоятельно. Я вижу, что в эту ловушку попадают многие разработчики, которые в конечном итоге получают менее удобный в обслуживании код.
cytinus

по какой-то причине, если секунды <60, то он просто
остается

@DanielLizik, просто добавьте {trim: false}. Например: duration.format ("чч: мм: сс", {обрезка: ложь});
Алексей Качинский
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
источник
1

Как правильно использовать длительности moment.js? | Используйте moment.duration () в кодах

Во-первых, вам нужно импортировать momentи moment-duration-format.

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

Затем используйте функцию продолжительности. Давайте применим приведенный выше пример: 28800 = 8 утра.

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

🎉Ну, у вас нет вышеуказанной ошибки типа. 🤔У вас есть правильное значение 8:00 утра? Нет…, вы получите значение 8:00. Формат Moment.js работает не так, как должен.

💡 Решение состоит в том, чтобы преобразовать секунды в миллисекунды и использовать время UTC.

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

Ладно, сейчас 8:00. Если вы хотите 8:00 вместо 8:00 для интегрального времени, нам нужно сделать RegExp

const time = moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a');
time.replace(/:00/g, '')
Фаррух Малик
источник
1

До 24 часов. Как Duration.formatосуждается, с moment@2.23.0

const seconds = 123;
moment.utc(moment.duration(seconds,'seconds').as('milliseconds')).format('HH:mm:ss');
dev adgh1
источник
1

Мое решение для изменения секунд (числа) на строковый формат (например: 'mm: ss'):

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

Напишите свои секунды вместо «S» в примере. И просто используйте «formattedSeconds» там, где вам нужно.

Ади Даслер
источник