One simple way to do achieve what you want is to use String#replace() to remove the currency from the string. To make this easier, you can set currencyDisplay to "code" which will use the ISO currency code - the same one passed in to currency:
const number = 123456.789;
console.log(new Intl.NumberFormat('de-DE', {
style: 'currency',
currency: 'EUR',
currencyDisplay: "code"
})
.format(number)
.replace("EUR", "")
.trim()
); // 123.456,79
// the Japanese yen doesn't use a minor unit
console.log(new Intl.NumberFormat('ja-JP', {
style: 'currency',
currency: 'JPY',
currencyDisplay: "code"
})
.format(number)
.replace("JPY", "")
.trim()
); // 123,457
This can be extracted into a function:
const number = 123456.789;
console.log(format('de-DE', 'EUR', number)); // 123.456,79
console.log(format('ja-JP', 'JPY', number)); // 123,457
function format (locale, currency, number) {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency,
currencyDisplay: "code"
})
.format(number)
.replace(currency, "")
.trim();
}
An alternative that allows you more control is to use Intl.NumberFormat#formatToParts() which formats the number but gives you tokens that you can programmatically consume and manipulate. For example, using the method with locale = "de-DE" and currency = "EUR" you get the following output:
[
{
"type": "integer",
"value": "123"
},
{
"type": "group",
"value": "."
},
{
"type": "integer",
"value": "456"
},
{
"type": "decimal",
"value": ","
},
{
"type": "fraction",
"value": "79"
},
{
"type": "literal",
"value": " "
},
{
"type": "currency",
"value": "EUR"
}
]
Which means that you can easily filter out "type": "currency" and then combine the rest into a string. For example:
const number = 123456.789;
console.log(format('de-DE', 'EUR', number)); // 123.456,79
console.log(format('ja-JP', 'JPY', number)); // 123,457
function format (locale, currency, number) {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency,
currencyDisplay: "code",
})
.formatToParts(number)
.filter(x => x.type !== "currency")
.filter(x => x.type !== "literal" || x.value.trim().length !== 0)
.map(x => x.value)
.join("")
}
NOTE: the exclusion here: .filter(x => x.type !== "literal" || x.value.trim().length !== 0) handles whitespace characters within the number. That might come up when using the option currencySign: 'accounting' in the formatter. In some locales this will use parentheses for negative numbers which would leave a space inside if just the currency is removed:
const number = -123456.789;
const parts = new Intl.NumberFormat('ja-JP', {
style: 'currency',
currency: 'JPY',
currencySign: "accounting",
currencyDisplay: "code",
})
.formatToParts(number);
console.log(parts);
/* output:
[
{ type: "literal" , value: "(" },
{ type: "currency", value: "JPY" },
{ type: "literal" , value: " " },
{ type: "integer" , value: "123" },
{ type: "group" , value: "," },
{ type: "integer" , value: "457" },
{ type: "literal" , value: ")" }
]
*/
.as-console-wrapper { max-height: 100% !important; }
Thus negative numbers are handled correctly:
const number = -123456.789;
console.log(format('de-DE', 'EUR', number)); // 123.456,79
console.log(format('ja-JP', 'JPY', number)); // 123,457
function format (locale, currency, number) {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency,
currencyDisplay: "code",
currencySign: "accounting",
})
.formatToParts(number)
.filter(x => x.type !== "currency")
.filter(x => x.type !== "literal" || x.value.trim().length !== 0)
.map(x => x.value)
.join("")
}
Thanks to Chris Peckham for pointing out potential pitfalls when using the accounting currency sign option.
Answer from VLAZ on Stack OverflowVideos
One simple way to do achieve what you want is to use String#replace() to remove the currency from the string. To make this easier, you can set currencyDisplay to "code" which will use the ISO currency code - the same one passed in to currency:
const number = 123456.789;
console.log(new Intl.NumberFormat('de-DE', {
style: 'currency',
currency: 'EUR',
currencyDisplay: "code"
})
.format(number)
.replace("EUR", "")
.trim()
); // 123.456,79
// the Japanese yen doesn't use a minor unit
console.log(new Intl.NumberFormat('ja-JP', {
style: 'currency',
currency: 'JPY',
currencyDisplay: "code"
})
.format(number)
.replace("JPY", "")
.trim()
); // 123,457
This can be extracted into a function:
const number = 123456.789;
console.log(format('de-DE', 'EUR', number)); // 123.456,79
console.log(format('ja-JP', 'JPY', number)); // 123,457
function format (locale, currency, number) {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency,
currencyDisplay: "code"
})
.format(number)
.replace(currency, "")
.trim();
}
An alternative that allows you more control is to use Intl.NumberFormat#formatToParts() which formats the number but gives you tokens that you can programmatically consume and manipulate. For example, using the method with locale = "de-DE" and currency = "EUR" you get the following output:
[
{
"type": "integer",
"value": "123"
},
{
"type": "group",
"value": "."
},
{
"type": "integer",
"value": "456"
},
{
"type": "decimal",
"value": ","
},
{
"type": "fraction",
"value": "79"
},
{
"type": "literal",
"value": " "
},
{
"type": "currency",
"value": "EUR"
}
]
Which means that you can easily filter out "type": "currency" and then combine the rest into a string. For example:
const number = 123456.789;
console.log(format('de-DE', 'EUR', number)); // 123.456,79
console.log(format('ja-JP', 'JPY', number)); // 123,457
function format (locale, currency, number) {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency,
currencyDisplay: "code",
})
.formatToParts(number)
.filter(x => x.type !== "currency")
.filter(x => x.type !== "literal" || x.value.trim().length !== 0)
.map(x => x.value)
.join("")
}
NOTE: the exclusion here: .filter(x => x.type !== "literal" || x.value.trim().length !== 0) handles whitespace characters within the number. That might come up when using the option currencySign: 'accounting' in the formatter. In some locales this will use parentheses for negative numbers which would leave a space inside if just the currency is removed:
const number = -123456.789;
const parts = new Intl.NumberFormat('ja-JP', {
style: 'currency',
currency: 'JPY',
currencySign: "accounting",
currencyDisplay: "code",
})
.formatToParts(number);
console.log(parts);
/* output:
[
{ type: "literal" , value: "(" },
{ type: "currency", value: "JPY" },
{ type: "literal" , value: " " },
{ type: "integer" , value: "123" },
{ type: "group" , value: "," },
{ type: "integer" , value: "457" },
{ type: "literal" , value: ")" }
]
*/
.as-console-wrapper { max-height: 100% !important; }
Thus negative numbers are handled correctly:
const number = -123456.789;
console.log(format('de-DE', 'EUR', number)); // 123.456,79
console.log(format('ja-JP', 'JPY', number)); // 123,457
function format (locale, currency, number) {
return new Intl.NumberFormat(locale, {
style: 'currency',
currency,
currencyDisplay: "code",
currencySign: "accounting",
})
.formatToParts(number)
.filter(x => x.type !== "currency")
.filter(x => x.type !== "literal" || x.value.trim().length !== 0)
.map(x => x.value)
.join("")
}
Thanks to Chris Peckham for pointing out potential pitfalls when using the accounting currency sign option.
If you only want the separators in between individual digits, just format as a number instead of using currency:
const numberFormatter = new Intl.NumberFormat("en-US", {
// Do not show fractions - front end should only handle whole numbers
maximumFractionDigits: 0,
});
And then numberFormatter.format(asNumber); with whatever number you like.
For your example of 123456, "de-DE" is 123.456, "ja-JP" is 123,456