Как я могу использовать format () для момента moment.js?

211

Есть ли способ, которым я могу использовать format метод moment.js на объектах длительности? Я не могу найти его где-нибудь в документах, и он не считается атрибутом объектов продолжительности.

Я хотел бы иметь возможность сделать что-то вроде:

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

Кроме того, если есть какие-либо другие библиотеки, которые могут легко приспособить такую ​​функциональность, я был бы заинтересован в рекомендациях.

Спасибо!

mvanveen
источник
5
moment.utc (duration.asMilliseconds ()) Формат ( 'чч: мм: сс . '); - Продолжительность - это вектор. Поставив хвост на начало координат, вы можете использовать форматирование даты, чтобы получить чч: мм: сс.
Пол Уильямс
moment.utc (moment.duration (23, 'секунд'). asMilliseconds ()). format ('hh: mm: ss') => "12:00:23" не работает так хорошо
goldenratio
Ах, я нашел проблему, HH:mm:ssприведу 00:00:23в моем предыдущем примере. так что просто неправильный корпус в части часов
goldenratio

Ответы:

55

Мы собираемся добавить какое-то форматирование к длительностям в moment.js. См. Https://github.com/timrwood/moment/issues/463.

Несколько других библиотек, которые могут помочь: http://countdownjs.org/ и https://github.com/icambron/twix.js

timrwood
источник
4
Я тоже с нетерпением жду форматирования продолжительности. Взгляните сейчас на countdownjs, но twix, кажется, выполняет только «умное» форматирование, а не особую настройку.
mpen
2
Хотя twix усердно работает над интеллектуальным форматированием, у него есть много вариантов форматирования, вплоть до задействованных токенов: github.com/icambron/twix.js/wiki/Formatting . Отказ от ответственности: я автор твикса.
3
Countdown.js превосходен, и автор очень полезен (он только выпустил 2 версии в один и тот же день из-за некоторых моих предложений)!
Охад Шнайдер
5
Я отказался от голосования, потому что проблема github, связанная в этом ответе, - это нескончаемый поток мнений, желаний и напыщенных рассуждений, которые
никуда
29
Почему он не может быть идентичен другому .format, используемому в других местах библиотеки? Это безумие. 5 лет и это еще не сделано? действительно?!
Кристополус
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 квадриллионов миллисекунд в виде мм: сс
Пьер-Люк Жандро
28
это не работает последние 24 часа (то есть, если я хотел показать 117 часов). в противном случае отличное решение!
Фил
1
@Phil, вы можете использовать "D" или "DD", если вы хотите показать дни.
Vinay
71

преобразовать длительность в мс, а затем в момент:

moment.utc(duration.as('milliseconds')).format('HH:mm:ss')
Сагив Офек
источник
14
Так что это не работает, если ваша продолжительность больше 24 часов .. 24
часа
4
@ S.Robijns полезным наблюдение , но только чтобы подчеркнуть для других - это является ожидаемым поведением .format('HH:mm:ss'). Смотрите документы
Давник
1
это лучший ответ!
Волшебник
44

Используйте этот плагин Moment Duration Format .

Пример:

moment.duration(123, "minutes").format("h:mm");
kayz1
источник
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")
NFpeter
источник
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 может показать, как это решение было достигнуто.
coffekid
2
Бесполезный. Как и большинство других ответов на этот вопрос, возвращается неполное количество часов в продолжительности, а не общее количество часов. Например, возвращается 12:00 для продолжительности moment.duration ({дней: 2, часов: 12})
Нейтрино
1
moment.duration (diff) .asMilliseconds () является чрезмерным. Вы можете просто использовать diff, это уже в миллисекундах.
Кристополус
12

Лучший сценарий для моего конкретного случая использования был:

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

Это улучшает ответ @ Wilson, поскольку он не имеет доступа к частному внутреннему свойству _data.

TaeKwonJoe
источник
Спасибо @TaeKwonJoe
Kamlesh
11

