Задайте питання та отримайте підсумок документа, вказавши цю сторінку та обраного вами постачальника штучного інтелекту
Вміст цієї сторінки перекладено за допомогою штучного інтелекту.
Переглянути останню версію оригінального вмісту англійськоюЯкщо у вас є ідея щодо покращення цієї документації, будь ласка, долучіться, надіславши pull request на GitHub.
Посилання на документацію на GitHubСкопіювати документацію у форматі Markdown в буфер обміну
Форматування дат і чисел за локалями за допомогою Intl
Переклад текстових рядків — це лише видима половина інтернаціоналізації (i18n). Інша половина, яка регулярно генерує звіти про помилки, це форматування: німецький користувач бачить 1,234.56 замість 1.234,56, японський користувач бачить 08/02/2026 і сприймає це як серпень, або дата по-різному рендериться на сервері та клієнті, спричиняючи помилку гідратації в React.
Жодна з цих ситуацій не вимагає сторонніх бібліотек. Стандартний Intl присутній у кожному сучасному середовищі виконання JavaScript.
Зміст
Почніть із видалення самописних хелперів для дат
Майже в кожній кодовій базі є функція formatDate, написана ще до того, як хтось задумався про підтримку локалей. Вона жорстко фіксує порядок відображення, роздільник і переважно англійські назви місяців.
Скопіюйте код у буфер обміну
Intl.DateTimeFormat повністю замінює її та забезпечує коректний результат для будь-якої локалі:
Скопіюйте код у буфер обміну
Те саме стосується чисел. Виклик toFixed(2) повсюдно повертає 1234.56, що є неправильним для більшості країн Європи.
Що охоплює Intl
Відкрийте таблицю в модальному вікні, щоб чітко переглянути всі дані
| API | Сфера застосування |
|---|---|
Intl.DateTimeFormat | Дати та час із готовими пресетами dateStyle / timeStyle |
Intl.NumberFormat | Десяткові дроби, валюти, відсотки, одиниці, компактний запис |
Intl.RelativeTimeFormat | "3 дні тому", "через 2 години" |
Intl.ListFormat | "а, б і в" згідно з граматикою мови |
Intl.PluralRules | Визначення граматичної категорії множини для чисел |
Intl.Collator | Коректне алфавітне сортування рядків з урахуванням мови |
Intl.Collator часто несправедливо забувають. Звичайний array.sort() на рядках сортує за кодовими точками Unicode, через що літери з діакритикою опиняються після літери z, а шведська ö потрапляє не на своє місце. Якщо ви сортуєте видимі користувачам списки, завжди використовуйте collator.
Скопіюйте код у буфер обміну
Віддавайте перевагу пресетам замість ручного збирання параметрів
Параметри dateStyle та timeStyle дозволяють самій локалі визначити прийнятний порядок полів та роздільники. Ручне вказування year, month та day надає контроль, якого краще уникати, оскільки правильний порядок змінюється залежно від регіону, і ви ризикуєте замінити дані CLDR власними хибними припущеннями.
Скопіюйте код у буфер обміну
Задавайте складові явно лише тоді, коли дизайн безапеляційно вимагає фіксованої ширини, наприклад у вузькій колонці таблиці.
Створення форматерів є ресурсомістким
Це ключовий нюанс продуктивності. Ініціалізація Intl.NumberFormat супроводжується завантаженням значного обсягу даних локалі, і цей процес набагато важчий за наступний виклик .format(). Виконання цієї операції всередині циклу рендерингу на тисячу рядків спричиняє відчутні затримки.
Скопіюйте код у буфер обміну
Функції toLocaleDateString() та toLocaleString() містять ту саму приховану ваду: кожен виклик створює новий форматер. Вони підходять для поодиноких випадків, але непридатні для списків.
Кешуйте форматери за комбінацією локалі та набору опцій:
Скопіюйте код у буфер обміну
Баг із часовим поясом, що проявляється лише в продакшені
Ця проблема забрала чимало годин у багатьох команд. Сервер формує дату під час SSR, браузер виконує гідратацію на клієнті, і React аварійно завершує роботу через помилку hydration mismatch, оскільки два середовища згенерували різний текст.
Причина: Intl.DateTimeFormat використовує системний часовий пояс хоста, якщо ви не передали його явно. Сервер продакшену налаштовано на UTC, а комп'ютер розробника — на локальний пояс. Тому локально помилка не відтворюється і проявляється лише після викатки.
Скопіюйте код у буфер обміну
Три робочі підходи:
- Зафіксувати часовий пояс на сервері та передавати його явно. Надійно та передбачувано, але всі бачать час у форматі UTC.
- Рендерити виключно на клієнті, показуючи нейтральний плейсхолдер під час SSR. Точно для кожного користувача, але викликає легке мерехтіння.
- Зберігати часовий пояс користувача і передавати його на сервер та клієнт. Найкращий досвід, що вимагає дещо більше інфраструктурного коду.
Хоч би який шлях ви обрали, завжди вказуйте timeZone явно для будь-якої дати, яка рендериться і на сервері, і на клієнті. Дата без зазначеного поясу — це дата з двома різними значеннями.
Валюта потребує коду валюти, а не локалі
Локаль і валюта — незалежні речі. fr-FR не означає автоматично розрахунки в євро: французький користувач може переглядати інвойс у доларах США.
Скопіюйте код у буфер обміну
Локаль відповідає за роздільники, групування цифр та розміщення символу. Валюта береться з бізнес-даних операції. Спроба вивести одне з іншого призводить до бухгалтерських помилок.
Зверніть увагу на параметр currencyDisplay. В інтерфейсах, де сусідують різні валюти зі знаком долара ($), значення "code" знімає будь-яку неоднозначність між американськими, канадськими та австралійськими доларами.
Відносний час сприймається легше за точну дату
Для недавніх дій формулювання "2 години тому" набагато зручніше за сухий часовий штамп, і Intl.RelativeTimeFormat якісно це локалізує.
Скопіюйте код у буфер обміну
Параметр numeric: "auto" забезпечує виведення "учора" замість неприродного "1 день тому".
Що додає Intlayer
Intlayer загортає ці можливості у легкі хелпери з автоматичним кешуванням, звільняючи від ручного контролю над Map, та автоматично застосовує активну локаль без потреби передавати її на кожному кроці.
Скопіюйте код у буфер обміну
Функція date() також підтримує пресети ("short", "long", "dateOnly", "timeOnly", "full"). Для React та Vue доступні хуки й composables, які дістають активну локаль безпосередньо з контексту.
Це зручний прошарок кешування та підтримки локалі за замовчуванням над стандартним API платформи. Сама поведінка форматування повністю спирається на Intl. Докладні сигнатури доступні в документації форматерів.
Поширені помилки
- Виклик
toLocaleDateString()без вказування локалі. Використовує локаль середовища хоста, яка на сервері залежить від контейнера. - Форматування в циклі без кешування. Створення форматера споживає більшість процесорного часу.
- Відсутність
timeZoneна ізоморфних датах. Провокує помилки гідратації, які неможливо виявити локально. - Виведення валюти з коду мови.
fr-FRне гарантує використання євро. - Звичайний
sort()для видимого тексту. Завжди використовуйтеIntl.Collator. - Ручний хардкод назв місяців чи днів. Усі вони вже зібрані в CLDR для кожної мови.
- Залишення
numeric: "always"для відносного часу. Призводить до "1 день тому" там, де є природне слово учора.
Корисні матеріали
- Форматери та утиліти локалей:
number,currency,date,relativeTime,list - Довідник конфігурації
- Звіти про продуктивність фреймворків
- Адаптер сумісності react-intl
- Формат повідомлень ICU: множина, вибір та чисельні шаблони
- Як тестувати переклади, включно з форматерами та множиною
- Що насправді охоплює інтернаціоналізація
Коментарі
Поки що немає коментарів. Будьте першим, хто поділиться своїми думками.
