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
How to Set State of Response from Axios in React
What Is the List of Possible Values for Navigator.Platform as of Today
Display a Popup Only Once Per User
JavaScript Change Date into Format of (Dd/Mm/Yyyy)
How to Redefine a JavaScript Class's Method
Maximum Call Stack Size Exceeded on Npm Install
Vuejs 2.0 Emit Event from Grand Child to His Grand Parent Component
JavaScript If Statement with Multiple Permissible Conditions
Sum of Array Object Property Values in New Array of Objects in JavaScript
Why Does JavaScript Hoist Variables
Which Browsers Support Import and Export Syntax for Ecmascript 6
Correct Way to Handle Conditional Styling in React
Detecting Line-Breaks with Jquery
How to Determine If an Image Has Loaded, Using JavaScript/Jquery
Dc.Js - How to Create a Row Chart from Multiple Columns
Facebook How to Check If User Has Liked Page and Show Content