Получение информации о локали

Локаль в JavaScript задаётся строкой в формате BCP 47, описывающей язык, регион, письменность и дополнительные параметры форматирования. Примеры: ru, ru-RU, en-US, zh-Hans-CN.

BCP 47 теги состоят из компонентов:

  • язык (ru, en, fr)
  • скрипт (письменность) (Hans, Hant, Latn)
  • регион (RU, US, CN)
  • варианты и расширения (например, u-nu-latn)

Получение текущей локали окружения

Среда выполнения предоставляет базовую информацию о предпочтениях пользователя через объект navigator.

Основной язык интерфейса пользователя:

navigator.language

Возвращает строку, например:

  • ru-RU
  • en-US

Особенности:

  • отражает главный язык системы или браузера
  • не гарантирует полный список предпочтений
  • используется как значение по умолчанию во многих Intl API

Список предпочтительных языков в порядке приоритета:

navigator.languages

Пример результата:

["ru-RU", "ru", "en-US", "en"]

Ключевые свойства:

  • порядок имеет значение (первый — наиболее приоритетный)
  • используется для выбора лучшей локали при форматировании
  • влияет на алгоритм сопоставления локалей (locale matching)

Нормализация локалей

Строки локалей могут иметь разные формы записи. Для приведения к каноническому виду используется:

Intl.getCanonicalLocales

Intl.getCanonicalLocales("ru-ru")

Результат:

["ru-RU"]

Назначение:

  • приведение локали к стандарту BCP 47
  • удаление неоднозначностей
  • проверка корректности строки локали

Каноническая локаль и её структура

Каноническая локаль представляет собой нормализованную BCP 47 строку, где:

  • регистр унифицирован (ru-RU, а не ru-ru)
  • расширения упорядочены
  • применены стандартные подстановки

Intl.Locale: объектная модель локали

Intl.Locale предоставляет структурированный доступ к компонентам локали.

Создание объекта локали

const locale = new Intl.Locale("ru-RU");

Основные свойства Intl.Locale

language

Базовый язык:

locale.language
// "ru"

region

Регион:

locale.region
// "RU"

script

Письменность (если указана):

const l = new Intl.Locale("zh-Hans-CN");
l.script
// "Hans"

baseName

Базовая часть без расширений:

const l = new Intl.Locale("en-US-u-ca-buddhist");
l.baseName
// "en-US"

Расширенные параметры локали

numberingSystem

Система чисел:

const l = new Intl.Locale("ar-EG-u-nu-arab");
l.numberingSystem
// "arab"

calendar

Календарная система:

const l = new Intl.Locale("ja-JP-u-ca-japanese");
l.calendar
// "japanese"

hourCycle

Формат времени:

const l = new Intl.Locale("en-US-u-hc-h23");
l.hourCycle
// "h23"

numeric

Поддержка числовой сортировки:

const l = new Intl.Locale("de-DE-u-kn-true");
l.numeric
// true

caseFirst

Приоритет регистра при сортировке:

const l = new Intl.Locale("en-US-u-kf-upper");
l.caseFirst
// "upper"

Определение фактически используемой локали в Intl API

Многие форматтеры возвращают не только результат форматирования, но и фактически выбранную локаль.


Intl.DateTimeFormat.resolvedOptions

const dtf = new Intl.DateTimeFormat(["fr-FR", "en-US"]);
dtf.resolvedOptions().locale

Результат:

"fr-FR"

Смысл:

  • отображает локаль, выбранную движком после сопоставления
  • учитывает доступные локали среды выполнения

Intl.NumberFormat.resolvedOptions

const nf = new Intl.NumberFormat(["de-DE", "en-US"]);
nf.resolvedOptions().locale

Intl.Collator.resolvedOptions

const collator = new Intl.Collator(["ja-JP", "en-US"]);
collator.resolvedOptions().locale

Алгоритм выбора локали (locale matching)

При передаче массива локалей Intl API выполняет сопоставление:

  1. Проверка полной поддержки (ru-RU)
  2. Переход к базовой локали (ru)
  3. Использование fallback (en-US или системной локали)

Поддерживаемые локали

Intl.supportedLocalesOf

Позволяет определить, какие локали поддерживаются движком:

Intl.supportedLocalesOf(["ru-RU", "xx-YY", "en-US"])

Результат может быть:

["ru-RU", "en-US"]

Назначение:

  • фильтрация неподдерживаемых локалей
  • предотвращение неявных fallback-значений

Расширения Unicode в локалях

Локали могут включать расширения u-, влияющие на форматирование.

Примеры:

en-US-u-ca-buddhist
de-DE-u-nu-latn
ja-JP-u-hc-h12

Категории расширений:

  • ca — календарь
  • nu — система чисел
  • hc — цикл часов
  • kf — сортировка по регистру
  • kn — числовая сортировка

Нормализация и разбор локали через Intl.Locale

Созданный объект позволяет разложить строку локали на компоненты без ручного парсинга:

const locale = new Intl.Locale("sr-Cyrl-RS-u-nu-latn");

locale.language;   // "sr"
locale.script;     // "Cyrl"
locale.region;     // "RS"
locale.numberingSystem; // "latn"

Отличие канонической локали от пользовательского ввода

Пользовательские строки локали могут быть:

  • в нижнем регистре (ru-ru)
  • неполными (ru)
  • с ошибками (en_us, EN-us)

Канонизация приводит их к единому виду:

Intl.getCanonicalLocales("EN-us")

Результат:

["en-US"]

Поведение fallback-цепочек

При отсутствии точного совпадения локали происходит последовательное упрощение:

  1. fr-CA-u-ca-buddhist
  2. fr-CA
  3. fr
  4. системная локаль

Влияние локали на Intl API

Локаль определяет:

  • формат дат и времени
  • правила сортировки строк
  • формат чисел и валют
  • календарные системы
  • правила округления и отображения

Каждый форматтер фиксирует выбранную локаль через resolvedOptions(), что позволяет анализировать реальное поведение движка.


Сравнение локалей и их сопоставление

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

Локаль A Локаль B Совместимость
ru-RU ru да
en-US en-GB частично
zh-Hans zh да

Роль системной локали

Если явная локаль не передана, используется системная:

new Intl.DateTimeFormat().resolvedOptions().locale

Она зависит от:

  • ОС
  • настроек браузера
  • языковых предпочтений пользователя