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

День года — это порядковый номер календарного дня в пределах одного года, начиная с 1 января как первого дня. Значение находится в диапазоне от 1 до 365 для обычного года и от 1 до 366 для високосного.

В задачах обработки дат это значение используется для:

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

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


Получение дня года в Moment.js

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

const moment = require('moment');

const date = moment('2026-05-21');
const day = date.dayOfYear();

console.log(day);

В данном примере переменная day будет содержать номер дня года для 21 мая 2026 года.

Метод работает на основе внутреннего календарного представления Moment.js и учитывает:

  • длину месяцев;
  • високосные годы;
  • корректное смещение начала года.

Метод dayOfYear()

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

Получение значения

const m = moment('2026-10-05');
console.log(m.dayOfYear());

Результат — число, соответствующее порядковому дню года.

Установка значения

const m = moment('2026-01-01');
m.dayOfYear(200);

console.log(m.format('YYYY-MM-DD'));

После выполнения кода дата будет изменена таким образом, чтобы соответствовать 200-му дню текущего года.


Внутренняя логика расчёта

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

Упрощённая логика выглядит следующим образом:

  1. Определяется начало года:

    moment().startOf('year')
  2. Вычисляется разница в днях между текущей датой и началом года.

  3. К результату добавляется 1, так как отсчёт начинается с единицы.


Примеры использования

Пример 1: вычисление прогресса года

const m = moment();

const progress = (m.dayOfYear() / (m.isLeapYear() ? 366 : 365)) * 100;

console.log(progress.toFixed(2) + '%');

Здесь день года используется для определения того, какая часть года уже прошла.


Пример 2: сравнение дат по порядковому номеру

const a = moment('2026-03-10');
const b = moment('2026-07-15');

if (a.dayOfYear() < b.dayOfYear()) {
    console.log('Первая дата раньше в пределах года');
}

Такое сравнение удобно, когда год одинаковый и важен только порядок дней.


Пример 3: генерация диапазона дней года

const start = moment().dayOfYear(1);
const end = moment().dayOfYear(365);

while (start <= end) {
    console.log(start.dayOfYear(), start.format('YYYY-MM-DD'));
    start.add(1, 'day');
}

Цикл проходит по всем дням года, начиная с первого и заканчивая последним.


Изменение дня года

Установка значения через dayOfYear() приводит к автоматической корректировке даты.

const m = moment('2026-06-01');

m.dayOfYear(1);

console.log(m.format('YYYY-MM-DD'));

Результатом будет переход к 1 января текущего года.

Если задать значение больше допустимого диапазона, Moment.js автоматически перенесёт дату в следующий год.

const m = moment('2026-01-01');

m.dayOfYear(400);

console.log(m.format('YYYY-MM-DD'));

Значение 400 выйдет за пределы года и приведёт к смещению в следующий календарный цикл.


Влияние високосного года

Високосный год увеличивает количество дней до 366, что напрямую влияет на результаты метода dayOfYear().

const leap = moment('2024-12-31');
console.log(leap.dayOfYear());

В 2024 году последний день года будет иметь значение 366.

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

moment().isLeapYear();

Он возвращает булево значение, которое используется для корректных расчётов диапазона.


Использование в календарной аналитике

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

Нормализация дат

const dates = [
    moment('2026-01-10'),
    moment('2026-03-15'),
    moment('2026-12-01')
];

const normalized = dates.map(d => d.dayOfYear());
console.log(normalized);

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


Группировка по дням года

const events = [
    { date: moment('2026-02-01'), value: 10 },
    { date: moment('2026-02-01'), value: 15 },
    { date: moment('2026-02-02'), value: 5 }
];

const grouped = {};

events.forEach(e => {
    const key = e.date.dayOfYear();
    grouped[key] = (grouped[key] || 0) + e.value;
});

console.log(grouped);

Здесь день года используется как ключ для агрегации данных.


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

Метод dayOfYear() в Moment.js имеет ряд особенностей:

  • отсчёт начинается с 1, а не с 0;
  • учитывается локальная временная зона объекта Moment;
  • изменения через dayOfYear() влияют на исходный объект;
  • при выходе за пределы года происходит автоматическая нормализация даты.

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

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

const m = moment('2026-01-01T23:30:00');
console.log(m.dayOfYear());

При смещении времени относительно UTC значение дня года может отличаться в зависимости от часового пояса.


Сочетание с другими методами Moment.js

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

startOf / endOf

const m = moment().dayOfYear(150);

console.log(m.startOf('day').format());
console.log(m.endOf('day').format());

format

const m = moment();

console.log(`${m.dayOfYear()} день: ${m.format('YYYY-MM-DD')}`);

diff

const a = moment().dayOfYear(50);
const b = moment().dayOfYear(100);

console.log(b.diff(a, 'days'));

Практическое значение в вычислениях

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

  • исключается необходимость учитывать месяцы;
  • упрощается логика циклов по датам;
  • ускоряется агрегация временных данных;
  • снижается вероятность ошибок при ручных расчётах календаря.

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