Локализация недель

Работа с неделями в разных культурах и стандартах не является унифицированной: начало недели, правила нумерации и границы календарных периодов зависят от локали и принятой системы летоисчисления. В JavaScript-библиотеке Date-fns эти различия формализованы через набор функций и параметров локализации, позволяющих корректно обрабатывать недельные интервалы в международных приложениях.

Ключевая проблема локализации недель заключается в трёх аспектах:

  • день начала недели;
  • правило вычисления номера недели;
  • границы первой недели года.

Каждый из этих аспектов может изменяться в зависимости от региона и стандарта ISO 8601.


Локаль и недельные настройки

В Date-fns локаль представляет собой объект, содержащий не только названия месяцев и дней, но и правила календаря. Важнейшие параметры недель:

  • weekStartsOn — день, с которого начинается неделя (0 — воскресенье, 1 — понедельник и т. д.)
  • firstWeekContainsDate — день января, который должен входить в первую неделю года (используется в нестандартных системах нумерации недель)

Пример локального объекта:

import { enUS, ru } from 'date-fns/locale'

Внутри локали:

  • enUS.weekStartsOn = 0
  • ru.weekStartsOn = 1

Это определяет поведение всех функций, зависящих от недельных границ.


Начало недели и функции startOfWeek / endOfWeek

Функции startOfWeek и endOfWeek являются базовыми инструментами работы с недельными границами.

startOfWeek

Функция возвращает дату начала недели с учётом локали или параметра weekStartsOn.

import { startOfWeek } from 'date-fns'
import { ru } from 'date-fns/locale'

startOfWeek(new Date(2026, 0, 15), { locale: ru })

Логика вычисления:

  • определяется день недели текущей даты;
  • отнимается смещение до первого дня недели;
  • возвращается дата с временем 00:00:00.

endOfWeek

Функция выполняет обратную операцию:

import { endOfWeek } from 'date-fns'

endOfWeek(new Date(2026, 0, 15), { weekStartsOn: 1 })

Особенность:

  • конец недели зависит от того же правила начала недели;
  • возвращается конец дня (23:59:59.999).

ISO-неделя и стандарт ISO 8601

ISO 8601 задаёт строгие правила определения недели:

  • неделя начинается с понедельника;
  • первая неделя года содержит первый четверг года (или 4 января);
  • недели нумеруются последовательно от 1 до 52/53.

Date-fns реализует ISO-подход через специализированные функции:

getISOWeek

import { getISOWeek } from 'date-fns'

getISOWeek(new Date(2026, 0, 1))

startOfISOWeek

import { startOfISOWeek } from 'date-fns'

endOfISOWeek

import { endOfISOWeek } from 'date-fns'

Особенность ISO-недель:

  • игнорируются пользовательские локали;
  • всегда используется понедельник как старт недели;
  • стабильная нумерация между странами.

Нумерация недель: getWeek и правила локали

Функция getWeek более гибкая, чем ISO-версия, и учитывает локальные правила.

import { getWeek } from 'date-fns'
import { enUS } from 'date-fns/locale'

getWeek(new Date(2026, 0, 1), { locale: enUS })

Механизм вычисления

Номер недели зависит от:

  • weekStartsOn
  • firstWeekContainsDate

firstWeekContainsDate

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

Варианты:

  • 1 — первая неделя содержит 1 января (часто в США)
  • 4 — первая неделя содержит 4 января (ISO-подход)
  • 7 — более редкие региональные модели

Различия между ISO-неделей и локальными неделями

Параметр ISO 8601 Локальная система
Начало недели Понедельник Зависит от локали
Первая неделя года Неделя с 4 января Может начинаться с 1 января
Унификация Да Нет
Функции Date-fns getISOWeek getWeek

Работа с диапазонами недель

eachWeekOfInterval

Функция используется для генерации списка недель в интервале.

import { eachWeekOfInterval } from 'date-fns'

eachWeekOfInterval({
  start: new Date(2026, 0, 1),
  end: new Date(2026, 2, 1)
})

Поведение зависит от:

  • weekStartsOn
  • локали (если передана)
  • смещения начала интервала

Каждый элемент результата — дата начала недели.


Смещение дней недели

setDay

Функция изменяет день недели у даты с учётом локали.

import { setDay } from 'date-fns'

setDay(new Date(2026, 0, 15), 0)

Особенность:

  • 0 может означать воскресенье или понедельник в зависимости от weekStartsOn;
  • поведение меняется при передаче locale.

Форматирование недельных значений

Date-fns не содержит отдельной функции «форматирования недели», но использует:

  • format
  • токены недель

Примеры токенов:

  • I — ISO неделя года
  • w — локальная неделя года
import { format } from 'date-fns'

format(new Date(2026, 0, 15), 'w')
format(new Date(2026, 0, 15), 'I')

Различие:

  • w зависит от локали;
  • I следует ISO 8601.

Влияние локали на недельные вычисления

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

  • weekStartsOn
  • firstWeekContainsDate

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

  • в enUS неделя начинается с воскресенья;
  • в ru неделя начинается с понедельника;
  • в ISO всегда понедельник.

Это влияет на:

  • startOfWeek
  • endOfWeek
  • getWeek
  • eachWeekOfInterval
  • setDay

Границы недель в календарных вычислениях

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

Пример нормализации диапазона

  • начало недели: обнуление времени до 00:00
  • конец недели: установка 23:59:59.999

Это обеспечивает корректную работу:

  • фильтрации событий;
  • агрегации данных;
  • построения календарных сеток.

Перекрытие недель между годами

Особенность недельной системы заключается в том, что:

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

ISO-логика делает это явным:

  • неделя принадлежит году, где находится её четверг.

В локальных системах возможны:

  • разрыв нумерации;
  • неоднозначность при переходе года.

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

При смешивании ISO и локальных недель возникают расхождения:

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

Date-fns решает это разделением функций:

  • ISO-функции (жёсткий стандарт);
  • локальные функции (гибкая настройка).

Ошибки при работе с недельной локализацией

Типичные проблемы:

  • игнорирование weekStartsOn;
  • смешивание getWeek и getISOWeek;
  • отсутствие locale в параметрах;
  • неправильная интерпретация границ недели при фильтрации данных.

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