Номер недели

Номер недели — это порядковый номер недели внутри года. В большинстве стран и стандартов используется система ISO 8601, где:

  • неделя начинается с понедельника;
  • первая неделя года — та, которая содержит первый четверг года;
  • номер недели находится в диапазоне от 1 до 52 или 53.

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


Свойство weekNumber

Для получения номера недели используется свойство weekNumber.

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

import { DateTime } from "luxon";

const date = DateTime.local(2025, 3, 14);

console.log(date.weekNumber);

Результат:

11

Дата 14 марта 2025 относится к одиннадцатой ISO-неделе года.


Как Luxon вычисляет номер недели

Luxon использует ISO-стандарт, поэтому:

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

Проверка граничных дат

Начало года

const date = DateTime.local(2021, 1, 1);

console.log(date.weekNumber);

Результат:

53

1 января 2021 относится к 53-й неделе 2020 года по ISO.


Конец года

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

console.log(date.weekNumber);

Результат:

53

Свойство weekYear

При работе с номером недели почти всегда необходимо учитывать ISO-год недели (weekYear).

Почему это важно

Календарный год и ISO-год недели могут отличаться.

const date = DateTime.local(2021, 1, 1);

console.log(date.year);
console.log(date.weekYear);
console.log(date.weekNumber);

Результат:

2021
2020
53

Здесь:

  • календарный год — 2021;
  • ISO-неделя принадлежит 2020;
  • номер недели — 53.

Свойство weekday

Для полноценной работы с неделями используется свойство weekday.

Нумерация дней:

День Значение
Понедельник 1
Вторник 2
Среда 3
Четверг 4
Пятница 5
Суббота 6
Воскресенье 7

Пример:

const date = DateTime.local(2025, 3, 14);

console.log(date.weekday);

Результат:

5

Пятница.


Создание даты через номер недели

Luxon позволяет создавать дату не только через год, месяц и день, но и через:

  • weekYear
  • weekNumber
  • weekday

Создание даты ISO-недели

const date = DateTime.fromObject({
  weekYear: 2025,
  weekNumber: 20,
  weekday: 1
});

console.log(date.toISODate());

Результат:

2025-05-12

Создан понедельник 20-й недели 2025 года.


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

Метод startOf("week")

const date = DateTime.local(2025, 3, 14);

const start = date.startOf("week");

console.log(start.toISODate());

Результат:

2025-03-10

Получение конца недели

Метод endOf("week")

const date = DateTime.local(2025, 3, 14);

const end = date.endOf("week");

console.log(end.toISO());

Результат:

2025-03-16T23:59:59.999

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

Следующая неделя

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

console.log(nextWeek.weekNumber);

Предыдущая неделя

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

console.log(prevWeek.weekNumber);

Разница между неделями

Метод diff

const start = DateTime.local(2025, 1, 1);
const end = DateTime.local(2025, 2, 1);

const diff = end.diff(start, "weeks");

console.log(diff.toObject());

Результат:

{ weeks: 4.428571428571429 }

Округление количества недель

const weeks = Math.floor(
  end.diff(start, "weeks").weeks
);

console.log(weeks);

Получение всех дней недели

Частая задача — сформировать массив дней текущей недели.

const now = DateTime.now();

const start = now.startOf("week");

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

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

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

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

Luxon поддерживает специальные токены для ISO-недель.

Токен Значение
W номер недели
WW номер недели с ведущим нулём
kkkk ISO-week-year

Пример

const date = DateTime.local(2025, 3, 14);

console.log(
  date.toFormat("kkkk-'W'WW")
);

Результат:

2025-W11

Формат ISO Week Date

ISO допускает запись даты в формате:

YYYY-Www-D

Пример:

2025-W11-5

Где:

  • 2025 — ISO-год;
  • 11 — номер недели;
  • 5 — пятница.

Создание ISO Week Date вручную

const date = DateTime.fromObject({
  weekYear: 2025,
  weekNumber: 11,
  weekday: 5
});

console.log(date.toISODate());

Результат:

2025-03-14

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

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

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

console.log(date.weekNumber);

