Метод formatToParts

Метод formatToParts() в семействах Intl.NumberFormat и Intl.DateTimeFormat возвращает не строку, а структурированное представление результата форматирования в виде массива объектов. Каждый объект описывает отдельный фрагмент итогового значения и содержит два ключевых поля: type и value. Такая модель позволяет работать с локализованным форматированием на уровне отдельных компонентов, а не готовой строки.


Результат работы formatToParts() представляет собой массив, где порядок элементов соответствует порядку символов в итоговой строке форматирования.

Каждый элемент имеет вид:

{ type: string, value: string }
  • type — тип фрагмента (например, integer, group, decimal, literal, month, year)
  • value — строковое представление части результата

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


Intl.NumberFormat.formatToParts

Метод Intl.NumberFormat.prototype.formatToParts() используется для разбиения числового форматирования на составные элементы.

Пример:

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

const parts = formatter.formatToParts(12345.67);
console.log(parts);

Результат:

[
  { type: 'currency', value: '$' },
  { type: 'integer', value: '12' },
  { type: 'group', value: ',' },
  { type: 'integer', value: '345' },
  { type: 'decimal', value: '.' },
  { type: 'fraction', value: '67' }
]

Основные типы частей

  • currency — символ валюты
  • integer — целая часть числа
  • fraction — дробная часть
  • decimal — десятичный разделитель
  • group — разделитель групп разрядов
  • plusSign / minusSign — знаки числа
  • percentSign — знак процента
  • unit — единицы измерения (в unit-формате)
  • literal — текстовые вставки, не зависящие от числа

Практическое применение NumberFormat.formatToParts

Подсветка отдельных частей числа

const formatter = new Intl.NumberFormat('ru-RU', {
  style: 'currency',
  currency: 'RUB'
});

const parts = formatter.formatToParts(987654.32);

const html = parts.map(part => {
  if (part.type === 'currency') {
    return `<span class="currency">${part.value}</span>`;
  }
  if (part.type === 'integer') {
    return `<span class="int">${part.value}</span>`;
  }
  if (part.type === 'fraction') {
    return `<span class="fraction">${part.value}</span>`;
  }
  return part.value;
}).join('');

Такой подход позволяет сохранять локализацию и при этом кастомизировать визуальное представление.

Локализационно корректные манипуляции

В отличие от разбиения строки через split, структура formatToParts() учитывает особенности локали:

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

Intl.DateTimeFormat.formatToParts

Метод Intl.DateTimeFormat.prototype.formatToParts() возвращает структурированное представление даты и времени.

Пример:

const formatter = new Intl.DateTimeFormat('en-GB', {
  dateStyle: 'full',
  timeStyle: 'long'
});

const parts = formatter.formatToParts(new Date());
console.log(parts);

Возможный результат:

[
  { type: 'weekday', value: 'Monday' },
  { type: 'literal', value: ', ' },
  { type: 'day', value: '26' },
  { type: 'literal', value: ' ' },
  { type: 'month', value: 'May' },
  { type: 'literal', value: ' ' },
  { type: 'year', value: '2026' },
  { type: 'literal', value: ' at ' },
  { type: 'hour', value: '14' },
  { type: 'literal', value: ':' },
  { type: 'minute', value: '05' }
]

Типы частей даты и времени

  • year — год
  • month — месяц
  • day — день месяца
  • weekday — день недели
  • hour — час
  • minute — минута
  • second — секунда
  • dayPeriod — утро/вечер (AM/PM или локализованный аналог)
  • timeZoneName — название временной зоны
  • era — эра (BC/AD или локальные аналоги)
  • literal — разделительные символы и текст

Управление отображением через formatToParts

Выделение отдельных компонентов даты

const formatter = new Intl.DateTimeFormat('ru-RU', {
  year: 'numeric',
  month: 'long',
  day: 'numeric'
});

const parts = formatter.formatToParts(new Date());

const result = parts.map(part => {
  if (part.type === 'day') {
    return `[${part.value}]`;
  }
  return part.value;
}).join('');

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


Различие между format и formatToParts

Обычный format() возвращает строку:

"12/31/2026"

formatToParts() возвращает структуру:

[
  { type: 'month', value: '12' },
  { type: 'literal', value: '/' },
  { type: 'day', value: '31' },
  { type: 'literal', value: '/' },
  { type: 'year', value: '2026' }
]

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


Поведение в разных локалях

Одна из особенностей formatToParts() — зависимость структуры от локали:

  • порядок частей может изменяться (например, день-месяц-год vs год-месяц-день)
  • наличие символов разделителей не гарантировано в фиксированном виде
  • формат валюты может включать пробелы, неразрывные пробелы или символы слева/справа

Это делает невозможным корректный парсинг форматированной строки без использования formatToParts().


Использование в пользовательских интерфейсах

Табличные данные

При отображении финансовых таблиц важно выравнивание по числовым частям:

const formatter = new Intl.NumberFormat('de-DE', {
  minimumFractionDigits: 2
});

const parts = formatter.formatToParts(1000000.5);

Далее можно отдельно стилизовать:

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

Графические интерфейсы с гибкой типографикой

В интерфейсах, где важна типографическая точность, formatToParts() позволяет:

  • отделять единицы измерения от чисел
  • управлять межсимвольными интервалами
  • вставлять дополнительные UI-элементы между частями (иконки, индикаторы)

Особенности реализации и ограничения

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

Комбинирование с другими API Intl

formatToParts() часто используется вместе с:

  • Intl.NumberFormat для финансовых и научных данных
  • Intl.DateTimeFormat для локализованных календарей и таймзон
  • Intl.RelativeTimeFormat косвенно, при ручной постобработке строк

При этом именно разбиение на части позволяет сохранять корректность локализации при дополнительной обработке результата.


Обработка результата как потоковой структуры

Массив частей можно рассматривать как поток токенов, где каждый элемент несёт семантический смысл:

  • тип определяет роль в формате
  • значение определяет визуальное представление

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