Добавление времени

В библиотеке Moment.js работа с добавлением времени строится вокруг метода add(), который позволяет изменять объект момента, увеличивая его на заданный интервал. Особенность подхода заключается в мутабельности: каждый вызов add() изменяет исходный объект, а не создаёт новый, что важно учитывать при построении цепочек вычислений.

Метод add() принимает два основных параметра: числовое значение и единицу измерения времени.

moment().add(Number, String);

Простейшие примеры:

moment().add(5, 'days');      // +5 дней
moment().add(2, 'hours');     // +2 часа
moment().add(30, 'minutes');  // +30 минут

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

  • years / y
  • months / M
  • weeks / w
  • days / d
  • hours / h
  • minutes / m
  • seconds / s
  • milliseconds / ms

Использование сокращений повышает компактность кода, но снижает его читаемость, что критично в крупных проектах.

Добавление нескольких интервалов

Метод add() допускает последовательное применение для различных единиц времени:

moment()
  .add(1, 'year')
  .add(2, 'months')
  .add(10, 'days');

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

Альтернативный подход — передача объекта с несколькими единицами:

moment().add({
  years: 1,
  months: 2,
  days: 10
});

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

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

Добавление месяцев и лет имеет нелинейное поведение из-за разной длины календарных периодов. Например:

moment('2024-01-31').add(1, 'month');

Результат зависит от контекста календаря: февраль не имеет 31 дня, поэтому библиотека автоматически корректирует дату, обычно устанавливая последний день месяца.

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

Работа с неделями и переходами через границы месяца

Добавление недель:

moment().add(3, 'weeks');

эквивалентно добавлению 21 дня, однако логически воспринимается как более семантическая операция.

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

moment('2024-12-20').add(20, 'days');

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

Использование объекта duration для сложных сценариев

Хотя add() напрямую работает с числами, в сложных сценариях часто используется объект длительности:

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

moment().add(duration);

Такой подход удобен при динамическом формировании интервалов, особенно когда данные приходят из API или пользовательского ввода.

Цепочки вызовов и мутабельность

Каждый вызов add() изменяет исходный объект:

const m = moment();

m.add(2, 'days');
console.log(m.format());

Это поведение может приводить к неожиданным результатам при повторном использовании переменной:

const base = moment();

const a = base.add(1, 'day');
const b = base.add(1, 'day'); // уже изменённый объект

Оба a и b будут ссылаться на один и тот же изменённый момент. Для предотвращения таких ситуаций используется клонирование:

const base = moment();

const a = base.clone().add(1, 'day');
const b = base.clone().add(2, 'days');

Добавление времени в строгом режиме парсинга

При использовании строгих форматов и ограничений парсинга добавление времени может влиять на валидность результата:

moment('2024-02-28', 'YYYY-MM-DD', true).add(1, 'day');

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

Особенности работы с переходом времени (DST)

В системах с переходом на летнее и зимнее время добавление часов может давать неожиданные результаты:

moment('2024-03-31 01:00').add(1, 'hour');

В зависимости от часового пояса итоговое значение может смещаться не на ровно один час, а перескакивать через несуществующий промежуток времени.

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

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

Для высокочастотных операций используется единица milliseconds:

moment().add(500, 'milliseconds');

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

Сочетание add() с форматированием

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

moment()
  .add(7, 'days')
  .format('YYYY-MM-DD HH:mm:ss');

Форматирование применяется уже после вычисления новой даты, не влияя на сам объект.

Работа с отрицательными значениями

Метод add() допускает отрицательные значения, фактически превращаясь в уменьшение времени:

moment().add(-3, 'days');

Это поведение эквивалентно subtract(), однако использование отрицательных значений снижает читаемость кода и может вызывать неоднозначность при поддержке.

Добавление времени в контексте бизнес-логики

В прикладных системах добавление времени используется для расчёта сроков выполнения задач, дедлайнов и периодов активности:

const deadline = moment().add(14, 'days');
const reminder = moment().add(1, 'hours');
const subscriptionEnd = moment().add(1, 'year');

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

Взаимодействие add() с другими методами

Метод add() часто используется совместно с startOf() и endOf() для нормализации дат:

moment()
  .startOf('day')
  .add(12, 'hours');

Такой подход позволяет фиксировать базовую точку отсчёта перед внесением изменений.

Также возможна комбинация с set():

moment()
  .set('year', 2025)
  .add(2, 'months');

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