I've got a web page that displays decimals in a user's localized format, like so:
7.75
7,75
If I add two number variables together in JavaScript on my machine (where the numbers are taken from strings in the above formats) I get the following results:
7.75 + 7.75 = 15.5
7,75 + 7,75 = 0
If I was to run this code on a Dutch users machine, should I expect the English-formatted addition to return 0, and the Dutch-formatted addition to return 15,5?
In short: Does the JavaScript calculation use local decimal separators in its string to number conversions?
Here's an example for a locale aware number 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 current locale of the browser if locale parameter is undefined) 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.
Update:
\p{Number} for removing digits. So that it also works with non-arabic digits.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; }
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
Expanding on the solution from @OXiGEN we can use Intl.NumberFormat.formatToParts() to extract also the currency symbol :)
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With