NumberFormatter: странное поведение со знаком минус в разных регионах - PullRequest
2 голосов
/ 07 августа 2020

Я столкнулся с проблемой с Symfony / Form , которые под капотом используют NumberFormatter для форматирования поля NumberType. Наш проект многоязычный, и для каждой страны мы используем разные языковые стандарты.

$formatter->format() возвращает разные знаки минуса для отрицательных чисел. Например:

$formatter = new \NumberFormatter('en', \NumberFormatter::DECIMAL);
$value = $formatter->format('-150');
var_dump($value); // string(4) "-150"

$formatter = new \NumberFormatter('lt', \NumberFormatter::DECIMAL);
$value = $formatter->format('-150');
var_dump($value); // string(6) "−150" <-- here is the problem

Как видите, NumberFormatter меняет знак минус на что-то другое.

Почему это важно для меня? Поскольку некоторые элементы на странице генерируются с javascript, а js не может анализировать −150 число и возвращает NaN.

Может ли кто-нибудь объяснить причину такого поведения и как получить правильный знак минус из NumberFormatter для lt locale?

Ответы [ 2 ]

0 голосов
/ 08 августа 2020

Как насчет преобразования в ascii?

$formatter = new \NumberFormatter('lt', \NumberFormatter::DECIMAL);
$value = $formatter->format('-150');
$valueAsAscii = iconv('utf8', 'ascii//translit', $value);

var_dump($value);
var_dump($valueAsAscii);

Рабочий пример .

вывод

string(6) "−150"
string(4) "-150"

ссылки

0 голосов
/ 07 августа 2020

Я нашел решение. Symfony / Form имеет отличную возможность добавить преобразователи вида , которые отображаются прямо перед отрисовкой элемента формы.

Вот мой FormType:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder->add('amount', NumberType::class, array(
        'required' => true,
        'scale' => 4,
    ));

    $builder->get('amount')->addViewTransformer(new CallbackTransformer(
        function ($forward) {
            // Transform the lithuanian minus sign to the normal minus sign.
            return preg_replace('/\x{2212}/u', '-', $forward);
        },
        function ($reverse) {
            return $reverse;
        }
    ));

    // others form elements...
}

Этот подход позволяет переопределить преобразователь вида по умолчанию для \Symfony\Component\Form\Extension\Core\Type\NumberType, который добавляет spesifi c знак минус.

$builder->addViewTransformer(new NumberToLocalizedStringTransformer(
    $options['scale'],
    $options['grouping'],
    $options['rounding_mode'],
    $options['html5'] ? 'en' : null
));

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

Это не решает проблему в целом для NumberFormatter, но помогите мне решить мою проблему.

...