Получение значений длительности

В Moment.js работа с длительностями реализована через объект Duration, создаваемый с помощью moment.duration(). Длительность представляет собой промежуток времени, не привязанный к конкретной дате или времени, и позволяет извлекать значения в различных единицах измерения.

Ключевая особенность работы с длительностями заключается в том, что одни и те же данные могут быть представлены в разных масштабах: от миллисекунд до лет, при этом часть единиц является условной (например, месяцы и годы зависят от контекста календаря).


Создание объекта длительности

Получение значений длительности начинается с её создания:

const duration = moment.duration(5000); // 5000 миллисекунд

Также поддерживаются альтернативные формы:

moment.duration(2, 'hours');
moment.duration({ hours: 2, minutes: 30 });
moment.duration('PT2H30M'); // ISO 8601

После создания объекта становится доступен набор методов для извлечения значений в нужных единицах.


Извлечение значений в фиксированных единицах

Moment.js предоставляет методы, возвращающие количество целых единиц времени, содержащихся в длительности.

Миллисекунды, секунды, минуты

const duration = moment.duration(125000); // 125000 ms

duration.milliseconds(); // 125000
duration.seconds();      // 125
duration.minutes();      // 2

Каждый метод возвращает значение без остатка в рамках собственной единицы измерения. При этом важно учитывать, что методы не пересчитывают длительность полностью, а извлекают компонент.

Пример:

const duration = moment.duration(90, 'seconds');

duration.seconds(); // 30
duration.minutes(); // 1

Здесь 90 секунд разбиваются на 1 минуту и 30 секунд, но каждый метод возвращает только «свою» часть.


Работа с часами и более крупными единицами

const duration = moment.duration(3700, 'seconds');

duration.seconds(); // 40
duration.minutes(); // 1
duration.hours();   // 1

Поведение аналогично: каждый метод возвращает остаток в пределах своей единицы, не учитывая «перенос» в более крупные значения.

Для получения общего количества часов используется другой подход.


Полное количество единиц: as()

Метод as() возвращает общую длительность, выраженную в заданной единице измерения.

const duration = moment.duration(3, 'hours');

duration.as('minutes'); // 180
duration.as('seconds'); // 10800

В отличие от методов .hours() или .minutes(), здесь выполняется полное преобразование всей длительности без остаточного деления.

Типичные варианты использования:

duration.as('milliseconds');
duration.as('seconds');
duration.as('minutes');
duration.as('hours');
duration.as('days');
duration.as('weeks');
duration.as('years');

Получение составных частей длительности

Метод get() позволяет извлекать значения по ключу, аналогично объектной модели.

const duration = moment.duration(2, 'days');

duration.get('days');      // 2
duration.get('hours');     // 0
duration.get('milliseconds'); // 0

Допустимые ключи включают:

  • years
  • months
  • weeks
  • days
  • hours
  • minutes
  • seconds
  • milliseconds

Особенность заключается в том, что get() возвращает внутренние компоненты хранения, а не пересчитанное значение.


Нормализация и остаточные значения

Moment.js хранит длительность в виде набора значений по единицам, не выполняя автоматической нормализации в единую шкалу.

const duration = moment.duration({
  hours: 1,
  minutes: 120
});
duration.hours();   // 1
duration.minutes(); // 0
duration.asHours(); // 3

Здесь видно различие между компонентным и агрегированным представлением.


Получение объекта представления длительности

Метод toObject() возвращает структурированное представление всех единиц времени:

const duration = moment.duration({
  days: 2,
  hours: 5,
  minutes: 10
});

duration.toObject();

Результат:

{
  years: 0,
  months: 0,
  weeks: 0,
  days: 2,
  hours: 5,
  minutes: 10,
  seconds: 0,
  milliseconds: 0
}

Это представление удобно для сериализации или дальнейшей обработки.


Особенности работы с месяцами и годами

Месяцы и годы в Moment.js считаются условными единицами, так как их продолжительность зависит от календаря.

const duration = moment.duration(1, 'year');

duration.asDays(); // примерно 365

Однако точное значение может варьироваться:

  • 1 год ≈ 365 или 366 дней
  • 1 месяц ≈ 28–31 день

Поэтому методы .months() и .years() работают как компонентные значения, а .as() — как приблизительное преобразование.


Преобразование длительности в миллисекунды

Базовая единица хранения в Moment.js — миллисекунды. Метод valueOf() возвращает числовое представление длительности:

const duration = moment.duration(1500, 'milliseconds');

duration.valueOf(); // 1500

Этот метод используется при арифметических операциях:

const total = +moment.duration(2, 'seconds');

Результатом будет число миллисекунд.


Разница между компонентными и агрегированными значениями

Для понимания извлечения значений важно различать два подхода:

Компонентные методы

  • duration.hours()
  • duration.minutes()
  • duration.seconds()

Возвращают остаток внутри единицы.

Агрегированные методы

  • duration.asHours()
  • duration.asMinutes()
  • duration.asSeconds()

Возвращают полное значение всей длительности.


Пример комбинированного извлечения значений

const duration = moment.duration(1, 'hours')
  .add(45, 'minutes')
  .add(30, 'seconds');
duration.hours();   // 1
duration.minutes(); // 45
duration.seconds(); // 30

duration.asMinutes(); // 105.5

Компонентные методы отражают структуру, агрегированные — общую величину.


Использование ISO 8601 и получение значений

При создании длительности из строки ISO 8601:

const duration = moment.duration('P2DT3H4M');

Доступ к значениям осуществляется аналогично:

duration.days();   // 2
duration.hours();  // 3
duration.minutes(); // 4

И агрегированное значение:

duration.asHours(); // 51

Ограничения точности

При извлечении значений следует учитывать:

  • дробные значения могут округляться при компонентном доступе
  • месяцы и годы являются приближёнными
  • накопление значений может давать неожиданные остатки при смешанных единицах
const duration = moment.duration(1.5, 'hours');

duration.hours();   // 1
duration.minutes(); // 30

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


Поведение при отрицательных значениях

Длительности могут быть отрицательными:

const duration = moment.duration(-90, 'seconds');
duration.seconds(); // 30
duration.asSeconds(); // -90

Компонентные методы могут возвращать положительные остатки, тогда как агрегированные сохраняют знак.


Взаимодействие с округлением

При преобразовании длительности в различные единицы применяется математическое деление:

const duration = moment.duration(2000, 'seconds');

duration.asMinutes(); // 33.333...

Округление не выполняется автоматически, результат сохраняет точность с плавающей точкой.


Итоговая модель получения значений

Система извлечения значений длительности в Moment.js строится на двух принципах:

  • хранение данных в базовой единице (миллисекундах)
  • предоставление интерфейсов для компонентного и агрегированного доступа

Это позволяет использовать длительности как для точных вычислений, так и для представления человекочитаемых временных интервалов без дополнительной конвертации.