Локализованное форматирование в date-fns основано на концепции
передачи локали (locale) в функции форматирования, что позволяет
получать строки дат, адаптированные под язык, культурные особенности и
правила конкретного региона. В отличие от встроенного Intl,
библиотека предоставляет более предсказуемый API, единый стиль работы и
возможность тонкой настройки отображения дат через подключаемые
локали.
Каждая локаль в date-fns представляет собой набор правил:
Локаль передаётся как опция:
import { format } from 'date-fns'
import { ru } from 'date-fns/locale'
format(new Date(2026, 0, 24), 'PPPP', { locale: ru })
Ключевой принцип: локаль не глобальная, а передаётся явно в каждую функцию.
Date-fns использует модульную структуру локалей. Каждая локаль импортируется отдельно:
import { enUS, de, fr, ru } from 'date-fns/locale'
Такой подход позволяет:
Пример выбора локали динамически:
import { format } from 'date-fns'
import { enUS, ru } from 'date-fns/locale'
const locales = { en: enUS, ru }
function formatDate(date, lang) {
return format(date, 'PPPP', { locale: locales[lang] })
}
Функция format поддерживает локализованные токены:
import { format } from 'date-fns'
import { ru } from 'date-fns/locale'
format(new Date(2026, 4, 22), 'EEEE, d MMMM yyyy', { locale: ru })
Результат:
пятница, 22 мая 2026
EEEE — полное название дня неделиEEE — сокращённое название дня неделиMMMM — полное название месяцаMMM — сокращённое название месяцаdo — порядковый номер дня (с суффиксом в некоторых
локалях)Одной из ключевых возможностей локализации является вывод относительных интервалов.
import { formatDistance } from 'date-fns'
import { ru } from 'date-fns/locale'
formatDistance(
new Date(2026, 4, 22),
new Date(2026, 4, 25),
{ locale: ru }
)
Результат:
3 дня
Используется для выражений типа «2 часа назад»:
import { formatDistanceToNow } from 'date-fns'
import { ru } from 'date-fns/locale'
formatDistanceToNow(new Date(2026, 4, 20), {
locale: ru,
addSuffix: true
})
Результат:
2 дня назад
Параметр addSuffix включает грамматическую форму с
предлогами.
Функция formatRelative формирует человекочитаемые строки
с учётом контекста даты:
import { formatRelative } from 'date-fns'
import { ru } from 'date-fns/locale'
formatRelative(new Date(2026, 4, 22), new Date(), { locale: ru })
Возможные результаты:
Логика зависит от расстояния между датами и внутренних правил локали.
Некоторые языки требуют изменения слов в зависимости от числа:
Date-fns автоматически выбирает правильную форму на основе локали.
В разных локалях могут меняться не только слова, но и порядок:
MMMM d, yyyyd MMMM yyyyЛокали содержат отдельные словари для:
Локаль можно применять последовательно в разных функциях:
import { format, formatDistance, formatRelative } from 'date-fns'
import { ru } from 'date-fns/locale'
const date = new Date(2026, 4, 22)
format(date, 'PPP', { locale: ru })
formatDistance(date, new Date(), { locale: ru })
formatRelative(date, new Date(), { locale: ru })
Это обеспечивает единообразие представления дат в интерфейсе.
Типичный сценарий — мультиязычное приложение:
import { format } from 'date-fns'
import { enUS, ru, de } from 'date-fns/locale'
const localeMap = {
en: enUS,
ru,
de
}
function formatUserDate(date, lang) {
return format(date, 'PPPP', {
locale: localeMap[lang] || enUS
})
}
Такой подход позволяет:
Если локаль отсутствует или не поддерживается, используется fallback:
format(date, 'PPPP', { locale: enUS })
Рекомендуется всегда задавать дефолтную локаль для предотвращения неоднородного вывода.
Хотя date-fns не предназначен для создания локалей с нуля в стандартном использовании, локаль представляет собой обычный объект JavaScript, что позволяет модифицировать или расширять её:
import { ru } from 'date-fns/locale'
const customRu = {
...ru,
formatDistance: {
...ru.formatDistance,
lessThanXSeconds: 'мгновенно'
}
}
Это даёт возможность:
Некоторые токены полностью зависят от локали:
format(new Date(), 'P', { locale: ru })
format(new Date(), 'PP', { locale: ru })
format(new Date(), 'PPP', { locale: ru })
format(new Date(), 'PPPP', { locale: ru })
Каждый уровень добавляет детализацию:
Локали в date-fns оптимизированы:
Это позволяет масштабировать приложение без лишних затрат памяти и времени загрузки.
format(date, 'PPPP') // всегда default enUS
Результат игнорирует нужный язык.
import ru from 'date-fns/locale/ru' // некорректный путь в современных версиях
Корректный способ — через именованный экспорт:
import { ru } from 'date-fns/locale'
Если разные части интерфейса используют разные локали, возникает:
При проектировании систем с date-fns часто выделяют слой форматирования:
// dateFormatter.js
import { format } from 'date-fns'
export function formatDate(date, locale, pattern = 'PPP') {
return format(date, pattern, { locale })
}
Такой слой позволяет: