Плагин calendar в Day.js отвечает за формирование
человеко-читаемых текстов относительных дат, таких как «сегодня в
14:00», «вчера в 18:30» или «на прошлой неделе». Именно он определяет,
как библиотека будет описывать дату в зависимости от её удалённости от
текущего момента.
Функциональность календаря в Day.js основана на наборе правил, которые сопоставляют конкретный диапазон дат с текстовым шаблоном. Эти правила применяются при вызове метода:
dayjs().calendar()
или при использовании форматирования с календарным режимом:
dayjs().calendar(referenceDate)
Внутренне Day.js сравнивает текущую дату с опорной и выбирает одно из заранее определённых правил.
Основные категории сравнения:
Перед использованием необходимо подключить плагин:
import dayjs from 'dayjs'
import calendar from 'dayjs/plugin/calendar'
dayjs.extend(calendar)
Без активации плагина метод calendar() недоступен.
Настройка текстов calendar осуществляется через локаль. Каждый набор правил представляет собой объект, содержащий функции или строки для различных случаев:
sameDaynextDaynextWeeklastDaylastWeeksameElseКаждое правило может быть задано как строка или функция, возвращающая строку.
Пример базовой структуры:
import dayjs from 'dayjs'
dayjs.updateLocale('en', {
calendar: {
sameDay: '[Today at] HH:mm',
nextDay: '[Tomorrow at] HH:mm',
nextWeek: 'dddd [at] HH:mm',
lastDay: '[Yesterday at] HH:mm',
lastWeek: '[Last] dddd [at] HH:mm',
sameElse: 'DD/MM/YYYY'
}
})
В строковых шаблонах используются квадратные скобки для фиксации текста:
'[Today at]'
Все выражения внутри [] выводятся буквально без
форматирования.
Оставшаяся часть строки интерпретируется как формат даты:
HH:mm — часы и минутыdddd — полное название дня неделиDD/MM/YYYY — дата в числовом форматеБолее гибкий способ настройки — использование функций. Это позволяет динамически формировать текст в зависимости от входной даты.
dayjs.updateLocale('en', {
calendar: {
sameDay: (now) => `[Today at] ${now.format('HH:mm')}`,
nextDay: (now) => `[Tomorrow at] ${now.format('HH:mm')}`,
lastDay: (now) => `[Yesterday at] ${now.format('HH:mm')}`,
nextWeek: (now) => `${now.format('dddd')} [at] ${now.format('HH:mm')}`,
lastWeek: (now) => `[Last] ${now.format('dddd')} [at] ${now.format('HH:mm')}`,
sameElse: (now) => now.format('DD/MM/YYYY')
}
})
Функции получают объект Day.js, уже приведённый к нужной дате, и позволяют использовать любые методы форматирования.
Day.js определяет категорию даты по следующим правилам:
Используется, если дата совпадает с текущим днём.
sameDay: '[Today at] HH:mm'
Используется для следующего календарного дня.
nextDay: '[Tomorrow at] HH:mm'
Используется для предыдущего календарного дня.
lastDay: '[Yesterday at] HH:mm'
Применяется к датам, которые попадают в следующую неделю, но не являются «завтра».
nextWeek: 'dddd [at] HH:mm'
Применяется к датам из предыдущей недели.
lastWeek: '[Last] dddd [at] HH:mm'
Фолбэк-правило для всех остальных случаев.
sameElse: 'DD.MM.YYYY'
Настройки календаря привязаны к конкретной локали. Для изменения
используется updateLocale:
dayjs.updateLocale('ru', {
calendar: {
sameDay: '[Сегодня в] HH:mm',
nextDay: '[Завтра в] HH:mm',
lastDay: '[Вчера в] HH:mm',
nextWeek: 'dddd [в] HH:mm',
lastWeek: '[Прошлый] dddd [в] HH:mm',
sameElse: 'DD.MM.YYYY'
}
})
После этого все вызовы календаря для данной локали будут использовать новые строки.
При смене локали автоматически подхватываются её правила:
import 'dayjs/locale/ru'
dayjs.locale('ru')
Если локаль содержит секцию calendar, она будет
применена без дополнительных действий.
Метод calendar может принимать вторым аргументом дату
сравнения:
dayjs(date).calendar(referenceDate)
Это влияет на выбор шаблона, так как сравнение происходит относительно переданного значения, а не текущего времени.
Пример:
const now = dayjs('2026-05-22 12:00')
dayjs('2026-05-21 18:00').calendar(now)
Результат будет зависеть от правил lastDay.
Calendar-формат часто комбинируется с локализацией времени:
dayjs.updateLocale('ru', {
calendar: {
sameDay: '[Сегодня в] LT',
nextDay: '[Завтра в] LT',
lastDay: '[Вчера в] LT',
nextWeek: 'dddd [в] LT',
lastWeek: '[Прошлая] dddd [в] LT',
sameElse: 'DD.MM.YYYY'
}
})
LT — локализованный формат времени, который адаптируется
под текущую локаль.
Выбор шаблона происходит последовательно:
sameElse)Этот порядок нельзя изменить, но можно влиять на результат через настройку правил.
Без скобок текст будет интерпретирован как формат:
sameDay: 'Today at HH:mm'
Результат может быть некорректным. Правильно:
sameDay: '[Today at] HH:mm'
Если локаль не активирована, настройки календаря могут не применяться:
dayjs.locale('ru')
без подключения dayjs/locale/ru.
Прямое изменение объекта локали не применяется корректно:
// неправильно
dayjs.Ls.en.calendar = {}
Правильный способ:
dayjs.updateLocale('en', { calendar: {} })
В сложных интерфейсах календарь используется для формирования сообщений уведомлений, логов событий и временных меток в чатах.
Пример адаптивного поведения:
dayjs.updateLocale('en', {
calendar: {
sameDay: (d) => {
const hour = d.hour()
return hour < 12
? `[Morning at] ${d.format('HH:mm')}`
: `[Evening at] ${d.format('HH:mm')}`
},
nextDay: '[Tomorrow at] HH:mm',
lastDay: '[Yesterday at] HH:mm',
nextWeek: 'dddd [at] HH:mm',
lastWeek: '[Last] dddd [at] HH:mm',
sameElse: 'DD MMM YYYY'
}
})
Такой подход позволяет не только локализовать текст, но и вводить контекстную семантику в отображение дат.