ISO-недельная система датирования (ISO 8601) вводит отдельное понятие календарной недели и связанного с ней «года недели» (ISO week-numbering year). В отличие от стандартного календарного года, который начинается 1 января, недельный год привязан к первой неделе, содержащей первый четверг года.
Ключевая особенность:
Это приводит к важному эффекту: дата в конце декабря может относиться к следующему ISO-году, а дата в начале января — к предыдущему.
В библиотеке Day.js работа с ISO-неделями реализуется через плагины. Базовая установка не включает недельные вычисления ISO, поэтому требуется расширение функциональности.
Основные плагины:
isoWeek — добавляет ISO-неделиisoWeekYear — добавляет поддержку ISO-недельного
годаПример подключения:
import dayjs from 'dayjs'
import isoWeek from 'dayjs/plugin/isoWeek'
import isoWeekYear from 'dayjs/plugin/isoWeekYear'
dayjs.extend(isoWeek)
dayjs.extend(isoWeekYear)
После подключения становятся доступны методы, работающие по ISO-стандарту.
Календарный год:
dayjs('2025-01-01').year() // 2025
ISO-недельный год:
dayjs('2025-01-01').isoWeekYear()
Эти значения могут различаться на границах года.
dayjs('2024-12-30').isoWeekYear() // может быть 2025
dayjs('2025-01-01').isoWeekYear() // может быть 2025 или 2024 в зависимости от недели
Причина заключается в том, что неделя определяется не по месяцу, а по структуре ISO-календаря.
Метод isoWeekYear() возвращает год, к которому относится
ISO-неделя даты.
dayjs().isoWeekYear()
isoWeek().Метод isoWeek() возвращает номер недели по
ISO-стандарту.
dayjs('2025-01-01').isoWeek()
Диапазон значений:
ISO-недельная система всегда опирается на пару значений:
isoWeekYear() — год неделиisoWeek() — номер неделиЭта пара уникально идентифицирует любую дату в рамках ISO-календаря.
ISO-недельный год строится вокруг недельных блоков:
| Дата | ISO-неделя | ISO-год |
|---|---|---|
| 2024-12-30 | 1 | 2025 |
| 2024-12-31 | 1 | 2025 |
| 2025-01-01 | 1 | 2025 |
| 2025-01-02 | 1 | 2025 |
Это демонстрирует смещение границы года относительно календаря.
Day.js предоставляет два разных измерения времени:
year() — календарный годisoWeekYear() — год недельного календаряconst d = dayjs('2024-12-31')
d.year() // 2024
d.isoWeekYear() // 2025
Такое расхождение критично для:
Корректная работа с ISO-календарём требует использования обеих функций одновременно:
const d = dayjs('2025-01-01')
const week = d.isoWeek()
const year = d.isoWeekYear()
console.log(`${year}-W${week}`)
Результат формирует стандартный ISO-идентификатор недели.
Часто используется строковый формат:
YYYY-Www
Пример реализации:
function formatIsoWeek(date) {
const d = dayjs(date)
const year = d.isoWeekYear()
const week = String(d.isoWeek()).padStart(2, '0')
return `${year}-W${week}`
}
formatIsoWeek('2024-12-31') // 2025-W01
Такой формат применяется в:
ISO-недели не зависят от локали, в отличие от обычных недель Day.js.
Неделя всегда начинается в понедельник, независимо от региональных настроек.
В некоторых годах возникает дополнительная неделя:
dayjs('2015-12-31').isoWeek() // 53
// некорректно для недельной аналитики
const y = dayjs(date).year()
week() зависит от локали и может давать разные
результаты.
dayjs.extend(isoWeek)
// правильно
dayjs(date).isoWeek()
// потенциально некорректно
dayjs(date).week()
Без подключения плагина метод отсутствует или возвращает ошибку:
dayjs.extend(isoWeekYear)
ISO-недельный год используется при построении:
Пример агрегации:
const grouped = {}
data.forEach(item => {
const key = `${dayjs(item.date).isoWeekYear()}-${dayjs(item.date).isoWeek()}`
grouped[key] = (grouped[key] || 0) + item.value
})
Особенно важны переходные дни:
Это делает ISO-недели устойчивыми для расчётов, где неделя важнее месяца или календарного года.
const dates = [
'2024-12-29',
'2024-12-30',
'2024-12-31',
'2025-01-01',
'2025-01-02'
]
dates.forEach(d => {
const dt = dayjs(d)
console.log(d, dt.isoWeekYear(), dt.isoWeek())
})
Такой анализ показывает непрерывность недельного ряда независимо от смены календарного года.