Работа с объектом Locale

Объект Intl.Locale представляет собой структурированное описание языковой локали и служит основой для унифицированной работы с языковыми настройками в ECMAScript Internationalization API. В отличие от строкового представления локали (например, "en-US"), экземпляр Intl.Locale позволяет обращаться к отдельным компонентам языка как к свойствам объекта и управлять ими через стандартизированные методы.

Локаль в контексте международной стандартизации описывается через BCP 47 language tags. Эти теги включают язык, регион, письменность, варианты и дополнительные расширения. Например: "en-Latn-US-u-ca-gregory-nu-latn"


При создании объекта Intl.Locale строка локали разбивается на компоненты:

  • language — основной язык (en, ru, zh)
  • script — система письма (Latn, Cyrl, Hans)
  • region — регион (US, GB, RU)
  • variants — дополнительные варианты диалекта или стандарта
  • extensions — расширения Unicode (u-ca-gregory, nu-latn)

Конструктор:

const locale = new Intl.Locale("en-Latn-US");

Каждая часть доступна через свойства объекта:

locale.language; // "en"
locale.script;    // "Latn"
locale.region;    // "US"

Нормализация и каноническое представление

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

new Intl.Locale("EN-us").toString();
// "en-US"

Метод toString() возвращает нормализованную строку локали, соответствующую стандарту Unicode LDML.


Уточнение локали через параметры конструктора

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

const locale = new Intl.Locale("en", {
  region: "GB",
  script: "Latn"
});

Результат:

locale.toString(); // "en-Latn-GB"

Поддерживаемые опции:

  • language
  • script
  • region
  • calendar
  • collation
  • numberingSystem
  • caseFirst
  • numeric
  • hourCycle

Расширения Unicode и параметры формата

Intl.Locale интегрируется с Unicode Extension Keys, которые управляют форматированием дат, чисел и текста.

Календарь

const locale = new Intl.Locale("ar-EG", {
  calendar: "islamic"
});

locale.calendar; // "islamic"

Система счисления

const locale = new Intl.Locale("hi-IN", {
  numberingSystem: "deva"
});

locale.numberingSystem; // "deva"

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

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

const locale = new Intl.Locale("fr");

locale.language; // "fr"
locale.region;    // undefined

При необходимости локаль может быть «расширена» через метод maximize():

const base = new Intl.Locale("zh");
const max = base.maximize();

max.toString();

Типичный результат:

"zh-Hans-CN"

Противоположная операция — minimize() — удаляет избыточные компоненты:

const locale = new Intl.Locale("zh-Hans-CN");
locale.minimize().toString(); // "zh"

Работа с часовой системой

Intl.Locale поддерживает настройку формата времени через hourCycle.

const locale = new Intl.Locale("en-US", {
  hourCycle: "h24"
});

locale.hourCycle; // "h24"

Основные значения:

  • h11 — 0–11 с привязкой к AM/PM
  • h12 — 1–12 с AM/PM
  • h23 — 0–23 без AM/PM
  • h24 — 1–24 без AM/PM

Поведение caseFirst и numeric

Эти параметры влияют на сортировку строк в Intl.Collator, но задаются на уровне локали.

const locale = new Intl.Locale("de-DE", {
  numeric: true,
  caseFirst: "upper"
});

locale.numeric;   // true
locale.caseFirst;  // "upper"
  • numeric: учитывает числовые части строк при сортировке
  • caseFirst: определяет приоритет регистра (upper, lower, false)

Связь с другими объектами Intl

Intl.Locale является фундаментом для других компонентов международного API:

  • Intl.NumberFormat использует локаль для форматирования чисел
  • Intl.DateTimeFormat опирается на календарь и часовой цикл
  • Intl.Collator использует правила сортировки, зависящие от локали
const locale = new Intl.Locale("fr-FR");

new Intl.NumberFormat(locale).format(123456.78);
new Intl.DateTimeFormat(locale).format(new Date());

Анализ строковой совместимости

Любая строка локали может быть преобразована в объект и обратно без потери информации, если она соответствует BCP 47.

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

const reconstructed = new Intl.Locale(locale.toString());

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


Извлечение базовой локали

Свойство baseName возвращает основную часть локали без расширений Unicode.

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

locale.baseName; // "en-US"

Это полезно при сравнении локалей без учета форматирующих параметров.


Иммутабельность объекта

Экземпляры Intl.Locale являются неизменяемыми. Любая модификация через методы maximize, minimize или повторный конструктор создаёт новый объект.

const a = new Intl.Locale("en-US");
const b = a.maximize();

a === b; // false

Такой подход гарантирует предсказуемость при использовании в функциональных цепочках и кэшировании.


Интероперабельность с пользовательскими настройками

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

const preferred = navigator.language;
const locale = new Intl.Locale(preferred);

Полученный объект позволяет извлечь структурированные данные вместо работы с сырой строкой.


Использование расширений Unicode для детализации

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

const locale = new Intl.Locale("en-US-u-nu-arab");
locale.numberingSystem; // "arab"

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


Роль в нормализации международных данных

Intl.Locale используется как промежуточный слой между пользовательским вводом и API форматирования. Он устраняет неоднозначность строковых представлений и обеспечивает единый формат интерпретации языковых параметров во всех объектах Intl.