Как использовать moment.js для получения оставшихся часов, минут и секунд из временной метки unix?

Учитывая метку времени unix в будущем, как я могу использовать Moment.js, чтобы получить часы, минуты и секунды, оставшиеся до этого?

Например:

now  = 1589252712837
time = 1589356202907

// This is the line I do not know
res = moment(time - now)

console.log(res)
// 23 hours, 12 minutes, 3 seconds

Редактировать:

Я считаю, что могу сделать что-то подобное, но есть ли собственный способ сделать это?:

now  = 1589252712837
time = 1589356202907
remaining = time - now

hour = moment(remaining).hour()
minute = moment(remaining).minute()
second = moment(remaining).second()

console.log(`${hour} hours, `${minute} minutes, ${seconds} seconds`)
// 23 hours, 12 minutes, 3 seconds

person ReactHelp    schedule 12.05.2020    source источник
comment
формат('ЧЧ:мм:сс')   -  person user120242    schedule 12.05.2020
comment
И есть ли удобочитаемый или 23 часа, 12 минут, 3 секунды способ сделать это?   -  person ReactHelp    schedule 12.05.2020
comment
ну, есть стиль Twitter Humanize(), также есть moment.duration(), который может обернуть оставшееся значение   -  person user120242    schedule 12.05.2020
comment
хакерский способ сделать это, извлекая из _data: Object.entries(moment.duration(remaining,'milliseconds')._data).reverse().map(([unit,value])=>value!==0?`${value} ${unit}`:'').join(' ')   -  person user120242    schedule 12.05.2020
comment
обратите внимание, что время в ваших примерах указано неправильно, вам нужно использовать moment.utc, если вы хотите использовать другие методы, которые не преобразуются в продолжительность. сделайте оставшееся/1000/3600, чтобы увидеть, что на самом деле это 28 часов. Вы можете посмотреть на github.com/jsmreese/moment-duration-format.   -  person user120242    schedule 12.05.2020


Ответы (1)


Обратите внимание, что код примера, который у вас есть, смещается по времени: remaining/1000/60/60~=28, а не 23. Вам нужно использовать moment.utc. Я не рекомендую этого делать, потому что вы столкнетесь с другими проблемами, такими как работа с днями и месяцами.

Что касается «родной» поддержки, см. подробное обсуждение здесь: https://github.com/moment/moment/issues/463
TL;DR: обсуждается с 2012 года по настоящее время. И в документах они указывают на плагин moment-duration-format. Посмотрите на этот плагин, если вам нужна поддержка, близкая к «родной»:
https://github.com/jsmreese/moment-duration-format

Честно говоря, посмотрев на ситуацию, я бы, наверное, просто использовал moment-duration-format или просто используйте humanize(). Может быть, свернуть мой собственный аналог того, как генерируется duration._data + Intl.NumberFormat, что я и предполагаю format-duration-format в основном уже работает.

Я собираюсь перечислить некоторые возможные методы, насколько я вижу:

now  = 1589252712837
time = 1589356202907
remaining = time - now

// extract key(units),value from parsed ._data property of duration
// no additional dependencies but depends on internal private variable _data
console.log(
Object.entries(moment.duration(remaining,'milliseconds')._data).reverse()
  .flatMap(([unit,value])=>value!==0?`${value} ${unit}`:[]).join(' ')
);

// using moment-duration-format plugin
console.log(moment.duration(remaining,'milliseconds').format('h [hours] m [minutes] s [seconds]'))

// twitter style humanize
console.log(moment.duration(remaining,'milliseconds').humanize());

// hours threshhold is Infinity; never round up to higher units than hours
console.log(moment.duration(remaining,'milliseconds').humanize({h:Infinity}));
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.25.3/moment.min.js"></script>

<!-- moment-duration-format plugin -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-duration-format/2.3.1/moment-duration-format.min.js"></script>

person user120242    schedule 12.05.2020
comment
Передайте параметр {trim: false} в .format('date format string', {trim: false}), чтобы он не обрезал 0 значений (например: если часы были равны 0, он попытался бы обрезать часть часов) - person user120242; 28.05.2020