Стандарты Unicode CLDR

Библиотека FormatJS опирается на стандарт Unicode CLDR (Common Locale Data Repository) — крупнейшее централизованное хранилище локализационных данных, поддерживаемое консорциумом Unicode. Именно CLDR определяет, как приложения должны отображать даты, числа, валюты, единицы измерения, имена языков, регионов и правила множественного числа для разных локалей.

FormatJS не изобретает собственные механизмы локализации. Вместо этого библиотека использует стандарты платформы ECMAScript Internationalization API (Intl), а сами данные и правила берутся из CLDR.


Что такое CLDR

CLDR представляет собой набор структурированных данных, описывающих особенности локалей:

  • форматы дат и времени;
  • валюты;
  • системы счисления;
  • правила pluralization;
  • локализованные названия стран;
  • форматы адресов;
  • правила сортировки;
  • единицы измерения;
  • особенности календарей;
  • текстовые шаблоны.

Пример различий между локалями:

Локаль Формат даты Разделитель дробной части
en-US 12/31/2025 .
de-DE 31.12.2025 ,
fr-FR 31/12/2025 ,
ja-JP 2025/12/31 .

Все эти различия определяются именно CLDR.


Архитектура взаимодействия FormatJS и CLDR

FormatJS работает поверх Intl.* API:

new Intl.DateTimeFormat('fr-FR')
new Intl.NumberFormat('de-DE')
new Intl.PluralRules('ru')

Движок JavaScript получает данные локализации из реализации ICU (International Components for Unicode), а ICU использует CLDR как источник данных.

Схема зависимости:

CLDR
  ↓
ICU
  ↓
Intl API
  ↓
FormatJS
  ↓
Приложение

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

  • CLDR содержит данные;
  • ICU реализует обработку;
  • Intl предоставляет API;
  • FormatJS добавляет удобный уровень abstractions.

Структура локалей в CLDR

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

language-Script-Region-Variant

Примеры:

Локаль Значение
en английский
en-US английский (США)
en-GB английский (Великобритания)
zh-Hans китайский упрощённый
zh-Hant китайский традиционный
sr-Cyrl сербский кириллица
sr-Latn сербский латиница

FormatJS полностью поддерживает BCP 47 locale identifiers, основанные на стандартах Unicode.


Определение локали в FormatJS

Наиболее часто локаль задаётся через IntlProvider.

import { IntlProvider } from 'react-intl'

<IntlProvider locale="ru">
  <App />
</IntlProvider>

Внутри:

  • locale="ru" активирует русские правила CLDR;
  • все formatter-объекты начинают использовать русские стандарты;
  • pluralization переключается на русские формы;
  • даты форматируются согласно российским нормам.

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

CLDR определяет:

  • разделители тысяч;
  • десятичные разделители;
  • позицию валюты;
  • способы округления;
  • компактные записи чисел.

Пример

new Intl.NumberFormat('en-US').format(1234567.89)

Результат:

1,234,567.89

Для немецкой локали:

new Intl.NumberFormat('de-DE').format(1234567.89)

Результат:

1.234.567,89

Разница полностью определяется CLDR.


Валютные форматы

CLDR содержит:

  • символы валют;
  • позиции валют;
  • правила округления;
  • локализованные названия валют.

Пример в FormatJS

intl.formatNumber(1000, {
  style: 'currency',
  currency: 'USD'
})

Для en-US:

$1,000.00

Для fr-FR:

1 000,00 $US

Для ja-JP:

US$1,000.00

Compact Number Formatting

CLDR содержит сокращённые формы записи больших чисел.

Пример

intl.formatNumber(1200000, {
  notation: 'compact'
})

Для английского:

1.2M

Для русского:

1,2 млн

Для японского:

120万

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

CLDR хранит:

  • порядок компонентов даты;
  • названия месяцев;
  • названия дней недели;
  • правила 12/24-часового времени;
  • шаблоны long/short/full.

Пример

intl.formatDate(new Date(), {
  dateStyle: 'full'
})

Для en-US:

Thursday, May 28, 2026

