Як я можу використовувати формат () на час moment.js?


211

Чи можна використовувати метод moment.js format на об'єктах тривалості? Я не можу його знайти ніде в документах, і він не бачить атрибут об’єктів тривалості.

Мені б хотілося зробити щось на кшталт:

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

Крім того, якщо є якісь інші бібліотеки, які можуть легко відповідати такому функціоналу, мені будуть цікаві рекомендації.

Дякую!


5
момент.utc (тривалість.asMilliseconds ()). формат ('hh: mm: ss'); - Тривалість - вектор. Поклавши хвіст на початок, ви можете використовувати форматування дати, щоб отримати hh: mm: ss.
Пол Вільямс

moment.utc (момент.дурація (23, 'секунди'). asMilliseconds ()). формат ('hh: mm: ss') => "12:00:23" працює не так добре
goldenratio

Ах, я знайшов проблему, HH:mm:ssнаведу 00:00:23в своєму попередньому прикладі. тому просто неправильний кожух на частині Години
goldenratio

Відповіді:


55

Ми шукаємо додавати якийсь формат до тривалості в moment.js. Дивіться https://github.com/timrwood/moment/isissue/463

Кілька інших бібліотек, які можуть допомогти, - http://countdownjs.org/ та https://github.com/icambron/twix.js


4
Я також з нетерпінням чекаю форматування тривалості. Перегляньте countdownjs зараз, але, здається, що twix лише робить "розумне" форматування, не так багато налаштувань.
mpen

2
Хоча twix важко працює для інтелектуального форматування, він має безліч варіантів форматування, аж до лексем: github.com/icambron/twix.js/wiki/Formatting . Відмова: Я автор трікса.

3
Countdown.js чудовий, і автор надзвичайно корисний (він тільки що випустив 2 версії в той же день через деякі пропозиції, які я зробив)!
Охад Шнайдер

5
Я голосую, оскільки питання, пов'язане з github, пов’язане з цією відповіддю, - це просто нескінченний потік думок, побажань та мітингів, які ні до чого не ведуть, питання залишається відкритим через 4 роки, нічого корисного
bmaggi

29
Чому він не може бути ідентичним іншому .формату, який використовується в інших місцях бібліотеки? Це божевілля. 5 років, і це все ще не робиться? справді ?!
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);

Погляньте на JSFiddle


3
Гарний підхід. Хоча це не працює, якщо я хочу також відображати дні: DDD HH:mm:ss.SSS(де DDDдень року), 1коли я хочу 0. Будь-яке швидке виправлення для цього?
Ендрю Мао

1
Непростий спосіб. Я зробив це jsfiddle.net/fhdd8/14 , це, мабуть, те, що ви зробили, але я не думаю, що в моменті немає нічого такого, що робить це з коробки
Девід Глас

49
Немає сенсу відображати 10 квадрильйонів мілісекунд як мм: ss
Pier-Luc Gendreau

28
це не працює протягом останніх 24 годин (тобто якщо я хотів відобразити 117 годин). інакше чудове рішення!
Філ

1
@Phil ви можете використовувати "D" або "DD", якщо хочете показувати дні.
Vinay

71

конвертувати тривалість у мс, а потім у момент:

moment.utc(duration.as('milliseconds')).format('HH:mm:ss')

14
Так що це не працює , якщо ваш термін більше ніж за 24 години .. 24h це скидається в 0h
С. Robijns

4
@ S.Robijns корисним спостереження , але тільки щоб підкреслити для інших - це є очікуваним поведінкою .format('HH:mm:ss'). Дивіться документи
davnicwil

1
це найкраща відповідь!
Магіко

44

Використовуйте цей формат тривалості моменту плагіна .

Приклад:

moment.duration(123, "minutes").format("h:mm");

1
Це форматування не працює належним чином, сторона тривалості хороша, але якщо я вказав hh:mm:mmі маю лише 10 секунд, він показує 10замість 00:00:10(навіть із увімкненою формою сили) Якщо його не форматування ... тоді його слід називати чимось іншим, формати повинні бути стандартизовані.
Пьотр Кула

9
@ppumkin Я знаю, що це старе, але якщо ви вкажете, { trim: false }це припинить цю поведінку.
Карлос Мартінес

3
Це те, що я вважаю за краще використовувати: припустимо, у вас тривалість, як const duration = moment.duration(value, 'seconds');я можу відформатувати, використовуючи: moment.utc(duration.as('milliseconds')).format('HH:mm:ss').toString();
Євгеній Бобкін

