Неделя года

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

ISO-неделя как основа модели

В Luxon неделя определяется по правилам ISO:

  • неделя начинается с понедельника;
  • неделя заканчивается в воскресенье;
  • первая неделя года — та, в которой присутствует 4 января;
  • год недели (weekYear) может отличаться от календарного года.

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

Ключевые свойства:

  • weekNumber — номер недели (1–52/53)
  • weekYear — год, к которому принадлежит неделя
  • weekday — день недели (1 = понедельник, 7 = воскресенье)

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

В Luxon работа с неделями осуществляется через объект DateTime.

import { DateTime } from "luxon";

const dt = DateTime.local(2026, 1, 2);

dt.weekNumber;
dt.weekYear;
dt.weekday;

Значения:

  • weekNumber возвращает номер недели в диапазоне 1–53
  • weekYear возвращает ISO-год недели
  • weekday фиксирует позицию дня внутри недели

Важно, что weekYear может отличаться от year.

const dt = DateTime.local(2026, 1, 1);

dt.year;      // 2026
dt.weekYear;  // может быть 2025

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

Граница года и смещение недель

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

const a = DateTime.local(2025, 12, 29);
const b = DateTime.local(2026, 1, 2);

a.weekYear;
a.weekNumber;

b.weekYear;
b.weekNumber;

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

Начало и конец недели

Luxon позволяет получать границы недели через методы навигации по времени.

const dt = DateTime.local(2026, 5, 23);

const start = dt.startOf("week");
const end = dt.endOf("week");

Результат:

  • startOf("week") возвращает понедельник текущей недели
  • endOf("week") возвращает воскресенье с точностью до конца дня

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

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

Luxon поддерживает форматирование ISO-недель через токены toFormat.

Основные спецификаторы:

  • W — номер недели без ведущего нуля
  • WW — номер недели с ведущим нулём
  • kkkk — ISO-год недели
const dt = DateTime.local(2026, 1, 2);

dt.toFormat("WW");     // "01"
dt.toFormat("W");      // "1"
dt.toFormat("kkkk");   // 2025 или 2026 в зависимости от границы

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

dt.toFormat("kkkk-'W'WW"); // например: "2026-W01"

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

Локаль и влияние на недели

Хотя Luxon опирается на ISO-недели, локаль может влиять на отображение других аспектов календаря, но не изменяет базовую структуру ISO-нумерации.

DateTime.local().setLocale("en");
DateTime.local().setLocale("fr");

Изменение локали влияет на форматирование месяцев и дней, но не изменяет:

  • порядок недель
  • начало недели (в ISO всегда понедельник)
  • алгоритм вычисления weekNumber

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

Luxon предоставляет глобальные настройки через Settings, позволяя адаптировать поведение календаря.

import { Settings } from "luxon";

Settings.defaultWeekSettings = {
  firstDay: 1,
  minimalDays: 4,
  weekend: 6
};

Параметры:

  • firstDay — день начала недели (1 = понедельник)
  • minimalDays — минимальное количество дней для первой недели года
  • weekend — граница выходных дней

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

Сравнение недель между датами

Недели удобно использовать для группировки временных данных.

const d1 = DateTime.local(2026, 5, 1);
const d2 = DateTime.local(2026, 5, 23);

d1.weekNumber === d2.weekNumber;

Однако сравнение только weekNumber без weekYear некорректно, поскольку номер недели повторяется каждый год.

Корректная проверка:

d1.weekNumber === d2.weekNumber && d1.weekYear === d2.weekYear;

Переходы между неделями

Luxon позволяет легко перемещаться по неделям с помощью арифметики времени:

const dt = DateTime.local(2026, 5, 23);

const nextWeek = dt.plus({ weeks: 1 });
const prevWeek = dt.minus({ weeks: 1 });

При этом автоматически пересчитываются:

  • weekNumber
  • weekYear
  • weekday

Использование недель в датированных системах

Модель недели года часто применяется в:

  • финансовых отчётах (weekly closing)
  • логистике (планирование маршрутов)
  • аналитике (когортный анализ)
  • управлении задачами (спринты)

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

Граничные случаи и особенности поведения

Некоторые даты могут вести себя неинтуитивно при первом знакомстве с ISO-нумерацией:

  • 1 января может относиться к последней неделе предыдущего года
  • 31 декабря может входить в первую неделю следующего года
  • год недели и календарный год могут не совпадать

Это не ошибка, а следствие строгого определения недель как непрерывной последовательности блоков по 7 дней с фиксированными правилами старта года.