Языковые теги BCP 47

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

Языковой тег BCP 47 представляет собой стандартизированную строку, описывающую язык, письменность, регион и дополнительные особенности локализации. Его цель — однозначно идентифицировать культурно-языковую среду без двусмысленностей и разночтений между системами.

Основная структура тега строится по иерархии subtags:

language-script-region-variant-extension-privateuse

На практике не все элементы обязательны. Минимально допустимым считается двухбуквенный или трёхбуквенный код языка, например:

  • en — английский язык
  • fr — французский язык
  • ru — русский язык

Дальнейшее уточнение достигается добавлением региона:

  • en-US — английский (США)
  • en-GB — английский (Великобритания)
  • pt-BR — португальский (Бразилия)
  • pt-PT — португальский (Португалия)

Региональный компонент всегда отделяется дефисом и представляет собой либо двухбуквенный код страны по ISO 3166-1, либо числовой код UN M.49.

Следующий уровень детализации — письменность (script). Он используется, когда один язык может быть записан разными системами письма:

  • zh-Hans — китайский упрощённый
  • zh-Hant — китайский традиционный
  • sr-Cyrl — сербский кириллицей
  • sr-Latn — сербский латиницей

Порядок элементов фиксирован: сначала язык, затем письменность, затем регион. Например:

  • zh-Hans-CN — китайский, упрощённая письменность, Китай
  • az-Latn-AZ — азербайджанский, латиница, Азербайджан

BCP 47 допускает добавление вариативных под-тегов, которые описывают специфические особенности языка или его использования.

Variant subtags применяются для обозначения диалектов или исторических орфографий:

  • sl-rozaj — резьянский диалект словенского
  • de-1901 — немецкая орфография до реформы 1901 года

Варианты могут комбинироваться с другими уровнями:

  • sl-IT-rozaj — резьянский в контексте Италии
  • de-DE-1901 — немецкий (Германия) в исторической орфографии

Extensions используются для расширения стандарта дополнительными параметрами. Они начинаются с одиночной буквы (кроме x) и применяются для специфических систем локализации. Наиболее известное расширение — u (Unicode locale extensions).

Примеры:

  • en-US-u-ca-gregory — использование григорианского календаря
  • ar-EG-u-nu-latn — арабский (Египет) с латинскими цифрами

Расширения позволяют управлять не только языком, но и культурными параметрами форматирования: календарями, системами чисел, сортировкой.

Private-use subtags начинаются с x- и предназначены для внутренних соглашений:

  • en-x-custom — пользовательское расширение
  • ru-RU-x-test — локальная модификация русского языка

Нормализация и каноническая форма

BCP 47 определяет строгие правила записи:

  • язык пишется в нижнем регистре (en, ru, zh)
  • регион — в верхнем (US, GB, CN)
  • script — с заглавной буквы (Hans, Latn)
  • разделитель всегда дефис (-), а не подчёркивание

Таким образом:

  • корректно: zh-Hans-CN
  • некорректно: zh_hans_cn, ZH-hans-cn

Стандарт также допускает эквивалентные формы, которые могут быть приведены к каноническому виду через registry данных IANA Language Subtag Registry. Например:

  • iwhe (иврит)
  • inid (индонезийский)
  • jiyi (идиш)

Связь с системами локализации

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

Локаль в Globalize фактически соответствует BCP 47-тегу, например:

  • Globalize("en")
  • Globalize("fr-CA")
  • Globalize("zh-Hant-TW")

Несмотря на то, что библиотека может принимать укороченные формы, внутренне происходит нормализация и сопоставление с CLDR-наборами.

Иерархическая природа сопоставления

BCP 47 поддерживает принцип fallback: если точное совпадение локали отсутствует, система переходит к более общему варианту.

Пример цепочки:

  • en-US-POSIXen-USen

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

Комбинирование компонентов

Языковые теги могут образовывать сложные комбинации, отражающие реальную культурную ситуацию:

  • es-419 — испанский (Латинская Америка)
  • zh-Hans-SG — китайский упрощённый (Сингапур)
  • pt-MO — португальский (Макао)

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

Практическая значимость структуры

BCP 47 обеспечивает единый способ описания языковых сред в различных системах:

  • браузеры используют их для navigator.language
  • серверные фреймворки применяют для content negotiation
  • библиотеки интернационализации используют как ключ доступа к CLDR

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

Ограничения и неоднозначности

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

  • различие между en-GB и en-UK (второй вариант не является каноническим)
  • неоднозначность региональных тегов вроде es-ES и es-419
  • различия в script-тегах при отсутствии явного указания

Поэтому системы интернационализации обязаны не только принимать теги, но и корректно их интерпретировать в соответствии с регистрами CLDR.

Сопоставление с данными локализации

Каждый BCP 47-тег связывается с набором локализованных ресурсов:

  • форматы чисел (десятичные разделители, группировка)
  • правила плюрализации
  • форматы дат и времени
  • единицы измерения
  • правила сортировки строк

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