Jak przekonwertować sekundy na HH: mm: ss w moment.js

94

Jak mogę zamienić sekundy na HH:mm:ss?

W tej chwili korzystam z poniższej funkcji

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

Działa to na Chrome, ale w Firefoxie przez 12 sekund otrzymuję 01:00:12 , że chciałbym używać momentu.js do kompatybilności z różnymi przeglądarkami

Próbowałem tego, ale nie działa

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

Co ja robię źle?

EDYTOWAĆ

Udało mi się znaleźć rozwiązanie bez moment.js, które jest następujące

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

Wciąż ciekawi mnie, jak mogę to zrobić w chwili.js

QGA
źródło
@mplungjan Przepraszamy, że nie wspomniałem, że przeczytałem już ten post. Muszę wyrenderować tabelę z milionami wierszy, a rozwiązanie jest zbyt wolne. druga odpowiedź jest dokładnie taka, jaką napisałem w swoim pytaniu, ale daje mi problemy w
Firefoksie
2
@QuentinTanioartino więc 4 trywialne operatory matematyczne to problem w przypadku zadania mutacji DOM dla milionów elementów? Czy na pewno dobrze rozumiesz problem z wydajnością?
zerkms
@zerkms Dobrze wiem, że moje klasy DAO muszą zostać przepisane, aby obsługiwały już przekonwertowane dane. Jest to problem, o którym wiem. Powiedział, że jestem całkiem zadowolony z obecnych wyników mojej pierwszej próby, ale kiedy mam 5 operacji matematycznych na konwersję, która trochę spowalnia system. Tak, zgadzam się z tobą, że to tylko szybkie rozwiązanie TYMCZASOWE
QGA,
@QuentinTanioartino ”, które spowalnia system nieco” --- ”, nie jest tym, jak rozumujesz wydajność. Czy to wąskie gardło? Czy udowodniono, że jest wąskim gardłem? Jeśli nie - co cię motywuje do optymalizacji tej operacji?
zerkms

Odpowiedzi:

81

Z tego postu spróbuję tego, aby uniknąć problemów ze skokiem

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

Nie uruchomiłem jsPerf, ale myślę, że jest to szybsze niż tworzenie nowych obiektów daty milion razy

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
źródło
2
Wielkie
1
Drugi, jest niesamowicie szybki
QGA,
1
Możesz to zrobić w drugim przykładzie: return [godziny, minuty, sekundy] .filter (t => t) .map (pad) .join (":")
Onno Faber
@OnnoFaber Jak myślisz, co jest najszybsze? konkatenacja czy filtr plus mapa? Mogliśmy też zrobić`${pad(hours)}:${pad(minutes)}:${pad(secs)}`
mplungjan
Ze wszystkich wcześniejszych odpowiedzi najprostsza to odpowiedź mplungjan , ale zawiera błąd, który pokazuje liczby losowe, jeśli wartość ma milisekundy (na przykład: 17,3 s). Bazując na jego kodzie, proponuję co następuje: function pad (num) {return ("0" + num) .slice (-2); } / ** * @return {string} * / export default function renderUserTime (sekundy) {let minutes = Math.floor (sekundy / 60); const outputSecs = Math.round (sekundy% 60); let hours = Math.floor (minuty / 60); const outputMinutes = Math.round (minuty% 60); return `$ {pad (godziny)}: $ {pad (outputMi
Alberto Soto

98

Jest to podobne do odpowiedzi mplungjan, do której odwołuje się inny post, ale bardziej zwięzłe:

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>

Cierpi na te same zastrzeżenia, np. Jeśli sekundy przekroczą jeden dzień (86400), nie otrzymasz tego, czego się spodziewasz.


1
dziękuję, myślę, że jest to bardzo częsta potrzeba, otwórz żądanie ściągnięcia na moment.js, powinni go uwzględnić.
Morris S

Dzięki @Sophie. Niewiele miejsc wspomina o utc (), co było dokładnie tym, czego potrzebowałem w moim przypadku.
pmont

25

Możesz użyć wtyczki formatu czasu trwania :

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>

Zobacz także to Fiddle

Aktualizacja: Aby uniknąć przycinania dla wartości krótszych niż 60 sekund, użyj { trim: false }:

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

Jest pewien kompromis, na który należy zwrócić uwagę w przypadku Twojej odpowiedzi i odpowiedzi @ sophie. Chociaż technicznie rozwiązanie będzie wyświetlało czas trwania „Czas” jako gg: mm: ss, wymaga dodatkowej wtyczki. Sophie to „Data” od bieżącego momentu w formacie gg: mm: ss. Jeśli usuniesz „utc” z Sophie's, może zwrócić niepoprawne informacje, ponieważ używa epoki jako daty, a nie bieżącego punktu w czasie. Obie odpowiedzi działają. Coś do przemyślenia i zrozumienia.
Michael

Podczas gdy tutaj używanie CDN i innych rzeczy mogłoby zwiększyć opóźnienie, generalnie niebezpieczne jest myślenie o „włączeniu innej biblioteki” jako o negatywnym kompromisie w porównaniu z samodzielnym wdrażaniem kodu. Jest to pułapka, w którą wpada wielu programistów i ostatecznie kończy się kodem, który jest trudniejszy do utrzymania.
cytinus

z jakiegoś powodu, jeśli sekundy <60, to po prostu kończy się niesformatowanie
Daniel Lizik

@DanielLizik, po prostu dodaj {trim: false}. Np .: 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
źródło
1

Jak poprawnie używać czasów trwania moment.js? | Użyj w kodach momentu.duration ()

Najpierw musisz zaimportować momenti moment-duration-format.

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

Następnie użyj funkcji czasu trwania. Zastosujmy powyższy przykład: 28800 = 8 rano.

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

🎉Cóż, nie masz powyższego błędu typu. 🤔Czy otrzymujesz właściwą wartość o 8:00? Nie…, otrzymana wartość to 8:00. Format Moment.js nie działa tak, jak powinien.

💡 Rozwiązaniem jest zamiana sekund na milisekundy i użycie czasu UTC.

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

W porządku, teraz mamy 8:00. Jeśli chcesz, aby godzina 8 rano zamiast 8:00 była czasem całkowania, musimy wykonać RegExp

const time = moment.utc(moment.duration(value, 'seconds').asMilliseconds()).format('h:mm a');
time.replace(/:00/g, '')
Farrukh Malik
źródło
1

Do 24 godz. Jak Duration.formatjest przestarzałe, z [email protected]

const seconds = 123;
moment.utc(moment.duration(seconds,'seconds').as('milliseconds')).format('HH:mm:ss');
dev adgh1
źródło
1

Moje rozwiązanie do zmiany sekund (liczby) na format ciągu (na przykład: 'mm: ss'):

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

Wpisz swoje sekundy zamiast „S” na przykład. I po prostu użyj „formattedSeconds” tam, gdzie potrzebujesz.

Adi Dasler
źródło