Jak korzystać z formatu () podczas trwania pliku moment.js?

211

Czy jest jakiś sposób na użycie format metody moment.js na obiektach czasu trwania? Nigdzie nie mogę go znaleźć w dokumentach i nie wydaje się, aby był atrybutem obiektów czasu trwania.

Chciałbym móc zrobić coś takiego:

var diff = moment(end).unix() - moment(start).unix();
moment.duration(diff).format('hh:mm:ss')

Ponadto, jeśli istnieją inne biblioteki, które mogą łatwo dostosować się do tego rodzaju funkcjonalności, byłbym zainteresowany rekomendacjami.

Dzięki!

mvanveen
źródło
5
moment.utc (duration.asMilliseconds ()). format ('hh: mm: ss'); - Czas trwania jest wektorem. Umieszczając ogon na początku, możesz użyć formatowania daty, aby uzyskać gg: mm: ss.
Paul Williams
moment.utc (moment.duration (23, 'sekund'). asMilliseconds ()). format ('hh: mm: ss') => „12:00:23” nie działa tak dobrze
goldenratio
Ach, znalazłem problem, HH:mm:sspodam 00:00:23w moim poprzednim przykładzie. więc po prostu niewłaściwa obudowa od strony Godziny
goldenratio

Odpowiedzi:

55

Zastanawiamy się nad dodaniem pewnego rodzaju formatowania do czasów trwania w mom.js. Zobacz https://github.com/timrwood/moment/issues/463

Kilka innych bibliotek, które mogą pomóc, to http://countdownjs.org/ i https://github.com/icambron/twix.js

timrwood
źródło
4
Nie mogę się też doczekać formatowania czasu trwania. Spójrzmy teraz na odliczanie, ale twix wydaje się robić tylko „inteligentne” formatowanie, a nie wiele dostosowań.
mpen
2
Chociaż twix ciężko pracuje nad inteligentnym formatowaniem, ma wiele opcji formatowania, aż do zaangażowanych tokenów: github.com/icambron/twix.js/wiki/Formatting . Uwaga: Jestem autorem twix.
3
Countdown.js jest doskonały, a autor jest bardzo pomocny (właśnie wydał 2 wersje tego samego dnia z powodu niektórych sugestii).
Ohad Schneider,
5
Głosuję w dół, ponieważ kwestia github powiązana z tą odpowiedzią jest po prostu niekończącym się strumieniem opinii, życzeń i rantów, które nie prowadzą do żadnego miejsca, problem jest nadal otwarty po 4 latach, nic użytecznego
bmaggi
29
Dlaczego nie może być identyczny z innym formatem używanym gdzie indziej w bibliotece? To jest szaleństwo. 5 lat i nadal nie jest gotowe? naprawdę?!
Kristopolous
164
// set up
let start = moment("2018-05-16 12:00:00"); // some random moment in time (in ms)
let end = moment("2018-05-16 12:22:00"); // some random moment after start (in ms)
let diff = end.diff(start);

// execution
let f = moment.utc(diff).format("HH:mm:ss.SSS");
alert(f);

Spójrz na JSFiddle

David Glass
źródło
3
Dobre podejscie. Chociaż to nie działa, jeśli chcę również wyświetlać dni: DDD HH:mm:ss.SSS(gdzie DDDjest dzień roku) wyświetla się, 1kiedy chcę 0. Jakaś szybka naprawa tego?
Andrew Mao,
1
Nie ma łatwego sposobu. Zrobiłem to jsfiddle.net/fhdd8/14 , co jest prawdopodobnie tym, co zrobiłeś, ale nie sądzę, że chwila ma coś, co robi to po wyjęciu z pudełka
David Glass
49
Nie ma sensu wyświetlać 10 biliardów milisekund jako mm: ss
Pier-Luc Gendreau
28
to nie działa w ciągu ostatnich 24 godzin (tzn. gdybym chciał wyświetlić 117 godzin). w przeciwnym razie świetne rozwiązanie!
Phil
1
@ Filip możesz użyć „D” lub „DD”, jeśli chcesz pokazywać dni.
Vinay,
71

przelicz czas trwania na ms, a następnie na moment:

moment.utc(duration.as('milliseconds')).format('HH:mm:ss')
Sagiv Ofek
źródło
14
To nie działa, jeśli twój czas trwania jest dłuższy niż 24
godziny
4
@ S.Robijns jest użyteczną obserwacją, ale dla podkreślenia dla innych - takie jest oczekiwane zachowanie .format('HH:mm:ss'). Zobacz dokumentację
davnicwil
1
to najlepsza odpowiedź!
Magico
44

