Локализованные недели

В разных странах неделя начинается по-разному. В большинстве европейских стран первым днём недели считается понедельник, а в США — воскресенье. Кроме того, различается правило определения первой недели года.

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

Основные задачи локализованных недель:

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

Метод week()

Метод week() возвращает номер недели года в соответствии с текущей локалью.

const moment = require('moment');

const date = moment('2025-01-10');

console.log(date.week());

Результат зависит от активной локали.


Установка локали

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

moment.locale('ru');

После установки русской локали неделя будет начинаться с понедельника.

Для американской локали:

moment.locale('en');

В этом случае неделя начинается с воскресенья.


Различия между week() и isoWeek()

Moment.js поддерживает два разных стандарта недель:

Метод Стандарт
week() локализованные недели
isoWeek() ISO 8601

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

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

Пример:

const date = moment('2025-01-01');

console.log(date.week());
console.log(date.isoWeek());

В зависимости от локали результаты могут различаться.


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

Метод startOf('week') возвращает начало недели по локали.

const now = moment();

console.log(now.startOf('week').format('YYYY-MM-DD'));

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

Для американской — воскресенье.


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

Метод endOf('week') возвращает последний момент недели.

const now = moment();

console.log(
    now.endOf('week').format('YYYY-MM-DD HH:mm:ss')
);

Пример различий локалей

moment.locale('ru');

console.log(
    moment('2025-03-05')
        .startOf('week')
        .format('dddd')
);

moment.locale('en');

console.log(
    moment('2025-03-05')
        .startOf('week')
        .format('dddd')
);

Результат:

понедельник
Sunday

Изменение номера недели

Метод week(number) позволяет установить неделю года.

const date = moment();

date.week(20);

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

Moment автоматически пересчитает дату.


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

Иногда неделя относится к другому году.

Например:

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

Для получения года локализованной недели используется метод weekYear().

const date = moment('2021-01-01');

console.log(date.weekYear());

ISO-год недели

Для ISO-стандарта существует отдельный метод:

console.log(
    moment('2021-01-01').isoWeekYear()
);

Настройка параметров недели

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

Используется метод updateLocale().


Параметр dow

dow — первый день недели.

Значение День
0 воскресенье
1 понедельник
6 суббота

Пример:

moment.updateLocale('custom', {
    week: {
        dow: 1
    }
});

moment.locale('custom');

Параметр doy

doy определяет правило первой недели года.

Например:

moment.updateLocale('custom', {
    week: {
        dow: 1,
        doy: 4
    }
});

Здесь:

  • неделя начинается в понедельник;
  • первая неделя должна содержать 4 января.

Это соответствует ISO 8601.


Проверка параметров локали

Получение текущих настроек:

console.log(
    moment.localeData()._week
);

Результат:

{
    dow: 1,
    doy: 4
}

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

moment.locale('ru');

const current = moment();

const start = current.clone().startOf('week');

for (let i = 0; i < 7; i++) {
    console.log(
        start.clone()
            .add(i, 'days')
            .format('dddd DD.MM.YYYY')
    );
}

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

Moment.js поддерживает специальные токены форматирования.

Токен Описание
w номер недели
ww номер недели с нулём
gggg год локализованной недели

Пример:

const date = moment();

console.log(
    date.format('ww')
);

ISO-токены

Токен Описание
W ISO-неделя
WW ISO-неделя с нулём
GGGG ISO-год недели

Пример:

console.log(
    moment().format('WW')
);

Сравнение локализованной и ISO-недели

const date = moment('2025-01-01');

console.log('week:', date.week());
console.log('isoWeek:', date.isoWeek());

Работа с границами года

Особенно важно учитывать локализованные недели в:

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

Пример:

const date = moment('2020-12-31');

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

Получение дня недели по локали

Метод weekday() работает с локализованными неделями.

moment.locale('ru');

const date = moment();

console.log(date.weekday());

При русской локали:

Значение День
0 понедельник
6 воскресенье

Установка локализованного дня недели

const date = moment();

date.weekday(0);

console.log(
    date.format('dddd')
);

Различие day() и weekday()

Метод Особенность
day() воскресенье всегда 0
weekday() зависит от локали

Пример:

moment.locale('ru');

const date = moment();

console.log(date.day());
console.log(date.weekday());

Перебор недель месяца

const start = moment()
    .startOf('month')
    .startOf('week');

for (let i = 0; i < 6; i++) {
    console.log(
        start.clone()
            .add(i, 'weeks')
            .format('DD.MM.YYYY')
    );
}

Генерация сетки календаря

moment.locale('ru');

const start = moment()
    .startOf('month')
    .startOf('week');

const days = [];

for (let i = 0; i < 42; i++) {
    days.push(
        start.clone()
            .add(i, 'days')
            .format('DD.MM.YYYY')
    );
}

console.log(days);

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

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

const date = moment.tz(
    '2025-01-01 10:00',
    'Europe/Moscow'
);

console.log(date.week());

Частые ошибки

Изменение оригинального объекта

Методы startOf() и endOf() изменяют объект Moment.

Ошибка:

const date = moment();

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

console.log(date.format());

Безопасный вариант:

const date = moment();

const start = date.clone().startOf('week');

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

Ошибка:

date.week();
date.isoWeek();

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


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

moment.locale('ru');

Без установки локали поведение может отличаться от ожидаемого.


Практический пример расписания

moment.locale('ru');

const currentWeek = moment().week();

const events = [
    {
        title: 'Совещание',
        date: '2025-05-12'
    },
    {
        title: 'Презентация',
        date: '2025-05-15'
    }
];

events.forEach(event => {
    const week = moment(event.date).week();

    if (week === currentWeek) {
        console.log(event.title);
    }
});

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

function getWeekRange(date) {
    return {
        start: moment(date)
            .startOf('week')
            .format('YYYY-MM-DD'),

        end: moment(date)
            .endOf('week')
            .format('YYYY-MM-DD')
    };
}

console.log(
    getWeekRange('2025-06-15')
);

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

moment.defineLocale('my-locale', {
    week: {
        dow: 1,
        doy: 7
    }
});

moment.locale('my-locale');

Методы для локализованных недель

Метод Назначение
week() номер локализованной недели
weekYear() год локализованной недели
weekday() день недели по локали
startOf('week') начало недели
endOf('week') конец недели

Методы ISO-недель

Метод Назначение
isoWeek() ISO-неделя
isoWeekYear() ISO-год
isoWeekday() ISO-день недели
startOf('isoWeek') начало ISO-недели
endOf('isoWeek') конец ISO-недели

Сравнение локализованной и ISO-модели

Особенность week() isoWeek()
Зависит от локали Да Нет
Первый день недели зависит от локали понедельник
Международный стандарт Нет Да
Использование в ISO 8601 Нет Да

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

Локализованные недели особенно важны в следующих сценариях:

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