Получение года

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

Основной способ извлечения года реализуется через метод year() без аргументов. Он возвращает календарный год в локальном часовом поясе, соответствующий внутреннему состоянию объекта момента.

const m = moment('2024-07-18');
const y = m.year(); // 2024

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

Альтернативный способ получения значения реализован через универсальный метод get:

moment('2024-07-18').get('year'); // 2024

get('year') является частью общего интерфейса доступа к полям даты и используется реже, так как year() обеспечивает более прямой и читаемый синтаксис.

Форматирование года

Для вывода года в строковом представлении используется метод format, принимающий токен YYYY.

moment('2024-07-18').format('YYYY'); // "2024"

Форматирование не изменяет внутреннее состояние объекта и применяется исключительно для представления данных. Токен YYYY возвращает четырёхзначный календарный год с ведущими нулями при необходимости.

Существует также альтернативный токен YY, возвращающий последние две цифры года:

moment('2024-07-18').format('YY'); // "24"

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

Установка года

Изменение года выполняется тем же методом year, но с передачей аргумента:

const m = moment('2024-07-18');
m.year(2026);
m.format(); // 2026-07-18T00:00:00

При установке года сохраняются месяц и день, если они валидны в новом контексте. В случае несуществующих дат происходит автоматическая нормализация:

moment('2024-02-29').year(2025);
// результат: 2025-03-01

Такое поведение связано с тем, что 2025 год не является високосным, и 29 февраля не существует.

ISO-недели и ISO-год

Отдельная система представления года используется в стандарте ISO 8601, где год определяется не календарной датой, а неделями. Для этого применяется метод isoWeekYear().

moment('2020-01-01').isoWeekYear(); // 2020 или 2019 (в зависимости от недели)

ISO-год может отличаться от календарного, поскольку первая неделя года определяется как неделя, содержащая первый четверг января.

Пример различий:

moment('2019-12-31').year();        // 2019
moment('2019-12-31').isoWeekYear(); // 2020

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

Разница между календарным и ISO годом

Календарный год определяется фиксированно — с 1 января по 31 декабря. ISO-год зависит от структуры недель и может начинаться в конце предыдущего календарного года.

Основные различия:

  • календарный год: фиксированная граница 1 января
  • ISO-год: зависит от первой недели с четвергом
  • возможен сдвиг на ±1 год в начале и конце декабря/января
const d = moment('2021-01-01');

d.year();        // 2021
d.isoWeekYear(); // 2020

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

Получение года через форматные шаблоны ISO

Для ISO-формата используется комбинация GGGG:

moment('2020-01-01').format('GGGG'); // "2020"

Токены ISO:

  • GGGG — ISO-год
  • WW — номер недели
  • GG — двухзначный ISO-год

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

Особенности работы с временными зонами

Год вычисляется на основе локального времени экземпляра. При изменении часового пояса через плагины Moment Timezone значение года может изменяться, если дата находится близко к границе года.

moment.tz('2024-12-31 23:30', 'America/New_York').year();

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

Преобразование и цепочки вызовов

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

moment()
  .add(2, 'years')
  .subtract(3, 'months')
  .year();

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

Проверка и сравнение года

Год может использоваться для фильтрации и сравнения дат:

const targetYear = 2024;

const isMatch = moment('2024-05-10').year() === targetYear;

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

const start = moment().year(2024).startOf('year');
const end = moment().year(2024).endOf('year');

Год в контексте startOf и endOf

Методы startOf('year') и endOf('year') позволяют получать границы года:

moment('2024-07-18').startOf('year'); // 2024-01-01 00:00:00
moment('2024-07-18').endOf('year');   // 2024-12-31 23:59:59

Эти операции полезны при построении интервалов фильтрации данных.

Нормализация значений при изменении года

При установке года Moment.js автоматически корректирует дату при некорректных комбинациях месяца и дня. Это поведение важно учитывать при массовых трансформациях дат:

moment('2020-02-29').year(2021);

Результат будет смещён в ближайшую корректную дату, поскольку февраль 29 отсутствует в 2021 году.

Влияние парсинга строк

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

moment('2024').year(); // 2024

Если строка содержит только год, остальные компоненты устанавливаются в начало года (1 января 00:00:00).

Итоговая модель работы с годом

Работа с годом в Moment.js строится на трёх базовых механизмах:

  • прямой доступ через year()
  • универсальный интерфейс get('year') и set
  • форматирование через format('YYYY')

Дополнительно выделяется ISO-модель через isoWeekYear() и соответствующие форматные токены.

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