Użyj tej wtyczki Format Moment Duration .

Przykład:

moment.duration(123, "minutes").format("h:mm");
kayz1
źródło
1
To formatowanie nie działa poprawnie, strona czasu trwania jest dobra, ale jeśli podam hh:mm:mmi mam tylko 10 sekund, pokazuje to 10zamiast 00:00:10(nawet przy włączonej forcelength) Jeśli nie formatuje ... to należy to nazwać czymś innym, formaty powinny być znormalizowany.
Piotr Kula,
9
@ppumkin wiem, że to jest stare, ale jeśli { trim: false }go określisz , przestanie to działać .
Carlos Martinez,
3
To jest to, co wolę używać: Załóżmy, że masz czas trwania, const duration = moment.duration(value, 'seconds');niż można sformatować za pomocą: moment.utc(duration.as('milliseconds')).format('HH:mm:ss').toString();
Evgeny Bobkin
1
@EvgenyBobkin, który nie będzie działać, jeśli twój czas trwania jest dłuższy niż jeden dzień, biblioteka sobie z tym poradzi
reggaeguitar
16

Użyj tego wiersza kodu:

moment.utc(moment.duration(4500, "seconds").asMilliseconds()).format("HH:mm:ss")
NFpeter
źródło
8
Jeśli czas trwania wynosi> 86400 '' (tj. 24 godziny), to nie zadziała.
Lorenzo Tassone
To samo w programie Excel, przewinie się o 24 godziny. Jest to świetne obejście, jeśli zdajesz sobie sprawę z ograniczenia 24 godzin.
Eman4real,
15
var diff = moment(end).unix() - moment(start).unix();
moment.utc(moment.duration(diff).asMilliseconds()).format("HH:mm:ss.SSS");
Eric Saboia
źródło
1
Zasadniczo odpowiedzi są o wiele bardziej pomocne, jeśli zawierają wyjaśnienie tego, do czego służy kod i dlaczego rozwiązuje problem bez przedstawiania innych. (Ten post został oflagowany przez co najmniej jednego użytkownika, prawdopodobnie dlatego, że uważali, że odpowiedź bez wyjaśnienia powinna zostać usunięta.)
Nathan Tuggy
1
Bez wyjaśnienia czy nie, to właśnie zrobiło dla mnie. Dzięki :)
dmmd
Wyjaśnienie nie jest potrzebne. Dokument Moment.js może pokazać, w jaki sposób osiągnięto to rozwiązanie.
coffekid
2
Bezużyteczny. Jak większość innych odpowiedzi na to pytanie, zwraca częściowe godziny w czasie, a nie całkowite godziny. Np. Zwraca 12:00 na czas trwania. Czas trwania ({dni: 2, godziny: 12})
Neutrino
1
moment.duration (diff) .asMilliseconds () jest nadmierna. Możesz po prostu użyć diff, jest już w milisekundach.
kristopolous,
12

Najlepszy scenariusz dla mojego konkretnego przypadku użycia to:

var duration = moment.duration("09:30"),
    formatted = moment.utc(duration.asMilliseconds()).format("HH:mm");

Poprawia się to po odpowiedzi @ Wilsona, ponieważ nie ma on dostępu do prywatnych danych wewnętrznych _data.

TaeKwonJoe
źródło
Dziękuję @TaeKwonJoe
Kamlesh
11

Nie potrzebujesz .format. Użyj takich czasów:

const duration = moment.duration(83, 'seconds');
console.log(duration.minutes() + ':' +duration.seconds());
// output: 1:23

Znalazłem to rozwiązanie tutaj: https://github.com/moment/moment/issues/463

EDYTOWAĆ:

I z wypełnieniem na sekundy, minuty i godziny:

const withPadding = (duration) => {
    if (duration.asDays() > 0) {
        return 'at least one day';
    } else {
        return [
            ('0' + duration.hours()).slice(-2),
            ('0' + duration.minutes()).slice(-2),
            ('0' + duration.seconds()).slice(-2),
        ].join(':')
    }
}

withPadding(moment.duration(83, 'seconds'))
// 00:01:23