Локаль влияет на форматирование текста, но не меняет ISO-алгоритм недель.


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

Для получения локализованных названий дней применяется класс Info.

import { Info } from "luxon";

console.log(
  Info.weekdays("long", { locale: "ru" })
);

Результат:

[
  'понедельник',
  'вторник',
  'среда',
  'четверг',
  'пятница',
  'суббота',
  'воскресенье'
]

Календарная сетка недели

Пример формирования структуры для календаря.

function getWeek(date) {
  const start = date.startOf("week");

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

const week = getWeek(DateTime.now());

week.forEach(day => {
  console.log({
    date: day.toISODate(),
    week: day.weekNumber,
    weekday: day.weekday
  });
});

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

function isSameWeek(a, b) {
  return (
    a.weekYear === b.weekYear &&
    a.weekNumber === b.weekNumber
  );
}

const d1 = DateTime.local(2025, 3, 10);
const d2 = DateTime.local(2025, 3, 14);

console.log(isSameWeek(d1, d2));

Результат:

true

Сортировка по неделям

const dates = [
  DateTime.local(2025, 3, 14),
  DateTime.local(2025, 1, 1),
  DateTime.local(2025, 7, 20)
];

dates.sort((a, b) => {
  if (a.weekYear !== b.weekYear) {
    return a.weekYear - b.weekYear;
  }

  return a.weekNumber - b.weekNumber;
});

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

const orders = [
  DateTime.local(2025, 3, 10),
  DateTime.local(2025, 3, 12),
  DateTime.local(2025, 3, 20)
];

const grouped = {};

for (const order of orders) {
  const key =
    `${order.weekYear}-W${order.weekNumber}`;

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

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

console.log(grouped);

Работа с 53-й неделей

Некоторые годы содержат 53 недели.

Проверка:

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

console.log(date.weekNumber);

Результат:

53

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

const currentWeek = DateTime.now().weekNumber;

console.log(currentWeek);

Получение текущего ISO-года недели

const currentWeekYear =
  DateTime.now().weekYear;

console.log(currentWeekYear);

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

function generateWeeks(year, count) {
  return Array.from(
    { length: count },
    (_, i) => ({
      weekYear: year,
      weekNumber: i + 1
    })
  );
}

console.log(generateWeeks(2025, 10));

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

let current = DateTime.now();

function nextWeek() {
  current = current.plus({ weeks: 1 });
}

function prevWeek() {
  current = current.minus({ weeks: 1 });
}

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

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

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

Пример формирования ключа аналитики:

const date = DateTime.now();

const analyticsKey =
  `${date.weekYear}-W${date.weekNumber}`;

console.log(analyticsKey);

Ошибки при работе с неделями

Игнорирование weekYear

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

const key = `${date.year}-${date.weekNumber}`;

Правильно:

const key =
  `${date.weekYear}-${date.weekNumber}`;

Использование year вместо weekYear

const date = DateTime.local(2021, 1, 1);

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

Результат:

2021
2020

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

В ISO:

Понедельник = первый день недели

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

function printWeek(date) {
  const start = date.startOf("week");

  for (let i = 0; i < 7; i++) {
    const day = start.plus({ days: i });

    console.log(
      day.toFormat("cccc dd.MM.yyyy")
    );
  }
}

printWeek(DateTime.now());

Практический пример: выборка данных по ISO-неделе

function filterByWeek(items, weekYear, weekNumber) {
  return items.filter(item => {
    return (
      item.weekYear === weekYear &&
      item.weekNumber === weekNumber
    );
  });
}

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

const now = DateTime.now();

const range = {
  start: now.startOf("week"),
  end: now.endOf("week")
};

console.log({
  start: range.start.toISO(),
  end: range.end.toISO()
});

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

const date = DateTime.now();

const label =
  `Неделя ${date.weekNumber}`;

console.log(label);

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

function goToWeek(year, week) {
  return DateTime.fromObject({
    weekYear: year,
    weekNumber: week,
    weekday: 1
  });
}

const result = goToWeek(2025, 30);

console.log(result.toISODate());