Carl's Notes
Life complexity navigation algorithms

A Simple Solution for Parsing Localized Numbers in JavaScript

I recently published a simple tool for calculating how adding water to a glass of whisky changes the alcohol strength.

Because the user should be able to enter numbers with a precision of 0.1 or even 0.01, I was faced with a classic localization problem: numbers are formatted differently in different cultures. US-based users write 1,234.5. In Germany or France, the same number could be written 1.234,5. Actually, my guess is that most people would even omit the thousand separator altogether and write either 1234.5 or 1234,5.

Now, formatting a number in the user’s locale is easy. With:

num.toLocaleString(undefined, { maximumFractionDigits: 2})

I can output the number with 2 fraction digits precision, just the way the user would expect to see them based on their browser’s language settings.

But there isn’t an out-of-the-box way of parsing such numbers. Doing so with perfect accuracy is probably very hard and would require importing a comprehensive set of culture-specific rules, and also knowing which one to apply. I just needed a simple solution that would work in 99,9% of cases, though. (Or 99.9%, as my spellchecker points out…)

I went with a simple solution:

function parseUserNumber(s) {
	const c = s.indexOf(',');
	const p = s.indexOf('.');
	if (c == -1) {
		// No comma at all, life is good.
		return parseFloat(s);
	}
	else if (p == -1) {
		// No period at all. Assume comma used as decimal sign, replace with period.
		return parseFloat(s.replace(',', '.'));
	}
	else if (c < p) {
		// Something resembling 1,234.5: Assume comma is thousands separator, just remove.
		return parseFloat(s.replaceAll(',', ''));
	}
	else {
		// Something resembling 1.234,5: Remove period, then replace comma with period.
		return parseFloat(s.replaceAll('.', '').replace(',', '.'));
	}
}

In the function above, s is assumed to be a string. Add your own solution to handle other types as needed.

You can try it out here:

JavaScript Number (or in your locale).

There’s probably more accurate ways of doing it, and, acknowledging this is a very western-centric solution, there are possibly locales in which this doesn’t quite work. You probably don’t want to use this for a financial application (you don’t want to use JavaScript Numbers for this in any case). But this solution is simple, works in all cases I could think of, and is good enough in a context where performance when converting user input is not a concern.

Found a bug? Report an issue on GitHub. Thanks!

Read another post