I\'ve got a web page that displays decimals in a user\'s localized format, like so:
7.757,75
Expanding on the solution from @naitsirch we can use Intl.NumberFormat.formatToParts() to have JS parse 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
No, decimal separators are not localized at all in JavaScript, and parseFloat() parses numbers in the same format as you need to use in JavaScript source code: “.” as decimal separator, no group (thousands) separator, “E” or “e” as “times ten to power” symbol, and Ascii hyphen “-” as minus sign.
To read or write numbers in localized format, you need something else. I would recommend the Globalize.js library, unless you can limit yourself to the single issue of decimal separator and a limited number of languages—in that case, it might be simpler to do just string manipulation that maps “.” to “,” on output and vice versa on input.
No, comma (,) is an operator having special meaning, just like dot (.). Otherwise things as simple as:
var array1 = [1,2];
var array2 = [1.2];
would break under different locales. All mainstream languages I know treat . and , separately and stricly, irrespective to locale.
No, the separator is always a dot (.) in a javascript Number. So 7,75 evaluates to 75, because a , invokes left to right evaluation (try it in a 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, let's say Continental European) formatted value, it should be a String. You could write an extension to the String prototype, something like:
String.prototype.toFloat = function(){
return parseFloat(this.replace(/,(\d+)$/,'.$1'));
};
//usage
'7,75'.toFloat()+'7,75'.toFloat(); //=> 15.5
Note, if the browser supports it you can use Number.toLocaleString
console.log((3.32).toLocaleString("nl-NL"));
console.log((3.32).toLocaleString("en-UK"));
.as-console-wrapper { top: 0; max-height: 100% !important; }
Here's an example for a locale aware number parser:
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 locale of the browser to replace thousand and decimal separators.
With a German locale setting
var n = parseLocaleNumber('1.000.045,22');
n will be equal to 1000045.22.
Taking the symbol into account, 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: