How to Convert String to Number According to Locale (Opposite of .Tolocalestring)

How do I convert String to Number according to locale javascript

The following function will first construct a NumberFormat based on the given locale. Then it will try to find the decimal separator for that language.

Finally it will replace all but the decimal separator in the given string, then replace the locale-dependant separator with the default dot and convert it into a number.

function convertNumber(num, locale) {
const { format } = new Intl.NumberFormat(locale);
const [, decimalSign] = /^0(.)1$/.exec(format(0.1));
return +num
.replace(new RegExp(`[^${decimalSign}\\d]`, 'g'), '')
.replace(decimalSign, '.');
}

// convertNumber('100,45', 'de-DE')
// -> 100.45

Keep in mind that this is just a quick proof of concept and might / will fail with more exotic locales that do not follow the assumptions made here (e.g. left-to-right, no weird number insertions, no whitespace, no signs etc.).

You can however adapt this...

Is there any JavaScript standard API to parse to number according to locale?

The NPM package d2l-intl provides a locale-sensitive parser. It has since been superseded by @brightspace-ui/intl (essentially version 3), so some info below might or might not apply in its newer incantation.

const { NumberFormat, NumberParse } = require('d2l-intl');
const formatter = new NumberFormat('es');
const parser = new NumberParse('es');
const number = 1234.5;
console.log(formatter.format(number)); // 1.234,5
console.log(parser.parse(formatter.format(1234.5))); // 1234.5

Unfortunately, that library only comes with support for a handful of locales out of the box. It also uses parseInt which only supports Western Arabic numerals, so for locales that use different numeral systems, you're going to have to get more clever. Here's one solution I found by Mike Bostock. I don't want to take credit for it, but I've reproduced it here for posterity (with some slight tweaks based on my own preferences):

class NumberParser {
constructor(locale) {
const format = new Intl.NumberFormat(locale);
const parts = format.formatToParts(12345.6);
const numerals = Array.from({ length: 10 }).map((_, i) => format.format(i));
const index = new Map(numerals.map((d, i) => [d, i]));
this._group = new RegExp(`[${parts.find(d => d.type === "group").value}]`, "g");
this._decimal = new RegExp(`[${parts.find(d => d.type === "decimal").value}]`);
this._numeral = new RegExp(`[${numerals.join("")}]`, "g");
this._index = d => index.get(d);
}
parse(string) {
return (string = string.trim()
.replace(this._group, "")
.replace(this._decimal, ".")
.replace(this._numeral, this._index)) ? +string : NaN;
}
}

const formatter = new Intl.NumberFormat('ar-EG');
const parser = new NumberParser('ar-EG');
console.log(formatter.format(1234.5)); // ١٬٢٣٤٫٥
console.log(parser.parse(formatter.format(1234.5))); // 1234.5


Related Topics



Leave a reply



Submit