Ошибки парсинга

Парсинг в Globalize опирается на данные CLDR (Unicode Common Locale Data Repository) и строго следует локальным правилам представления чисел, дат и валют. Ошибки возникают не как исключения в классическом смысле, а как результат несоответствия входной строки ожидаемому формату конкретной локали.

Ключевая особенность: большинство функций парсинга не выбрасывают исключения, а возвращают NaN, null или некорректно интерпретированные значения. Это требует отдельного подхода к диагностике и обработке ошибок.


Ошибки парсинга чисел

Несоответствие локальному формату

Каждая локаль определяет собственные символы разделителей:

  • десятичный разделитель (. или ,)
  • разделитель тысяч (пробел, неразрывный пробел, точка)
  • набор допустимых цифр (в некоторых локалях — не латинские символы)

Пример ошибки:

Globalize.locale("de");

Globalize.parseNumber("1,234.56");
// результат: NaN

В немецкой локали:

  • , — десятичный разделитель
  • . — разделитель тысяч

Корректная строка:

Globalize.parseNumber("1.234,56");
// 1234.56

Неразрывные пробелы и скрытые символы

CLDR активно использует неразрывные пробелы (\u00A0) как разделители тысяч. Обычный пробел приводит к ошибке.

Globalize.locale("fr");

Globalize.parseNumber("1 234,56");
// NaN (обычный пробел)

Globalize.parseNumber("1\u00A0234,56");
// 1234.56

Ошибка часто возникает при копировании данных из UI или внешних источников.


Неверный набор цифр

Некоторые локали используют арабские, индийские или восточноазиатские цифры.

Globalize.locale("ar");

Globalize.parseNumber("١٢٣");
// 123

Если вход содержит смешанные системы цифр:

Globalize.parseNumber("12٣");
// NaN

Причина — нарушение атомарности числового набора.


Избыточные или недопустимые символы

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

  • валюта внутри числа
  • текстовые суффиксы
  • HTML-артефакты
Globalize.parseNumber("1,234.56 USD");
// NaN

Ошибки парсинга дат

Строгая зависимость от шаблонов локали

Globalize использует CLDR-шаблоны форматов даты. Несоответствие структуры приводит к невозможности разбора.

Globalize.locale("en");

Globalize.parseDate("31/12/2024");
// null

В данной локали ожидается MM/dd/yyyy, а не dd/MM/yyyy.


Неоднозначные даты

Форматы без года или с сокращёнными компонентами создают неоднозначность:

Globalize.parseDate("01/02");

Результат зависит от локали и конфигурации, но часто возвращается null или некорректная дата при невозможности вывода однозначного значения.


Несоответствие порядка компонентов

Globalize.locale("en");

Globalize.parseDate("2024-12-31");
// null

Ожидается формат с месяцем в начале.


Лишние символы времени

Globalize.parseDate("12/31/2024 10:00 PM UTC");
// null

Причина — отсутствие поддержки указанного формата времени в текущем шаблоне.


Ошибки парсинга валют

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

Неверное расположение символа

Globalize.locale("en");

Globalize.parseNumber("$1,000");
// корректно интерпретируется

Globalize.parseNumber("1,000$");
// NaN

В зависимости от локали валюта может быть:

  • префиксом
  • суффиксом
  • с пробелом

Несоответствие коду валюты

Globalize.parseNumber("1.000 €");

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


Ошибки из-за несоответствия CLDR-данных

Globalize полностью зависит от корректно загруженных CLDR-ресурсов. Отсутствие обязательных сегментов приводит к сбоям парсинга.

Отсутствие числовых данных

Если не загружен numbers:

Globalize.parseNumber("1234");

Результат:

  • NaN или исключение в зависимости от конфигурации сборки

Отсутствие данных дат

Без dates:

Globalize.parseDate("12/31/2024");
// null

Парсер не имеет шаблонов для сопоставления.


Ошибки из-за конфликтов локалей

Переключение локали без пересборки состояния приводит к неконсистентному поведению:

Globalize.locale("en");
Globalize.locale("fr");

Globalize.parseNumber("1.234,56");

Если данные кэшированы под предыдущую локаль, результат может быть неожиданным.


Ошибки форматирования входных данных

Лишние пробелы

Globalize.parseNumber(" 1234 ");

Часто обрабатывается, но не гарантируется во всех версиях и конфигурациях.


Пустые строки

Globalize.parseNumber("");
// NaN
Globalize.parseDate("");
// null

Частично валидные строки

Globalize.parseNumber("123abc");
// NaN

Парсер не игнорирует хвостовые символы, в отличие от некоторых нестрогих реализаций.


Неявные причины ошибок

Несовпадение форматирования и парсинга

Одна из наиболее частых проблем — использование разных паттернов для вывода и ввода.

const number = 1234.56;

Globalize.formatNumber(number, { minimumFractionDigits: 2 });
// "1,234.56"

Globalize.locale("de");

Globalize.parseNumber("1,234.56");
// NaN

Форматирование и парсинг должны использовать одну локаль и одну модель разделителей.


Потеря точности из-за округления формата

При форматировании с округлением:

Globalize.formatNumber(1.23456, { maximumFractionDigits: 2 });
// "1.23"

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


Стратегии обработки ошибок парсинга

Проверка результата парсинга

const result = Globalize.parseNumber(input);

if (Number.isNaN(result)) {
  // значение некорректно
}

Валидация перед парсингом

Проверка строки на соответствие локальному шаблону снижает количество ошибок:

  • допустимые разделители
  • допустимые символы цифр
  • позиция валюты

Нормализация входных данных

Перед парсингом выполняется приведение:

  • замена NBSP на обычный пробел
  • удаление валютных символов
  • унификация десятичного разделителя
input.replace(/\u00A0/g, " ");

Явное задание локали

Globalize.locale("en");
Globalize.parseNumber("1234.56");

Стабильность достигается только при отсутствии неявных переключений локали.


Поведение ошибок в разных типах данных

Тип данных Поведение при ошибке
Числа NaN
Даты null
Валюты NaN или null

Характер ошибок парсинга как системное ограничение

Парсинг в Globalize не является универсальным текстовым анализатором. Он строго ориентирован на:

  • форматы CLDR
  • конкретную локаль
  • симметрию форматирования и разбора

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