1
@EvgenyBobkin не буде працювати, якщо ваша тривалість довше дня, але бібліотека буде працювати з цим, хоча
reggaeguitar

16

Використовуйте цей рядок коду:

moment.utc(moment.duration(4500, "seconds").asMilliseconds()).format("HH:mm:ss")

8
Якщо тривалість> 86400 '' (тобто 24 год), це не працюватиме.
Лоренцо Тассоне

Це те саме у excel, він перекинеться за 24 години. Це чудове рішення, якщо ви знаєте обмеження на 24 години.
Eman4real

15
var diff = moment(end).unix() - moment(start).unix();
moment.utc(moment.duration(diff).asMilliseconds()).format("HH:mm:ss.SSS");

1
Як правило, відповіді набагато корисніші, якщо вони включають пояснення того, що призначений для виконання коду та чому це вирішує проблему, не вводячи інших. (Цей пост було позначено хоча б одним користувачем, імовірно, тому, що вони вважали, що відповідь без пояснень слід видалити.)
Натан Туггі

1
Пояснення чи ні, саме це зробило для мене. Дякую :)
dmmd

Пояснення не потрібно. Moment.js doc може показати, як було досягнуто цього рішення.
кофекід

2
Марно. Як і більшість інших відповідей на це питання повертає часткові години тривалістю не загальною кількістю годин. Напр., Повертається 12:00 протягом тривалості моменту.дурація ({днів: 2, години: 12})
Neutrino

1
moment.duration (razl) .asMilliseconds () є надмірним. Можна просто використовувати diff, це вже в мілісекундах.
kristopolous

12

Найкращий сценарій для мого конкретного випадку використання:

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

Це покращується у відповідь @ Вілсона, оскільки він не має доступу до приватних даних про внутрішню власність.


Дякую @TaeKwonJoe
Kamlesh

11

Вам не потрібен .формат. Використовуйте тривалість, як це:

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

Я знайшов це рішення тут: https://github.com/moment/moment/isissue/463

Редагувати:

І з прокладками на секунди, хвилини та години:

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

2
Це не включатиме провідні нулі, якщо тривалість.секунди () менше 10, хоча ...
carpiediem

Що буде, якщо у вас більше секунди, ніж години? Це добре, що тоді у вас більше 60 секунд?
shaedrich

Ведучі нулі працюють, але duration = moment.duration(7200, 'seconds'); withPadding(duration);скажуть "00:00".
shaedrich

@shaedrich Я знову оновив свою відповідь, щоб включити години; якщо вам потрібні дні, тижні, також ви можете додати їх до масиву
ni-ko-o-kin

1
if (duration.asDays() > 0) { return 'at least one day';- я це правильно читаю?
Стівен Пол

8

Я використовую:

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

І я отримую "09:30" на вул.


Чудово! Це просто спрацьовує ... як же ви придумали це :)
vanthome

4
Уникайте цього рішення, _dataє внутрішньою властивістю і може змінюватися без попередження.
Друська

1
На жаль, це працюватиме не так, як очікувалося: moment(moment.duration(1200000)._data).format('hh:mm:ss')повернеться 12:20 замість 00:20
Anna R

2
@AnnaR hзнаходиться в діапазоні 1-12, тому це досить очікувано. Використовуйте Hнатомість документи - годинні жетони
barbsan

Це неправильно, не тільки те, що ви ігноруєте ДНІ, тому 1 день та 1 година відображатимуться як 01:00. Крім того , ви повністю ігноруючи тимчасові зони, краще рішення, але і не повний один буде moment.utc(...).format("HH:mm");
Gil Epshtain

5

якщо різниця - це момент

var diff = moment(20111031) - moment(20111010);
var formated1 = moment(diff).format("hh:mm:ss");
console.log("format 1: "+formated1);

Це не здається надійним в умовах часових поясів тощо. Чи використовуєте ви це у виробництві?
Кіт

питання не згадує часові пояси.
Киеран

3
Усі живуть у часовому поясі. Чи завжди момент (0) реєструється як 00:00 у кожному часовому поясі?
Кіт

Я просто запитую, чи працює у вашій відповіді код чи ні, тому що я скептично налаштований. Я написав багато коду, який працює з датами, багатьма мовами програмування. Виходячи з мого досвіду, здається, що ваш код працював би лише в певних часових поясах - але я запитую, бо, можливо, є щось, чого я не знаю про те, як Javascript представляє дати біля епохи Unix.
Кіт

