[ACCEPTED]-Does JavaScript take local decimal separators into account?-localization
Here's an example for a locale aware number 5 parser:
function parseLocaleNumber(stringNumber, locale) {
var thousandSeparator = Intl.NumberFormat(locale).format(11111).replace(/\p{Number}/gu, '');
var decimalSeparator = Intl.NumberFormat(locale).format(1.1).replace(/\p{Number}/gu, '');
return parseFloat(stringNumber
.replace(new RegExp('\\' + thousandSeparator, 'g'), '')
.replace(new RegExp('\\' + decimalSeparator), '.')
);
}
It uses the passed locale (or the 4 current locale of the browser if locale 3 parameter is undefined) to replace thousand 2 and decimal separators.
With a German locale 1 setting
var n = parseLocaleNumber('1.000.045,22');
n
will be equal to 1000045.22
.
Update:
- Addressed Pointy's comment by using the regex class
\p{Number}
for removing digits. So that it also works with non-arabic digits. - Addressed Orion Adrian's comment to support languages where numbers are separated at every fourth digits.
- Added locale parameter to sepcify different locales for parsing.
No, the separator is always a dot (.) in 9 a javascript Number
. So 7,75
evaluates to 75
, because 8 a ,
invokes left to right evaluation (try 7 it in a console: x=1,x+=1,alert(x)
, or more to the point 6 var x=(7,75); alert(x);
). If you want to convert a Dutch (well, not 5 only Dutch, let's say Continental European) formatted 4 value, it should be a String
. You could write 3 an extension to the String
prototype, something 2 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 1 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; }
Expanding on the solution from @naitsirch 2 we can use Intl.NumberFormat.formatToParts() to have JS parse the group and 1 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
Expanding on the solution from @OXiGEN we 2 can use Intl.NumberFormat.formatToParts() to extract also the currency symbol 1 :)
function parseLocaleNumber(stringNumber, locale, currency_code) {
let num = 123456.789,
fmt_local = new Intl.NumberFormat(locale, {
style: 'currency',
currency: currency_code
}),
parts_local = fmt_local.formatToParts(num),
group = '',
decimal = '',
currency = '';
// separators
parts_local.forEach(function(i) {
//console.log(i.type + ':' + i.value);
switch (i.type) {
case 'group':
group = i.value;
break;
case 'decimal':
decimal = i.value;
break;
case 'currency':
currency = i.value;
break;
default:
break;
}
});
return parseFloat(stringNumber
.replace(new RegExp('\\' + group, 'g'), '')
.replace(new RegExp('\\' + decimal), '.')
.replace(new RegExp('\\' + currency, 'g'), '')
);
}
//replace inputs with a number formatted for your locale, your locale code, your currency code
console.log(parseLocaleNumber('$987,654,321.01', 'en', 'USD'));
//output for "en" locale and "USD" code: 987654321.01
No, comma (,
) is an operator having special 5 meaning, just like dot (.
). Otherwise things 4 as simple as:
var array1 = [1,2];
var array2 = [1.2];
would break under different 3 locales. All mainstream languages I know 2 treat .
and ,
separately and stricly, irrespective 1 to locale.
No, decimal separators are not localized 14 at all in JavaScript, and parseFloat() parses 13 numbers in the same format as you need to 12 use in JavaScript source code: “.” as decimal 11 separator, no group (thousands) separator, “E” or 10 “e” as “times ten to power” symbol, and 9 Ascii hyphen “-” as minus sign.
To read or 8 write numbers in localized format, you need 7 something else. I would recommend the Globalize.js 6 library, unless you can limit yourself to 5 the single issue of decimal separator and 4 a limited number of languages—in that case, it 3 might be simpler to do just string manipulation 2 that maps “.” to “,” on output and vice 1 versa on input.
Taking the symbol into account, this works 1 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:
- use 11111 instead of 1111 because the first always shows thousand separator by default.
- Number format always uses '.' as decimal separator
More Related questions
We use cookies to improve the performance of the site. By staying on our site, you agree to the terms of use of cookies.