Вам не нужно .формат. Используйте длительности как это:

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

Я нашел это решение здесь: https://github.com/moment/moment/issues/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
Это не будет включать начальные нули, если duration.seconds () меньше 10, хотя ...
carpiediem
Что будет, если у вас будет больше секунд, чем час? Это нормально, что у тебя тогда больше 60 секунд?
Шедрих
Ведущие нули работают, но duration = moment.duration(7200, 'seconds'); withPadding(duration);скажут «00:00».
Шедрих
@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» в вар ул.

Wilson
источник
Большой! Это просто работает ... как,
черт возьми,
4
Избегайте этого решения, _dataявляется внутренним свойством и может изменяться без предупреждения.
Друска
1
К сожалению, он не будет работать всегда, как ожидалось: moment(moment.duration(1200000)._data).format('hh:mm:ss')вернется 12:20 вместо 00:20
Анна Р
2
@AnnaR hнаходится в диапазоне 1-12, так что это вполне ожидаемо. Используйте Hвместо документов - часовые жетоны
Барбсан
Это неправильно не только потому, что вы игнорируете ДНИ, поэтому 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) регистрируется как 12:00 в каждом часовом поясе?
Кит
Я просто спрашиваю, работает ли код в вашем ответе или нет, потому что я скептически отношусь. Я написал много кода, который работает с датами, на многих языках программирования. Исходя из моего опыта, кажется, что ваш код будет работать только в определенных часовых поясах - но я спрашиваю, потому что, возможно, есть кое-что, чего я не знаю о том, как Javascript представляет даты рядом с эпохой Unix.
Кейт
1
вторая строка создаст момент с начала времени (1970). Это не будет делать.
kumarharsh
5

Если вы хотите использовать другую библиотеку JavaScript, цифра.js может отформатировать секунды следующим образом (пример для 1000 секунд):

var string = numeral(1000).format('00:00');
// '00:16:40'
GChorn
источник
безусловно, путь. как и ожидалось.
Петр Кула
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')
OV
источник
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
shaedrich
источник
Я не думаю, что это очень читабельно. Какую проблему вы хотите решить здесь? Какой у вас вариант использования?
Ни-Ко-О-Кин
Я обновил свой ответ снова, чтобы иметь дело больше чем с одним днем. Это прекрасно работает для моего случая использования.
Ни-Ко-О-Кин
2
Проблема в том, что в большинстве случаев ваше решение не является идеальным, поскольку оно содержит слишком много начальных нулей. Кто хочет вернуть "00: 00: 00: 00: 01"? Мое решение является «масштабируемым» и добавляет столько начальных нулей, сколько необходимо.
Шедрих
Работает отлично. Очень простой вывод. Если дней нет, не будет нулей для отображаемых дней и т. Д.
Хасан Сефа Озальп
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");
}
Dineshkani
источник
3

если вы используете angular, добавьте это в ваши фильтры:

.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

Мое решение, которое не требует какой-либо другой библиотеки и работает с 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))
Лоренцо Тассоне
источник
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');
AryanJ-Нью-Йорк
источник
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 с

davidhq
источник
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

Вы можете использовать цифру.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>

kindacoder
источник
0

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

Сначала нужно импортировать momentи moment-duration-format.

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

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

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

,Ну, у вас нет ошибки типа выше. GetВы получаете правильное значение 8:00 утра? Нет ..., значение, которое вы получаете 8:00. Формат Moment.js не работает, как положено.

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

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

Хорошо, сейчас 8:00. Если вы хотите 8 часов утра вместо 8 часов утра для интегрального времени, нам нужно сделать 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, я создал Pipe, вдохновленный ответом @ 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
источник
-3

Это работает для меня:

moment({minutes: 150}).format('HH:mm') // 01:30
Натан Аугусто
источник
Возврат "Неверная дата"
themadmax
3
150 минут это не 1 час 30 минут.
Марк Браун