Javascript number.toLocaleString currency without currency sign
Suppose we have
var number = 123456.789;
What I want is to display this number in locale 'de-DE' as
123.456,79
in locale 'ja-JP' as
123,457
in locale 'en-US' as
123,456.79
and so on according to user's locale. The problem is that Javascript's number.toLocaleString
requires to specify currency sign and I can't find out how to tell to not display it at all.
What I tried:
number.toLocaleString('de-DE', { style: 'currency' }));
// TypeError: undefined currency in NumberFormat() with currency style
number.toLocaleString('de-DE', { style: 'currency', currency: '' }));
// RangeError: invalid currency code in NumberFormat():
number.toLocaleString('de-DE', { style: 'currency', currency: false }));
// RangeError: invalid currency code in NumberFormat(): false
number.toLocaleString('de-DE', { style: 'currency', currency: null }));
// RangeError: invalid currency code in NumberFormat(): null
The function also has option currencyDisplay
. I tried the same values as above with currency
option but with same result.
UPDATE (2020-11-25)
A few people pointed to .resolvedOptions()
. It basically solves the question:
const currencyFractionDigits = new Intl.NumberFormat('de-DE', {
style: 'currency',
currency: 'EUR',
}).resolvedOptions().maximumFractionDigits;
const value = (12345.678).toLocaleString('de-DE', {
maximumFractionDigits: currencyFractionDigits
});
console.log(value); // prints 12.345,68
Thank you.
Solution 1:
Here how I solved this issue. When I want to format currency without any signs, I format it with the currency code and then just remove 3-chars code from the result.
export function getCurrencyFormatWithSymbol(currencyCode) {
return {
style: 'currency',
currency: currencyCode,
currencyDisplay: 'symbol',
}
}
export function getCurrencyFormatWithIsoCode(currencyCode) {
return {
style: 'currency',
currency: currencyCode,
currencyDisplay: 'code',
}
}
export function getCurrencyFormatWithLocalName(currencyCode) {
return {
style: 'currency',
currency: currencyCode,
currencyDisplay: 'name',
}
}
export function getCurrencyFormatNumbersOnly(currencyCode) {
return {
style: 'currency',
currency: currencyCode,
currencyDisplay: 'none',
}
}
export function formatCurrency (value, format, lang) {
const stripSymbols = (format.currencyDisplay === 'none')
const localFormat = stripSymbols ? {...format, currencyDisplay: 'code'} : format
let result = Intl.NumberFormat(lang, localFormat).format(value)
if (stripSymbols) {
result = result.replace(/[a-z]{3}/i, "").trim()
}
return result
}
Usage:
const format = getCurrencyFormatNumbersOnly('JPY')
formatCurrency(12345, format, 'ja')
formatCurrency(123456, format, 'ja')
formatCurrency(1234567, format, 'ja')
formatCurrency(12345678, format, 'ja')
Edit: The only minus, in this case, is the speed. On simple tasks, it will work perfectly. But if you are going to format a lot of numbers (for example, if you are fetching financial reports with raw data from backend and then format numbers according to user settings) this function can slow down your algorithms significantly and become a bottleneck on some browsers. So, test it carefully before using in production.
Solution 2:
There is no way to pass parameter to toLocaleString
and remove currency symbol. so use this function instead.
var convertedNumber = num.toLocaleString('de-DE', { minimumFractionDigits: 2 });