withPadding(moment.duration(6048000, 'seconds'))
// at least one day
ni-ko-o-kin
źródło
2
Nie obejmuje to zer wiodących, jeśli czas trwania.
Sekund
Co się stanie, jeśli masz więcej sekund niż godzinę? Czy to w porządku, że masz wtedy ponad 60 sekund?
shaedrich
Zera wiodące działają, ale duration = moment.duration(7200, 'seconds'); withPadding(duration);powiedzą „00:00”.
shaedrich,
@shaedrich Ponownie zaktualizowałem swoją odpowiedź, aby uwzględnić godziny; jeśli potrzebujesz dni, tygodni, a także możesz dodać je do tablicy
ni-ko-o-kin
1
if (duration.asDays() > 0) { return 'at least one day';- czy czytam to poprawnie?
Stephen Paul,
8

Używam:

var duration = moment.duration("09:30");
var str = moment(duration._data).format("HH:mm");

I dostaję „09:30” w var str.

Wilson
źródło
Wspaniały! To po prostu działa ... jak do
cholery
4
Unikaj tego rozwiązania, _datajest własnością wewnętrzną i może ulec zmianie bez ostrzeżenia.
Druska
1
Niestety nie zawsze będzie działać zgodnie z oczekiwaniami: moment(moment.duration(1200000)._data).format('hh:mm:ss')zwróci 12:20 zamiast 00:20
Anna R
2
@ AnnaR hjest w zakresie 1-12, więc jest raczej przewidywalna. HZamiast tego użyj docs - tokeny godzin
barbsan
To źle, nie tylko ignorujesz DNI, więc 1 dzień i 1 godzina będą wyświetlane jako 01:00. Ponadto całkowicie ignorujesz strefy czasowe, lepszym rozwiązaniem, ale też niepełnym będzie moment.utc(...).format("HH:mm");
Gil Epshtain
5

jeśli diff jest chwilą

var diff = moment(20111031) - moment(20111010);
var formated1 = moment(diff).format("hh:mm:ss");
console.log("format 1: "+formated1);
Kieran
źródło
Nie wydaje się to wiarygodne w obliczu stref czasowych i tym podobnych. Czy używasz tego w produkcji?
Keith,
pytanie nie wspomina o strefach czasowych.
Kieran
3
Wszyscy żyją w strefie czasowej. Czy moment (0) zawsze rejestruje się jako 12:00 AM w każdej strefie czasowej?
Keith,
Po prostu pytam, czy kod w twojej odpowiedzi działa, czy nie, ponieważ jestem sceptyczny. Napisałem dużo kodu, który działa z datami, w wielu językach programowania. Z mojego doświadczenia wynika, że ​​Twój kod działałby tylko w określonych strefach czasowych - ale pytam, ponieważ być może jest coś, czego nie wiem o tym, jak JavaScript reprezentuje daty w pobliżu epoki Uniksa.
Keith
1
druga linia stworzy moment od początku czasu (1970). To się nie uda.
kumarharsh
5

Jeśli chcesz użyć innej biblioteki javascript, numeral.js może sformatować sekundy w następujący sposób (przykład to 1000 sekund):

var string = numeral(1000).format('00:00');
// '00:16:40'
GChorn
źródło
zdecydowanie droga. zgodnie z oczekiwaniami.
Piotr Kula,
4

Używam klasycznej funkcji formatowania w następujących przypadkach:

var diff = moment(end).unix() - moment(start).unix();

//use unix function instead of difference
moment.unix(diff).format('hh:mm:ss')

Jest to hack, ponieważ różnicę czasu traktuje się jako datę standardową, wczesną datę epoki, ale nie ma to znaczenia dla naszego celu i nie potrzebujesz żadnej wtyczki

Pasy
źródło
4

Jeśli wszystkie godziny muszą być wyświetlane (więcej niż 24) i jeśli „0” przed godzinami nie jest konieczne, formatowanie można wykonać za pomocą krótkiego wiersza kodu:

Math.floor(duration.as('h')) + moment.utc(duration.as('ms')).format(':mm:ss')
ov
źródło
4

Na podstawie odpowiedzi ni-ko-o-kin :

meassurements = ["years", "months", "weeks", "days", "hours", "minutes", "seconds"];
withPadding = (duration) => {
    var step = null;
    return meassurements.map((m) => duration[m]()).filter((n,i,a) => {
        var nonEmpty = Boolean(n);
        if (nonEmpty || step || i >= a.length - 2) {
            step = true;
        }
        return step;
    }).map((n) => ('0' + n).slice(-2)).join(':')
}

duration1 = moment.duration(1, 'seconds');
duration2 = moment.duration(7200, 'seconds');
duration3 = moment.duration(604800, 'seconds');

withPadding(duration1); // 00:01
withPadding(duration2); // 02:00:00
withPadding(duration3); // 01:07:00:00:00
Shaedrich
źródło
Nie sądzę, żeby to było bardzo czytelne. Jaki problem chcesz tutaj rozwiązać? Jaki jest twój przypadek użycia?
ni-ko-o-kin
Zaktualizowałem swoją odpowiedź ponownie, aby poradzić sobie z więcej niż jednym dniem. Działa dobrze w moim przypadku użycia.
ni-ko-o-kin
2
Problem polega na tym, że w większości przypadków twoje rozwiązanie nie jest idealne, ponieważ zawiera zbyt wiele zer wiodących. Kto chce otrzymać zwrot „00: 00: 00: 00: 01”? Moje rozwiązanie jest „skalowalne” i dodaje tyle zer wiodących, ile potrzeba.
shaedrich,
Działa świetnie. Bardzo prosta wydajność. Jeśli nie ma dni, nie będzie żadnych zer dla wyświetlanych dni itp.
Hasan Sefa Ozalp
3

Aby sformatować czas trwania momentu na ciąg

var duration = moment.duration(86400000); //value in milliseconds
var hours = duration.hours();
var minutes = duration.minutes();
var seconds = duration.seconds();
var milliseconds = duration.milliseconds();

var date = moment().hours(hours).minutes(minutes).seconds(seconds).millisecond(milliseconds);
if (is12hr){
    return date.format("hh:mm:ss a");
}else{
    return date.format("HH:mm:ss");
}
Dineshkani
źródło
3

jeśli używasz kątowej, dodaj to do filtrów:

.filter('durationFormat', function () {
    return function (value) {
        var days = Math.floor(value/86400000);
        value = value%86400000;
        var hours = Math.floor(value/3600000);
        value = value%3600000;
        var minutes = Math.floor(value/60000);
        value = value%60000;
        var seconds = Math.floor(value/1000);
        return (days? days + ' days ': '') + (hours? hours + ' hours ': '') + (minutes? minutes + ' minutes ': '') + (seconds? seconds + ' seconds ': '')
    }
})

przykład użycia

<div> {{diff | durationFormat}} </div>
Hai Alaluf
źródło
Naprawdę bardzo ładnie. Szukałem takiego „ładnego formatu”. Dzięki!
riketscience
3

Moje rozwiązanie, które nie wymaga żadnej innej biblioteki i działa z diff> 24h

var momentInSeconds = moment.duration(n,'seconds')
console.log(("0" + Math.floor(momentInSeconds.asHours())).slice(-2) + ':' + ("0" + momentInSeconds.minutes()).slice(-2) + ':' + ("0" + momentInSeconds.seconds()).slice(-2))
Lorenzo Tassone
źródło
1

Co z rodzimym javascript?

var formatTime = function(integer) {
    if(integer < 10) {
        return "0" + integer; 
    } else {
        return integer;
    }
}

function getDuration(ms) {
    var s1 = Math.floor(ms/1000);
    var s2 = s1%60;
    var m1 = Math.floor(s1/60);
    var m2 = m1%60;
    var h1 = Math.floor(m1/60);
    var string = formatTime(h1) +":" + formatTime(m2) + ":" + formatTime(s2);
    return string;
}
J. Allen
źródło
1

Użyj formatu czasu trwania .

Client Framework (np. React)

import moment from 'moment';
import momentDurationFormatSetup from 'moment-duration-format';
momentDurationFormatSetup(moment);

const breakLengthInMinutes = moment.duration(breakLengthInSeconds, 's').format('m');

Serwer (node.js)

const moment = require("moment-timezone");
const momentDurationFormatSetup = require("moment-duration-format");

momentDurationFormatSetup(moment);

const breakLengthInMinutes = moment.duration(breakLengthInSeconds, 's').format('m');
AryanJ-NYC
źródło
0
const duration = moment.duration(62, 'hours');
const n = 24 * 60 * 60 * 1000;
const days = Math.floor(duration / n);
const str = moment.utc(duration % n).format('H [h] mm [min] ss [s]');
console.log(`${days > 0 ? `${days} ${days == 1 ? 'day' : 'days'} ` : ''}${str}`);

Wydruki:

2 dni 14 godz. 00 min 00 sek

davidhq
źródło
0
import * as moment from 'moment'
var sleep = require('sleep-promise');

(async function () {
    var t1 = new Date().getTime();
    await sleep(1000); 
    var t2 = new Date().getTime();
    var dur = moment.duration(t2-t1); 
    console.log(`${dur.hours()}h:${dur.minutes()}m:${dur.seconds()}s`);
})();
0h:0m:1s
zestaw narzędzi
źródło
0

Możesz użyć numeral.js do sformatowania czasu trwania:

numeral(your_duration.asSeconds()).format('00:00:00') // result: hh:mm:ss
João Paulo
źródło
0

Można tego użyć, aby uzyskać pierwsze dwa znaki jako godziny, a ostatnie dwa jako minuty. Ta sama logika może być zastosowana do sekund.

/**
     * PT1H30M -> 0130
     * @param {ISO String} isoString
     * @return {string} absolute 4 digit number HH:mm
     */

    const parseIsoToAbsolute = (isoString) => {
    
      const durations = moment.duration(isoString).as('seconds');
      const momentInSeconds = moment.duration(durations, 'seconds');
    
      let hours = momentInSeconds.asHours().toString().length < 2
        ? momentInSeconds.asHours().toString().padStart(2, '0') : momentInSeconds.asHours().toString();
        
      if (!Number.isInteger(Number(hours))) hours = '0'+ Math.floor(hours);
    
      const minutes = momentInSeconds.minutes().toString().length < 2
        ? momentInSeconds.minutes().toString().padEnd(2, '0') : momentInSeconds.minutes().toString();
    
      const absolute = hours + minutes;
      return absolute;
    };
    
    console.log(parseIsoToAbsolute('PT1H30M'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

José Luis Raffalli
źródło
Jeśli wstawisz kod jako fragment kodu, będziesz mógł przetestować metodę i wyświetlić dane wyjściowe w konsoli.
DJDaveMark
Jasne! Właśnie zaktualizowano za pomocą fragmentu kodu do szybkich testów.
José Luis Raffalli
0

moment.duration(x).format()został wycofany. Możesz użyć, moment.utc(4366589).format("HH:mm:ss")aby uzyskać pożądaną odpowiedź.

console.log(moment.utc(4366589).format("HH:mm:ss"))
<script src="https://momentjs.com/downloads/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

kindacoder
źródło
0

Jak poprawnie używać czasów mom.js? | Użyj moment.duration () w kodzie

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");

Ell No cóż, nie występuje błąd powyżej typu. 🤔 Czy masz odpowiednią wartość 8:00? Nie… otrzymana wartość to 8:00 a. Format Moment.js nie działa tak, jak powinien.

Solution Rozwiązaniem jest przekształcenie sekund w milisekundy i wykorzystanie czasu UTC.

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

W porządku, teraz mamy 8:00. Jeśli chcesz 8 rano zamiast 8:00 czasu integralnego, musimy zrobić RegExp

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

Musiałem to zrobić do pracy jako wymóg wyświetlania godzin w tym formacie. Na początku próbowałem tego.

moment.utc(totalMilliseconds).format("HH:mm:ss")

Jednak wszystko w ciągu 24 godzin i godziny resetują się do 0. Ale minuty i sekundy były dokładne. Wykorzystałem więc tylko tę część minut i sekund.

var minutesSeconds = moment.utc(totalMilliseconds).format("mm:ss")

Teraz potrzebuję tylko całkowitej liczby godzin.

var hours = moment.duration(totalMilliseconds).asHours().toFixed()

Aby uzyskać format, który wszyscy chcemy, po prostu go sklejamy.

var formatted = hours + ":" + minutesSeconds

jeśli totalMillisecondsjest 894600000to wróci 249:30:00.

Mam nadzieję, że to pomogło. Zostaw wszelkie pytania w komentarzach. ;)

Zach Dyer
źródło
-1

Jeśli używasz Angular> 2, stworzyłem fajkę zainspirowaną odpowiedzią @ hai-alaluf.

import {Pipe, PipeTransform} from "@angular/core";

@Pipe({
  name: "duration",
})

export class DurationPipe implements PipeTransform {

  public transform(value: any, args?: any): any {

    // secs to ms
    value = value * 1000;
    const days = Math.floor(value / 86400000);
    value = value % 86400000;
    const hours = Math.floor(value / 3600000);
    value = value % 3600000;
    const minutes = Math.floor(value / 60000);
    value = value % 60000;
    const seconds = Math.floor(value / 1000);
    return (days ? days + " days " : "") +
      (hours ? hours + " hours " : "") +
      (minutes ? minutes + " minutes " : "") +
      (seconds ? seconds + " seconds " : "") +
      (!days && !hours && !minutes && !seconds ? 0 : "");
  }
}
0x29A
źródło
-3

To działa dla mnie:

moment({minutes: 150}).format('HH:mm') // 01:30
Natan Augusto
źródło
Zwróć „Nieprawidłowa data”
themadmax
3
150 minut to nie 1 godzina 30 minut.
Mark Brown