ADR-UI-015. Локализация и форматы
Целевая аудитория — российские библиотеки; весь интерфейс русский. Фиксируем: русский —
единственный язык (без i18n-инфраструктуры), единые форматы дат/времени/чисел по локали ru и единую
точку форматирования — встроенные пайпы Angular и общий пайп даты, без ручного форматирования в компонентах.
1. Контекст и постановка задачи
Система адресована российским библиотечным сетям — все тексты, а также форматы дат, времени и чисел должны быть русскими. Поддержка других языков сейчас не требуется.
Нужно зафиксировать два решения, чтобы они не выбирались заново в каждой задаче:
- Уровень локализации — заводим ли мы i18n-инфраструктуру (словари переводов,
@angular/localize) или обходимся одним языком напрямую. - Единая точка форматирования — где и как форматируются даты и числа, чтобы вид был одинаков во всём приложении, а компоненты не форматировали значения «руками».
Повод — вывод значения-даты (ISO yyyy-mm-dd) в человеко-читаемом виде.
2. Драйверы решения
- Соответствие спеке — вся спецификация и все интерфейсные тексты на русском.
- Минимум абстракций — не тащить словари переводов и
@angular/localizeпод единственный язык. - Единообразие форматов — даты, время, числа выглядят одинаково на всех экранах.
- Одна точка форматирования — никаких локальных форматтеров, разъезжающихся по компонентам.
3. Рассмотренные варианты
- A. Только русский, без i18n-инфраструктуры — строки пишутся прямо на русском в шаблонах и
коде; локаль
ruзадаётся один раз; форматирование — через локаль-зависимые пайпы. - B.
@angular/localizeс единственной локальюru— заранее обернуть весь текст вi18n, «на будущее». - C. Свой словарь переводов (json + сервис) — то же, что B, но вручную.
4. Решение
Выбран Вариант A. Все строки UI — прямо на русском в шаблонах и коде, без i18n-обёрток и
словарей. Мультиязычности нет.
4.1. Регистрация локали (app.config.ts)
Локаль ru регистрируется один раз и задаётся как LOCALE_ID — на неё опираются встроенные
пайпы (date, number, currency) и наши форматтеры:
import { registerLocaleData } from '@angular/common';
import localeRu from '@angular/common/locales/ru';
import { LOCALE_ID } from '@angular/core';
registerLocaleData(localeRu);
providers: [
{ provide: LOCALE_ID, useValue: 'ru' },
// ...
]
4.2. Фиксируемые форматы
| Аспект | Значение |
|---|---|
| Язык интерфейса | Русский (ru). |
| Формат даты | дд.мм.гггг (dd.MM.yyyy). |
| Формат даты-времени | дд.мм.гггг чч:мм (dd.MM.yyyy HH:mm). |
| Десятичный разделитель | запятая. |
| Разделитель тысяч | неразрывный пробел. |
| Первый день недели | понедельник. |
| Часовой пояс | локальный, пользовательский. |
| Валюта по умолчанию | RUB (если появится вывод сумм). |
4.3. Единая точка форматирования
- Числа, суммы, «широкие» даты — встроенные пайпы Angular (
number,currency,date), работающие поLOCALE_ID = 'ru'. - Доменные значения-даты приходят и хранятся как ISO-строка
yyyy-mm-dd(машинный формат обмена с API). Для их показа — общий пайпicdDate(ui/pipes): режимыdate/datetime, локальru. Пайп разбирает ISO-дату как локальную (полночь по месту), чтобы дата не «съезжала» на день при отрицательном смещении пояса. - Собственные компоненты набора (
icd-date-pickerи др.) форматируют вывод и подписи календаря черезIntlс локальюru: понедельник — первый день недели, названия месяцев русские. - Компоненты не форматируют даты/числа вручную (ни
padStart-склейкой, ни локальными функциями) — только через пайпы/Intl-форматтеры выше.
4.4. Тексты и ошибки
- Тексты пишем на русском прямо в шаблонах и коде, без оборачивания.
- Текст ошибок API формирует бэкенд (на русском); UI не переводит коды ошибок в строки.
5. Положительные следствия
- Нет лишнего слоя i18n в приложении на одном языке — меньше кода и зависимостей.
- Тексты живут рядом с UI — проще читать и менять, чище diff.
- Даты и числа выглядят одинаково везде: один
LOCALE_ID, один пайп даты.
6. Отрицательные следствия и компромиссы
- При появлении требования мультиязычности тексты придётся извлекать вручную — решается
миграцией на
@angular/localizeв тот момент (тогда же — отдельный ADR, этот получит статусSuperseded).
7. Проверка
- Даты в UI отображаются как
дд.мм.гггг(дата-время —дд.мм.гггг чч:мм). - Календарь
icd-date-picker: первый день недели — понедельник, месяцы по-русски. - В компонентах нет ручного форматирования дат/чисел — только пайпы/
Intl. - ISO-дата
yyyy-mm-ddпоказывается тем же днём независимо от часового пояса.
8. Открытые вопросы / отложено
- Вывод денежных сумм — формат RUB зафиксирован, но появится вместе с первым экраном сумм.
- Мультиязычность — отдельный ADR при появлении требования.