Форматирование с учетом локали

Локализация в Luxon основана на стандартном механизме ECMAScript Internationalization API (Intl). Это означает, что библиотека не реализует собственные словари или таблицы форматов дат, а делегирует формирование локализованных строк встроенным возможностям JavaScript-движка.

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

  • структура даты и времени (год, месяц, день, часы)
  • представление этих данных в конкретной локали

Luxon управляет первым уровнем, а второй полностью отдаётся Intl.DateTimeFormat.


Локаль как часть объекта DateTime

Каждый экземпляр DateTime в Luxon может хранить информацию о локали. Локаль влияет на отображение месяцев, дней недели, форматов времени и порядка компонентов даты.

Локаль задаётся строкой в формате BCP 47:

  • en — английский
  • ru — русский
  • de — немецкий
  • fr-CA — французский (Канада)

Локаль может быть установлена:

  • глобально для всей библиотеки
  • локально для конкретного объекта

Глобальная локаль через Settings

Luxon предоставляет глобальную настройку, влияющую на все создаваемые даты.

import { Settings } from "luxon";

Settings.defaultLocale = "ru";

После этого все новые объекты DateTime будут использовать русскую локаль, если не переопределено явно.

Глобальная локаль влияет на:

  • названия месяцев
  • названия дней недели
  • формат вывода в toLocaleString

Локаль на уровне DateTime

Локаль может быть задана непосредственно при работе с объектом времени:

import { DateTime } from "luxon";

const dt = DateTime.now().setLocale("de");

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

Пример использования одного значения в разных локалях:

const dt = DateTime.local(2026, 5, 23);

dt.setLocale("en").toLocaleString(DateTime.DATE_FULL);
dt.setLocale("ru").toLocaleString(DateTime.DATE_FULL);
dt.setLocale("de").toLocaleString(DateTime.DATE_FULL);

Форматирование через предустановленные форматы

Luxon предоставляет набор предопределённых форматов через константы DateTime:

  • DATE_SHORT
  • DATE_MED
  • DATE_FULL
  • DATE_HUGE
  • TIME_SIMPLE
  • DATETIME_SHORT
  • DATETIME_FULL
  • DATETIME_HUGE

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

Пример:

const dt = DateTime.local(2026, 5, 23, 14, 30);

dt.setLocale("en").toLocaleString(DateTime.DATETIME_FULL);
dt.setLocale("ru").toLocaleString(DateTime.DATETIME_FULL);

Разница проявляется в:

  • порядке компонентов даты
  • названии месяца
  • формате времени (12/24 часа)
  • использовании AM/PM

Механизм toLocaleString

Основной метод локализованного форматирования — toLocaleString.

Он принимает:

  1. предустановку
  2. объект Intl.DateTimeFormatOptions

Предустановка

dt.toLocaleString(DateTime.DATE_FULL);

Расширенные настройки

dt.toLocaleString({
  locale: "ru",
  weekday: "long",
  year: "numeric",
  month: "long",
  day: "2-digit"
});

Такой режим полностью соответствует Intl.DateTimeFormat.


Тонкая настройка через Intl.DateTimeFormatOptions

Luxon не ограничивает форматирование только готовыми шаблонами. Через объект опций можно контролировать структуру вывода с высокой точностью.

Основные параметры:

  • year: “numeric” | “2-digit”
  • month: “numeric” | “2-digit” | “long” | “short” | “narrow”
  • day: “numeric” | “2-digit”
  • hour: “numeric” | “2-digit”
  • minute: “numeric” | “2-digit”
  • second: “numeric” | “2-digit”
  • weekday: “long” | “short” | “narrow”

Пример:

dt.toLocaleString({
  locale: "ru",
  weekday: "long",
  year: "numeric",
  month: "long",
  day: "numeric",
  hour: "2-digit",
  minute: "2-digit"
});

Влияние локали на названия месяцев и дней недели

Luxon не хранит названия месяцев внутри себя. Они формируются через Intl, поэтому полностью зависят от выбранной локали.

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

Одна и та же дата:

const dt = DateTime.local(2026, 5, 23);

Вывод:

  • en: May 23, 2026
  • ru: 23 мая 2026 г.
  • de: 23. Mai 2026

Различия затрагивают:

  • порядок компонентов
  • грамматические формы
  • сокращения месяцев
  • формат точки или запятой

Формат времени и локаль

Локаль также влияет на систему времени:

  • 12-часовой формат (AM/PM) в en-US
  • 24-часовой формат в ru, de, fr и большинстве европейских локалей

Пример:

dt.setLocale("en").toLocaleString(DateTime.TIME_SIMPLE);
dt.setLocale("ru").toLocaleString(DateTime.TIME_SIMPLE);

Результат будет различаться не только числом, но и наличием AM/PM.


Явное переопределение локали при форматировании

Локаль можно указать прямо в момент форматирования, не изменяя объект:

dt.toLocaleString({
  locale: "ru",
  month: "long",
  day: "numeric",
  year: "numeric"
});

Это полезно при:

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

Наследование локали при операциях с DateTime

При преобразованиях (например, plus, minus, set) локаль сохраняется:

const dt = DateTime.now().setLocale("ru");

const next = dt.plus({ days: 5 });

next унаследует ту же локаль, что и исходный объект.


Особенности поведения при отсутствии локали

Если локаль не задана:

  • используется Settings.defaultLocale
  • если он не установлен — используется локаль среды выполнения (обычно en-US)

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


Работа с региональными форматами дат

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

  • разделители (/, ., -)
  • порядок день/месяц/год
  • наличие ведущих нулей
  • формат длинных дат

Пример различий:

  • США: 05/23/2026
  • Европа: 23/05/2026
  • Германия: 23.05.2026

Luxon автоматически подстраивает формат через Intl, без необходимости ручной конфигурации.


Использование локали в цепочках форматирования

Методы Luxon можно комбинировать, сохраняя локаль:

DateTime.now()
  .setLocale("ru")
  .setZone("Europe/Moscow")
  .toLocaleString(DateTime.DATETIME_FULL);

Локаль остаётся активной на всём протяжении цепочки и применяется на этапе финального форматирования.


Ограничения локализации Luxon

Несмотря на гибкость, локализация имеет ограничения, связанные с зависимостью от Intl:

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

Luxon не предоставляет собственного слоя исправления этих различий, полностью полагаясь на стандарт ECMAScript Internationalization API.