Валидация локалей

Локаль в JavaScript-экосистеме Globalize представляется строкой, описывающей язык и региональные особенности форматирования: даты, чисел, валют, единиц измерения. Типичный формат включает язык, регион, а иногда и расширенные теги: ru, ru-RU, en-US, zh-Hans-CN. Корректность локали не сводится к синтаксической проверке строки — важна её согласованность с загруженными данными CLDR (Common Locale Data Repository), на которых основан Globalize.

Строка локали состоит из нескольких компонентов:

  • Язык: ISO 639 (ru, en, de)
  • Регион: ISO 3166 (RU, US, DE)
  • Письменность (script): Hans, Hant, Latn
  • Варианты: дополнительные модификаторы

Комбинации формируют иерархию:

  • en — общий английский
  • en-GB — британский вариант
  • en-US — американский вариант
  • zh-Hans-CN — упрощённый китайский для Китая

Globalize не ограничивается проверкой формата строки. Локаль считается валидной только в контексте доступных CLDR-данных и механизма разрешения локалей.

Зависимость валидации от CLDR

Globalize полностью опирается на CLDR, и без загруженных данных любая операция с локалями становится неполноценной.

Для корректной работы обычно загружаются:

  • cldr/supplemental/likelySubtags
  • cldr/supplemental/numberingSystems
  • cldr/main/<locale>/numbers
  • cldr/main/<locale>/ca-gregorian
  • cldr/supplemental/timeData

Отсутствие даже части этих данных приводит к тому, что локаль может быть технически установлена, но не сможет корректно форматировать данные.

Разрешение и нормализация локали

При установке локали Globalize выполняет нормализацию:

  • приводит код к каноническому виду
  • применяет likely subtags
  • расширяет неполные идентификаторы

Например:

  • ru может быть расширено до ru-Latn-RU или ru-RU в зависимости от CLDR likely subtags
  • en может стать en-Latn-US

Этот процесс делает «валидацию» не бинарной (да/нет), а контекстной: валидность определяется тем, можно ли локаль однозначно разрешить.

Установка локали и проверка доступности

Основной механизм работы с локалью — функция установки текущего контекста:

Globalize.locale("ru-RU");

При этом библиотека:

  1. Проверяет наличие CLDR данных для данной локали
  2. Применяет likely subtags
  3. Сохраняет результат как текущую локаль контекста

Если данные для локали отсутствуют, Globalize не всегда выбрасывает ошибку — вместо этого может произойти fallback на более общий язык или ранее установленную локаль. Это делает явную «валидацию» локали задачей разработчика, а не встроенного механизма.

Подход к валидации локалей

Так как Globalize не предоставляет строгой функции вида isValidLocale, проверка корректности строится косвенно:

1. Проверка наличия CLDR-данных

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

  • проверка наличия cldr/main/<locale>
  • проверка supplemental-данных

Если данные отсутствуют, любые операции форматирования будут некорректны.

2. Попытка установки локали

Практический способ проверки — установка локали и тестирование результата форматирования:

  • если форматирование чисел/дат работает без ошибок — локаль поддерживается
  • если происходят fallback-значения или ошибки данных — локаль неполная

3. Проверка через список загруженных локалей

В приложениях часто ведётся реестр загруженных локалей:

  • ["en", "en-GB", "ru", "de"]

Валидация сводится к проверке принадлежности строки к этому списку.

Канонизация и сравнение локалей

При сравнении локалей важно учитывать, что одинаковый смысл может иметь разные записи:

  • en-US и en-us (регистр не имеет значения)
  • zh-CN и zh-Hans-CN (разные уровни детализации)

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

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

Fallback-механизм и его влияние на валидность

Одной из ключевых особенностей является автоматический fallback:

  • fr-CAfr
  • es-MXes

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

Поэтому валидация должна учитывать не только факт существования локали, но и уровень точности:

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

Практическая модель валидации

В реальных приложениях проверка локали в контексте Globalize обычно строится по следующей схеме:

  • локаль проходит синтаксическую проверку (ISO формат)
  • проверяется наличие соответствующих CLDR main-данных
  • выполняется проверка через установку Globalize.locale
  • проводится тестовое форматирование числа или даты
  • фиксируется уровень fallback

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

Особенности работы с составными локалями

Сложные локали с script и variant требуют особого внимания:

  • sr-Cyrl-RS (сербский, кириллица, Сербия)
  • az-Latn-AZ (азербайджанский, латиница)

Если отсутствует поддержка script-уровня, Globalize может:

  • игнорировать script
  • переключаться на базовый язык
  • использовать likelySubtags для восстановления

Это напрямую влияет на то, считается ли локаль «валидной» в прикладном смысле.

Ограничения модели валидации

Валидация локалей в Globalize не является централизованной функцией, потому что:

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

Поэтому одна и та же локаль может считаться валидной в одном окружении и невалидной в другом.

Роль likelySubtags в определении валидности

likelySubtags — ключевой механизм, который расширяет неполные локали до максимально конкретных:

  • enen-Latn-US
  • ruru-Cyrl-RU

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

Итоговая модель интерпретации локали

В контексте Globalize локаль нельзя рассматривать как просто строку, соответствующую шаблону. Это динамическая ссылка на набор CLDR-данных, которая:

  • нормализуется через likelySubtags
  • проверяется через наличие ресурсов
  • может деградировать через fallback
  • зависит от загруженного окружения

Валидация локалей становится не отдельной функцией, а результатом взаимодействия структуры строки, доступных данных и механизмов разрешения CLDR.