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

Локаль в Day.js представляет собой набор правил форматирования дат, времени и текстовых представлений, зависящих от языка и культурных особенностей. Она влияет на отображение месяцев, дней недели, форматов относительного времени, календарных выражений и множества других аспектов.

Внутренне Day.js хранит локали в объекте dayjs.Ls, где каждая локаль определяется по строковому ключу:

dayjs.Ls['en'] // английская локаль
dayjs.Ls['ru'] // русская локаль

Каждая локаль представляет собой объект конфигурации:

{
  name: 'en',
  weekdays: [...],
  months: [...],
  relativeTime: {...},
  formats: {...},
  ordinal: function (n) { ... }
}

Подключение встроенных локалей

Day.js поставляется с набором локалей, но по умолчанию используется en. Для подключения дополнительных локалей их необходимо импортировать отдельно:

import dayjs from 'dayjs'
import 'dayjs/locale/ru'

После импорта локаль становится доступной:

dayjs.locale('ru')

Изменение локали глобальное для текущего экземпляра Day.js.


Установка и переключение локали

Глобальная установка

dayjs.locale('ru')

После этого все последующие вызовы используют русскую локаль:

dayjs().format('dddd, D MMMM YYYY')

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

Day.js позволяет переопределять локаль на уровне конкретного объекта:

dayjs().locale('ru').format('dddd')

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


Структура локали

Локаль Day.js состоит из нескольких ключевых частей, каждая из которых отвечает за отдельный аспект форматирования.

Дни недели и месяцы

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

months: [
  'январь', 'февраль', 'март', 'апрель',
  'май', 'июнь', 'июль', 'август',
  'сентябрь', 'октябрь', 'ноябрь', 'декабрь'
]

Эти значения используются при форматировании dddd, MMMM и других токенов.


Форматы отображения

Раздел formats определяет шаблоны вывода дат:

formats: {
  LT: 'HH:mm',
  LTS: 'HH:mm:ss',
  L: 'DD.MM.YYYY',
  LL: 'D MMMM YYYY',
  LLL: 'D MMMM YYYY HH:mm',
  LLLL: 'dddd, D MMMM YYYY HH:mm'
}

При вызове:

dayjs().format('LL')

Day.js подставляет соответствующий шаблон из локали.


Относительное время

Раздел relativeTime отвечает за выражения вроде «3 минуты назад» или «через 2 дня»:

relativeTime: {
  future: 'через %s',
  past: '%s назад',
  s: 'несколько секунд',
  m: 'минуту',
  mm: '%d минут',
  h: 'час',
  hh: '%d часов',
  d: 'день',
  dd: '%d дней',
  M: 'месяц',
  MM: '%d месяцев',
  y: 'год',
  yy: '%d лет'
}

Функция форматирования автоматически выбирает нужную форму:

dayjs().add(5, 'minute').fromNow()

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

Создание локали выполняется через метод dayjs.locale с передачей объекта конфигурации.

import dayjs from 'dayjs'

dayjs.locale({
  name: 'custom',
  weekdays: ['A', 'B', 'C', 'D', 'E', 'F', 'G'],
  months: ['M1', 'M2', 'M3', 'M4', 'M5', 'M6', 'M7', 'M8', 'M9', 'M10', 'M11', 'M12'],
  relativeTime: {
    future: 'in %s',
    past: '%s ago',
    s: 'a few seconds',
    m: 'one minute',
    mm: '%d minutes',
    h: 'an hour',
    hh: '%d hours',
    d: 'a day',
    dd: '%d days',
    M: 'a month',
    MM: '%d months',
    y: 'a year',
    yy: '%d years'
  },
  ordinal: (n) => `${n}.`
}, null, true)

Последний параметр true означает регистрацию локали без немедленного переключения.


Обновление существующей локали

Day.js позволяет модифицировать уже существующие локали через updateLocale.

import dayjs from 'dayjs'

dayjs.updateLocale('en', {
  months: [
    'Jan', 'Feb', 'Mar', 'Apr',
    'May', 'Jun', 'Jul', 'Aug',
    'Sep', 'Oct', 'Nov', 'Dec'
  ]
})

Это не заменяет локаль полностью, а изменяет только указанные поля.


Локализация порядковых чисел

Функция ordinal определяет формат числовых суффиксов:

ordinal: function (n) {
  return n + 'th'
}

Пример:

dayjs().date(1).format('Do MMMM')

Подключение нескольких локалей

При работе в проектах с мультиязычностью часто требуется загрузка нескольких локалей:

import 'dayjs/locale/ru'
import 'dayjs/locale/de'
import 'dayjs/locale/fr'

Переключение:

dayjs.locale('de')
dayjs.locale('fr')

Каждая локаль занимает отдельный объект в dayjs.Ls.


Динамическая загрузка локалей

Для оптимизации размера бандла локали можно загружать динамически:

async function setLocale(locale) {
  await import(`dayjs/locale/${locale}.js`)
  dayjs.locale(locale)
}

Это особенно полезно в крупных приложениях с ленивой загрузкой.


Локаль и плагины Day.js

Некоторые плагины зависят от локали, особенно:

  • relativeTime
  • updateLocale
  • localizedFormat

Подключение выполняется до установки локали:

import relativeTime from 'dayjs/plugin/relativeTime'
dayjs.extend(relativeTime)

Поведение локали в цепочках вызовов

Локаль сохраняется внутри объекта Day.js и передаётся по цепочке:

dayjs()
  .locale('ru')
  .add(1, 'day')
  .format('dddd')

Каждая операция сохраняет текущую локаль.


Форматирование календаря (calendar)

Локали также определяют поведение метода calendar:

calendar: {
  sameDay: '[Сегодня в] LT',
  nextDay: '[Завтра в] LT',
  nextWeek: 'dddd [в] LT',
  lastDay: '[Вчера в] LT',
  lastWeek: '[Прошлый] dddd [в] LT',
  sameElse: 'L'
}

Пример использования:

dayjs().calendar()

Внутренний механизм регистрации локалей

При подключении файла локали происходит регистрация:

dayjs.locale('ru', localeObject)

И объект сохраняется в глобальном реестре:

dayjs.Ls['ru'] = localeObject

При переключении Day.js просто меняет текущий ключ локали.


Приоритет локалей

При форматировании используется следующий порядок:

  1. Локаль текущего экземпляра (dayjs().locale())
  2. Глобальная локаль (dayjs.locale())
  3. Локаль по умолчанию (en)

Использование локалей в SSR и изоляции окружений

В серверных приложениях важно избегать глобального состояния:

const d = dayjs().locale('ru')

Это гарантирует независимость от глобальной локали между запросами.


Расширенные сценарии кастомизации

Локаль может включать дополнительные поля, используемые плагинами:

{
  name: 'custom',
  formats: { ... },
  relativeTime: { ... },
  weekStart: 1
}

Некоторые плагины используют weekStart для определения начала недели.


Комбинирование локалей с форматами

Локаль не заменяет форматирование, а дополняет его:

dayjs().locale('ru').format('LLLL')

Здесь токен LLLL берётся из локали, а значения подставляются из текущей даты.


Изоляция локали в разных частях приложения

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

const instanceA = dayjs().locale('ru')
const instanceB = dayjs().locale('en')

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