Для ru-RU:

четверг, 28 мая 2026 г.

Для ar-EG:

الخميس، ٢٨ مايو ٢٠٢٦

Локализованные календари

CLDR поддерживает множество календарных систем:

  • Gregorian;
  • Buddhist;
  • Islamic;
  • Japanese;
  • Persian;
  • Hebrew.

Пример

new Intl.DateTimeFormat('ja-JP-u-ca-japanese')

Результат:

R8/05/28

Используется японская эра вместо григорианского года.


Правила множественного числа

Plural Rules — одна из важнейших частей CLDR.

Разные языки имеют разные категории:

Язык Категории
English one, other
Russian one, few, many, other
Arabic zero, one, two, few, many, other

Русские plural rules

Русский язык имеет сложную систему:

Число Категория
1 one
2 few
5 many
21 one
32 few
100 many

FormatJS использует эти правила автоматически.

Пример

intl.formatMessage(
  {
    defaultMessage:
      '{count, plural, one {# файл} few {# файла} many {# файлов} other {# файла}}'
  },
  { count: 5 }
)

Результат:

5 файлов

ICU Message Syntax и CLDR

FormatJS использует ICU MessageFormat.

Pluralization напрямую связана с CLDR:

{
  count,
  plural,
  one {# item}
  other {# items}
}

Для русского:

{
  count,
  plural,
  one {# комментарий}
  few {# комментария}
  many {# комментариев}
  other {# комментария}
}

Категории pluralization

CLDR определяет следующие категории:

Категория Назначение
zero ноль
one единственное
two двойственное
few несколько
many много
other остальные

Не все языки используют все категории.


SelectFormat и CLDR

CLDR также поддерживает grammatical selection.

Пример

{
  gender,
  select,
  male {Он}
  female {Она}
  other {Они}
}

FormatJS использует эти конструкции через ICU MessageFormat.


Relative Time Formatting

CLDR содержит шаблоны относительного времени.

Пример

intl.formatRelativeTime(-1, 'day')

Для английского:

1 day ago

Для русского:

1 день назад

Для французского:

il y a 1 jour

Форматирование единиц измерения

CLDR описывает:

  • сокращения;
  • множественные формы;
  • локальные обозначения.

Пример

intl.formatNumber(5, {
  style: 'unit',
  unit: 'kilometer'
})

Для английского:

5 km

Для русского:

5 км

Локализованные списки

CLDR содержит правила соединения списков.

Пример

new Intl.ListFormat('en').format([
  'JavaScript',
  'TypeScript',
  'Rust'
])

Результат:

JavaScript, TypeScript, and Rust

Для русского:

JavaScript, TypeScript и Rust

Display Names

CLDR хранит локализованные имена:

  • языков;
  • стран;
  • валют;
  • регионов.

Пример

new Intl.DisplayNames(['ru'], {
  type: 'region'
}).of('US')

Результат:

Соединённые Штаты

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

CLDR поддерживает различные numeral systems.

Пример арабской локали

new Intl.NumberFormat('ar-EG').format(123456)

Результат:

١٢٣٬٤٥٦

Используются арабские цифры Unicode.


Directionality и RTL-языки

CLDR содержит информацию о направлении текста.

RTL-языки:

  • Arabic;
  • Hebrew;
  • Persian.

FormatJS сам не управляет layout, однако корректно форматирует текст для RTL-локалей через Unicode bidi algorithm.


Fallback Locale Mechanism

Если локаль отсутствует, применяется fallback.

Пример

<IntlProvider
  locale="fr-CA"
  defaultLocale="en"
>

Fallback-цепочка:

fr-CA → fr → en

CLDR определяет inheritance между локалями.


Locale Matching

Intl API использует locale negotiation.

Пример

navigator.languages

Может вернуть:

['ru-KZ', 'ru', 'en-US']

Далее выбирается наиболее подходящая локаль.


likelySubtags в CLDR

CLDR содержит likely subtags.

Например:

en → en-Latn-US
zh → zh-Hans-CN
sr → sr-Cyrl-RS

Это помогает движкам правильно определять:

  • регион;
  • систему письма;
  • fallback.

Locale Canonicalization

CLDR стандартизирует locale identifiers.

Пример

Intl.getCanonicalLocales('EN_us')

Результат:

['en-US']

Time Zone Data

CLDR содержит:

  • локализованные имена таймзон;
  • short/long варианты;
  • city-based labels.

Пример

intl.formatDate(new Date(), {
  timeZone: 'Europe/Paris',
  timeStyle: 'long'
})

Unicode Extensions

BCP 47 поддерживает расширения Unicode.

Примеры

en-US-u-ca-buddhist

Буддийский календарь.

de-DE-u-nu-latn

Латинские цифры.

ar-EG-u-nu-arab

Арабские цифры.


Polyfills и CLDR

Старые браузеры могут не поддерживать часть Intl API.

FormatJS предоставляет polyfills:

@formatjs/intl-pluralrules
@formatjs/intl-relativetimeformat
@formatjs/intl-displaynames

Polyfills включают данные CLDR.


Размер CLDR-данных

Полный набор CLDR очень большой. Поэтому FormatJS позволяет:

  • подключать только нужные локали;
  • загружать locale data динамически;
  • выполнять code splitting.

Пример

import '@formatjs/intl-pluralrules/locale-data/ru'

Минимизация bundle size

Для production обычно:

  • загружается только активная локаль;
  • lazy loading выполняется по требованию;
  • locale chunks разделяются webpack/vite.

Пример динамической загрузки

await import(
  '@formatjs/intl-relativetimeformat/locale-data/ru'
)

Обновления CLDR

Unicode регулярно выпускает новые версии CLDR.

Обновления включают:

  • новые валюты;
  • изменения геополитических названий;
  • исправления plural rules;
  • новые единицы измерения;
  • изменения таймзон.

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


Ограничения CLDR

CLDR не решает:

  • перевод текстов;
  • контекстную грамматику;
  • стилистические различия;
  • особенности tone of voice.

CLDR отвечает исключительно за стандартизированные локализационные данные.


ICU и CLDR: различия

Частая ошибка — путать ICU и CLDR.

Система Назначение
CLDR данные
ICU библиотека обработки
Intl API JavaScript API
FormatJS high-level abstraction

Поддержка нестандартных локалей

Некоторые локали могут отсутствовать в среде выполнения.

Пример Node.js

Минимальные сборки Node могут не содержать full ICU data.

Проверка:

Intl.DateTimeFormat.supportedLocalesOf([
  'ru',
  'ar',
  'zh'
])

Full ICU в Node.js

Для полноценной интернационализации Node.js часто запускается с full ICU.

Пример:

node --icu-data-dir=node_modules/full-icu

Проверка plural categories

Можно исследовать правила локали напрямую.

Пример

new Intl.PluralRules('ru').select(5)

Результат:

many

Диагностика локали

FormatJS и Intl позволяют определить активную локаль.

Пример

new Intl.NumberFormat().resolvedOptions()

Результат:

{
  locale: 'ru-RU',
  numberingSystem: 'latn',
  style: 'decimal'
}

Особенности азиатских локалей

CLDR содержит уникальные правила для:

  • китайского;
  • японского;
  • корейского.

Пример compact notation

Японский:

1万

Китайский:

1万

Английский:

10K

Лингвистическая сложность славянских языков

Славянские локали особенно зависят от CLDR:

  • сложные plural rules;
  • падежные формы;
  • контекстные изменения слов.

Русский, польский, украинский и чешский используют разные pluralization rules.


Влияние CLDR на UX

Корректная локализация влияет на:

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

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


Практическая роль CLDR в FormatJS

Практически каждая операция FormatJS использует CLDR косвенно:

Возможность Зависимость от CLDR
formatDate шаблоны дат
formatNumber числа и валюты
formatRelativeTime relative patterns
plural plural rules
DisplayNames локализованные названия
ListFormat правила списков
unit formatting единицы измерения

Без CLDR современная интернационализация JavaScript-приложений была бы невозможна.