Does JavaScript take local decimal separators into account?

I have a webpage with decimals in a localized user format, for example:

  • Russian: 7.75
  • Dutch: 7,75

If I add two numeric variables together in JavaScript on my computer (where numbers are taken from strings in the above formats), I get the following results:

  • Russian: 7.75 + 7.75 = 15.5
  • Dutch: 7,75 + 7,75 = 0

If I were to run this code on the user's Dutch computer, should I expect the add-on in the English format to return 0 , and adding the Dutch format to return 15,5 ?

In short: does JavaScript computation use local decimal separators in its string for numerical conversions?

+5
source share
6 answers

No, the delimiter is always a period (.) In javascript Number . Therefore, 7,75 is evaluated as 75 , since a causes the evaluation from left to right (try it in the console: x=1,x+=1,alert(x) or more to the point var x=(7,75); alert(x); ). If you want to convert a Dutch (well, not only Dutch, even continental European) formatted value, it must be String . You can write a String prototype extension, for example:

 String.prototype.toFloat = function(){ return parseFloat(this.replace(/,(\d+)$/,'.$1')); }; //usage '7,75'.toFloat()+'7,75'.toFloat(); //=> 15.5 
+7
source

Here is an example for a parser that supports locales:

 function parseLocaleNumber(stringNumber) { var thousandSeparator = (1111).toLocaleString().replace(/1/g, ''); var decimalSeparator = (1.1).toLocaleString().replace(/1/g, ''); return parseFloat(stringNumber .replace(new RegExp('\\' + thousandSeparator, 'g'), '') .replace(new RegExp('\\' + decimalSeparator), '.') ); } 

It uses the current browser locale to replace thousands and decimal separators.

With German installation

 var n = parseLocaleNumber('1.000.045,22'); 

n will be equal to 1000045.22 .

+17
source

No, a comma ( , ) is an operator that has special meaning, just like a period ( . ). Otherwise, everything is simple:

 var array1 = [1,2]; var array2 = [1.2]; 

will be divided into different locales. All the main languages ​​that I know relate to . and , separately and strictly, regardless of language.

+3
source

No, decimal separators are not localized in JavaScript at all, and parseFloat () parses numbers in the same format that you need to use in your JavaScript source code: "." as a decimal separator, a separator of groups (thousands), "E" or "e" as a symbol "from ten to power", and Ascii hyphen "-" as a minus sign.

To read or write numbers in a localized format, you need something else. I would recommend the Globalize.js library, unless you can limit yourself to a single decimal separator problem and a limited number of languages ​​- in this case it would be easier to just manipulate a string that displays ".". to "," at the output and vice versa at the input.

+1
source

Extending the solution from @naitsirch, we can use Intl.NumberFormat.formatToParts () so that JS parses the group and decimal separators.

 function parseLocaleNumber(stringNumber) { let num = 123456.789, fmt_local = new Intl.NumberFormat(), parts_local = fmt_local.formatToParts(num), group = '', decimal = ''; parts_local.forEach(function(i) { switch (i.type) { case 'group': group = i.value; break; case 'decimal': decimal = i.value; break; default: break; } }); return parseFloat(stringNumber .replace(new RegExp('\\' + group, 'g'), '') .replace(new RegExp('\\' + decimal), '.') ); } //replace this string with a number formatted for your locale console.log(parseLocaleNumber("987,654,321.01")); //output for "en" locale: 987654321.01 

+1
source

Given the symbol, this works in all cases:

 parseLocaleNumber: function ( stringNumber ) { let thousandSeparator = (11111).toLocaleString().replace(/1/g, ''); let decimalSeparator = (1.1).toLocaleString().replace(/1/g, ''); let symbol = (0).toLocaleString() .replace(/0/g, '') .replace(new RegExp('\\' + decimalSeparator), '.') .trim(); return parseFloat( stringNumber .replace(new RegExp('\\' + thousandSeparator, 'g'), '') .replace(new RegExp('\\' + decimalSeparator), '.') .replace(new RegExp( symbol ), '') ); } 

2 details highlighted:

  1. use 11111 instead of 1111 because the first always shows the thousands separator by default.
  2. The number format always uses "." as a decimal separator
0
source

Source: https://habr.com/ru/post/984233/


All Articles