Локальные недели

В разных странах неделя начинается в разные дни. Например:

  • в большинстве европейских стран первым днём недели считается понедельник;
  • в США — воскресенье;
  • в ряде арабских стран — суббота.

Luxon поддерживает локальные настройки календаря и позволяет работать с неделями в зависимости от региональных стандартов. Это особенно важно при:

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

Для локальных недель используются:

  • localWeekday
  • localWeekNumber
  • localWeekYear

Эти значения зависят от локали объекта DateTime.


Локаль объекта DateTime

Локаль задаётся через метод setLocale().

import { DateTime } from "luxon";

const date = DateTime.now().setLocale("en-US");

console.log(date.locale);

Результат:

en-US

Пример с русской локалью:

const date = DateTime.now().setLocale("ru");

console.log(date.locale);

Отличие weekNumber от localWeekNumber

Luxon поддерживает два типа недель:

Свойство Описание
weekNumber ISO-неделя
localWeekNumber локальная неделя

ISO-стандарт всегда использует:

  • понедельник как первый день недели;
  • строгие правила расчёта первой недели года.

Локальные недели зависят от культуры и региона.


Получение номера локальной недели

const date = DateTime.local(2025, 1, 1)
    .setLocale("en-US");

console.log(date.localWeekNumber);

В США результат может отличаться от ISO-недели.

Пример для Германии:

const date = DateTime.local(2025, 1, 1)
    .setLocale("de");

console.log(date.localWeekNumber);

Сравнение локалей

const dateUS = DateTime.local(2025, 1, 5)
    .setLocale("en-US");

const dateDE = DateTime.local(2025, 1, 5)
    .setLocale("de-DE");

console.log(dateUS.localWeekNumber);
console.log(dateDE.localWeekNumber);

Одна и та же дата может принадлежать разным неделям в зависимости от локали.


localWeekday

Свойство localWeekday возвращает номер дня недели с учётом локали.

const date = DateTime.local(2025, 1, 5)
    .setLocale("en-US");

console.log(date.localWeekday);

В США воскресенье считается первым днём недели.

Для европейской локали:

const date = DateTime.local(2025, 1, 5)
    .setLocale("ru");

console.log(date.localWeekday);

Значения будут отличаться.


Сравнение weekday и localWeekday

Свойство Основа
weekday ISO
localWeekday локаль

ISO-вариант:

const date = DateTime.local(2025, 1, 5);

console.log(date.weekday);

Локальный вариант:

console.log(
    date.setLocale("en-US").localWeekday
);

localWeekYear

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

Для локальных недель Luxon предоставляет:

localWeekYear

Пример:

const date = DateTime.local(2025, 1, 1)
    .setLocale("en-US");

console.log(date.localWeekYear);

Создание даты через локальную неделю

Метод fromObject() поддерживает локальные недели.

const date = DateTime.fromObject({
    localWeekYear: 2025,
    localWeekNumber: 1,
    localWeekday: 1
}).setLocale("en-US");

console.log(date.toISODate());

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

Пример генерации недели:

const start = DateTime.local(2025, 5, 1)
    .startOf("week");

for (let i = 0; i < 7; i++) {
    console.log(
        start.plus({ days: i }).toISODate()
    );
}

Однако startOf("week") использует ISO-логику.

Для локальных календарей необходимо учитывать локаль отдельно.


Определение первого дня недели

Luxon не предоставляет прямого метода вроде:

getFirstDayOfWeek()

Но локаль влияет на:

  • localWeekday
  • форматирование;
  • вычисление локальных недель.

Локализованное форматирование недели

const date = DateTime.local()
    .setLocale("fr");

console.log(
    date.toLocaleString(DateTime.DATE_FULL)
);

Результат:

20 mai 2025

Работа с разными регионами

США

const us = DateTime.local()
    .setLocale("en-US");

console.log(us.localWeekday);

Великобритания

const uk = DateTime.local()
    .setLocale("en-GB");

console.log(uk.localWeekday);

Россия

const ru = DateTime.local()
    .setLocale("ru");

console.log(ru.localWeekday);

Группировка данных по локальным неделям

const sales = [
    DateTime.local(2025, 1, 1),
    DateTime.local(2025, 1, 2),
    DateTime.local(2025, 1, 10)
];

const grouped = {};

for (const date of sales) {
    const local = date.setLocale("en-US");

    const key = `${local.localWeekYear}-${local.localWeekNumber}`;

    if (!grouped[key]) {
        grouped[key] = [];
    }

    grouped[key].push(date.toISODate());
}

console.log(grouped);

Проверка принадлежности к одной локальной неделе

function isSameLocalWeek(a, b, locale) {
    const d1 = a.setLocale(locale);
    const d2 = b.setLocale(locale);

    return (
        d1.localWeekYear === d2.localWeekYear &&
        d1.localWeekNumber === d2.localWeekNumber
    );
}

Использование:

const a = DateTime.local(2025, 1, 1);
const b = DateTime.local(2025, 1, 3);

console.log(
    isSameLocalWeek(a, b, "en-US")
);

Навигация по локальным неделям

Переход к следующей неделе:

const nextWeek = DateTime.now()
    .plus({ weeks: 1 });

console.log(nextWeek.toISO());

Переход к предыдущей:

const prevWeek = DateTime.now()
    .minus({ weeks: 1 });

console.log(prevWeek.toISO());

Генерация диапазона локальной недели

function getLocalWeek(date, locale) {
    const localDate = date.setLocale(locale);

    const start = localDate.minus({
        days: localDate.localWeekday - 1
    });

    return Array.from({ length: 7 }, (_, i) =>
        start.plus({ days: i })
    );
}

Использование:

const week = getLocalWeek(
    DateTime.local(),
    "en-US"
);

week.forEach(day => {
    console.log(day.toISODate());
});

Локальные недели и Time Zone

Часовой пояс влияет на вычисления.

const date = DateTime.now()
    .setZone("America/New_York")
    .setLocale("en-US");

console.log(date.localWeekNumber);

Пример для Европы:

const paris = DateTime.now()
    .setZone("Europe/Paris")
    .setLocale("fr");

console.log(paris.localWeekNumber);

Различия на границе года

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

  • в конце декабря;
  • в начале января.

Пример:

const date = DateTime.local(2024, 12, 31);

console.log(date.weekYear);
console.log(date.localWeekYear);

Практический пример календарной сетки

function buildCalendar(year, month, locale) {
    const firstDay = DateTime.local(year, month, 1)
        .setLocale(locale);

    const offset = firstDay.localWeekday - 1;

    const start = firstDay.minus({ days: offset });

    return Array.from({ length: 42 }, (_, i) =>
        start.plus({ days: i })
    );
}

Использование:

const calendar = buildCalendar(
    2025,
    5,
    "ru"
);

calendar.forEach(day => {
    console.log(day.toISODate());
});

Типичные ошибки

Смешивание ISO и локальных недель

Неправильно:

date.weekNumber === date.localWeekNumber

Эти значения могут различаться.


Игнорирование локали

DateTime.local().localWeekday

Без setLocale() результат зависит от окружения.


Неверное ожидание от startOf(“week”)

date.startOf("week")

Метод работает по ISO-стандарту.


Когда использовать локальные недели

Локальные недели особенно важны в:

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

Краткая сводка API

API Назначение
localWeekday локальный день недели
localWeekNumber номер локальной недели
localWeekYear год локальной недели
setLocale() установка локали
fromObject() создание даты через локальные недели