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 OverflowOne 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
You need to use the narrow option when formatting numbers in JS
"narrowSymbol" to use a narrow format symbol ("$100" rather than "US$100"),
const amount = 123444;
console.log(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', currencyDisplay: 'narrowSymbol'}).format(amount));
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat for full details.
V8 JavaScript engine is using ICU library for i18N.
See there for all currency data: https://github.com/unicode-org/icu/tree/master/icu4c/source/data/curr
But for sure French people use $ and not $US when talking about US dollar.
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 });
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.
The Intl.NumberFormat should have the symbols you need, you just have to make sure you specify the correct language code.
You can find a mapping of ISO language codes here: https://www.w3schools.com/tags/ref_language_codes.asp
In this case you will need to use the Polish value "pl" instead of "en-US"
Intl.NumberFormat("pl",{
style:'currency',
minimumIntegerDigits:1,
currency: 'PLN',
currencyDisplay: 'symbol'
}).format(43);
To display just the currency symbol more concisely, you might consider using currencyDisplay: 'narrowSymbol' instead of symbol in your Intl.NumberFormat configuration. This option is also applicable for toLocaleString. As explained in the MDN documentation, narrowSymbol provides a more streamlined symbol format, e.g., "$100" rather than "US$100".
Intl.NumberFormat("en-US", {
style: 'currency',
currency: 'PLN',
currencyDisplay: 'narrowSymbol'
}).format(43);
Displays 'zł 43.00'
However, please verify the compatibility with your target browsers here on CanIUse as narrowSymbol is not supported in some older or less common browsers.
The following works. It's a bit ugly, but it fulfils the contract:
NumberFormat nf = NumberFormat.getCurrencyInstance();
DecimalFormatSymbols decimalFormatSymbols = ((DecimalFormat) nf).getDecimalFormatSymbols();
decimalFormatSymbols.setCurrencySymbol("");
((DecimalFormat) nf).setDecimalFormatSymbols(decimalFormatSymbols);
System.out.println(nf.format(12345.124).trim());
You could also get the pattern from the currency format, remove the currency symbol, and reconstruct a new format from the new pattern:
NumberFormat nf = NumberFormat.getCurrencyInstance();
String pattern = ((DecimalFormat) nf).toPattern();
String newPattern = pattern.replace("\u00A4", "").trim();
NumberFormat newFormat = new DecimalFormat(newPattern);
System.out.println(newFormat.format(12345.124));
Set it with an empty string instead:
DecimalFormat formatter = (DecimalFormat) NumberFormat.getCurrencyInstance(Locale.US);
DecimalFormatSymbols symbols = formatter.getDecimalFormatSymbols();
symbols.setCurrencySymbol(""); // Don't use null.
formatter.setDecimalFormatSymbols(symbols);
System.out.println(formatter.format(12.3456)); // 12.35
If the amount is in pence and the result required in GBP, you have to divide the amount by 100, (considering 100 pence = 1 GBP). The minimumFractionDigits adjust the trailing Zeros after decimal point of the currently but does not manipulate the actual value.
You should try below
const formatter = new Intl.NumberFormat("en-GB", {
style: "currency",
currency: "GBP",
minimumFractionDigits: 2,
});
const moneyFormat = formatter.format(7360 / 100);
console.log(moneyFormat)
The format function takes the raw value and will format it to the amount of fraction digits that you specify. The raw number you gave it was 7360, so it is adding two fraction digits to make it 7360.00. The number it needs to be passed is actually 73.60.
If you are working with the currency value as the whole number, you can simply divide by 100 to display the value you are expecting.
const moneyFormat = formatter.format(7360 / 100);