Language and Calculations - non well formed numeric values (decimal separator)

What’s the best way to use languages and calculate numbers.

I am having the problem that on a multi language site the decimal separator
e.g.

  • german => ‘,’
  • english => ‘.’

is different, thus working with functions like number_format() does seem to break. Giving the usual error:

A non well formed numeric value encountered

is there any way to define that on all languages it’s using the same separator, or any other solution to not getting bothered with that? when not using number_format() it errors out while just doing simple $a * $b calculations.

Have you set different locale setting for each language: https://getkirby.com/docs/guide/languages/introduction#detailed-locale-settings. Apart from that, there is a parameter for the decimal separator in the number_format function that you can set.

setting the locale array completely in detail always ends up on my local machine

Use of undefined constant LC_MESSAGES - assumed 'LC_MESSAGES' (this will throw an Error in a future version of PHP)

Without setting the locale, something like this should work:

<?php $number = $page->number();
$decPoint = $kirby->language()->code() == 'en'? '.':',';
echo number_format ( $number->toFloat(), 1, $decPoint , ''); 
?>

Where for the last parameter, which is the decimal point, you could also set a variable depending on language.

The Panel automatically saves decimals in English with a dot, in German with a comma.

1 Like

is it possible to change that setting, that the panel is always saving in one of both?

If you use the same values in all languages, you might as well set translate to false. If the values are different, I don’t think there is such a settting.

seems like putting (float)$pricevariable seems to do the job as well…

well ok, it does not seem to be the final answer,

with (float) the english version works and calculation does not give any sort of error, however on the german version the numbers get rounded downwards… so decimals do not work like that.

You could try using LC_ALL instead:

return [
  'code' => 'en',
   ...  
  'locale'  => [
    LC_ALL  => 'en_US.utf8'
  ]
];

Maybe that works. Maybe also in combination with localeconv().

If you set


return array (
  LC_NUMERIC  => 'en_US.utf-8',

);

The Panel stores the number with a dot as decimal separator.

function langDecimal($value){
    if(site()->language()->code() == 'de'){
        $value = Str::replace($value,',','.');
    }
    return $value;
}
$num = '123,13';
$z = langDecimal($num) * 2)
// output 246,26

replacing the comma on german language seems to work.

1 Like