1
другий рядок створить момент від початку часу (1970). Це не зробить.
кумархарш

5

Якщо ви готові використовувати іншу бібліотеку javascript, numeral.js може відформатувати секунди наступним чином (приклад - на 1000 секунд):

var string = numeral(1000).format('00:00');
// '00:16:40'

безумовно шлях. як і очікувалося.
Пьотр Кула

4

Я використовую класичну функцію форматування в таких випадках:

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

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

Це злом, тому що час розгляду трактується як стандартна дата, момент ранньої дати, але це не має значення для нашої мети, і вам не потрібен плагін


4

Якщо потрібно відобразити всі години (більше 24) і якщо "0" перед годинами не потрібне, то форматування можна виконати з коротким рядком коду:

Math.floor(duration.as('h')) + moment.utc(duration.as('ms')).format(':mm:ss')

4

Спираючись на відповідь ні-ко-о-рода :

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

Я не думаю, що це дуже читабельно. Яку проблему ви хочете вирішити тут? Який твій куфар?
ni-ko-o-kin

Я знову оновив свою відповідь, щоб розібратися не один день. Це добре працює для мого використання.
ni-ko-o-kin

2
Проблема полягає в тому, що у більшості випадків ваше рішення не є ідеальним, оскільки містить занадто багато провідних нулів. Хто хоче повернути "00: 00: 00: 00: 01"? Моє рішення "масштабоване" і додає стільки ж провідних нулів, скільки потрібно.
shaedrich

Працює чудово. Дуже простий вихід. Якщо днів не буде, нулі не відображатимуться і т. Д.
Хасан Сефа Озалп

3

Відформатувати тривалість моменту в рядок

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

3

якщо ви використовуєте кутовий, додайте це до своїх фільтрів:

.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 ': '')
    }
})

приклад використання

<div> {{diff | durationFormat}} </div>

Справді дуже приємно. Я шукав такого "гарного формату", як цей. Дякую!
riketscience

3

Моє рішення, яке не передбачає жодної іншої бібліотеки, і воно працює з різницею> 24 години

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

1

Як щодо рідного 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;
}

1

Використовуйте формат тривалості моменту .

Клієнтська система (наприклад: React)

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

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

Сервер (node.js)

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

momentDurationFormatSetup(moment);

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

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}`);

Друкує:

2 дні 14 год. 00 хв. 00 с


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

0

Ви можете використовувати numeral.js для форматування тривалості:

numeral(your_duration.asSeconds()).format('00:00:00') // result: hh:mm:ss

0

Це можна використовувати для отримання перших двох символів як години, а останніх двох - як хвилин. Ця ж логіка може бути застосована і до секунд.

/**
     * 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>


Якщо ви вставите код як фрагмент, ви зможете протестувати метод і показати деякий вихід на консоль.
DJDaveMark

Звісна річ! Щойно оновлений фрагмент для швидких тестів.
Хосе Луїс Раффаллі

0

moment.duration(x).format()застаріло. Ви можете використовувати moment.utc(4366589).format("HH:mm:ss")для отримання потрібної відповіді.

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>


0

Як правильно використовувати тривалість 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 не працює як слід.

SolutionРешение полягає в перетворенні секунд в мілісекунди і використанні часу UTC.

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

Гаразд, ми отримуємо 8:00 ранку зараз. Якщо ви хочете 8 ранку замість 8:00 за цілий час, нам потрібно зробити RegExp

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

0

Мені це потрібно було зробити для роботи як вимоги відображення годин у такому форматі. Спочатку я спробував це.

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

Однак все, що перевищує 24 години, а години скидаються до 0. Але хвилини та секунди були точними. Тому я використав лише ту частину хвилин і секунд.

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

Тепер все, що мені потрібно, - це загальна кількість годин.

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

І щоб отримати той формат, який ми всі хочемо, ми просто склеїмо його разом.

var formatted = hours + ":" + minutesSeconds

якщо totalMillisecondsє 894600000це повернеться 249:30:00.

Сподіваюся, що це допомогло. Залиште будь-які питання в коментарях. ;)


-1

Якщо ви використовуєте Angular> 2, я зробив Трубу, натхненну відповіддю @ 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 : "");
  }
}

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.