Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 924
dMedia Avatar asked Jul 07 '17 11:07

dMedia


People also ask

What does toLocaleString() do?

The toLocaleString() method returns a string with a language-sensitive representation of this date. In implementations with Intl. DateTimeFormat API support, this method simply calls Intl. DateTimeFormat .

How do I localize a number in JavaScript?

In JavaScript, toLocaleString() is a Number method that is used to convert a number into a locale-specific numeric representation of the number (rounding the result where necessary) and return its value as a string.

How do you format numbers in JavaScript?

JavaScript numbers can be formatted in different ways like commas, currency, etc. You can use the toFixed() method to format the number with decimal points, and the toLocaleString() method to format the number with commas and Intl. NumberFormat() method to format the number with currency.


3 Answers

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.

like image 125
Alexander Pravdin Avatar answered Oct 19 '22 13:10

Alexander Pravdin


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 });

like image 22
Shahzaib Hayat Khan Avatar answered Oct 19 '22 12:10

Shahzaib Hayat Khan


Here is a solution that isn't using regex and will deal with any locale, properly.

It uses the currency formatter of the locale and iterates all parts of it to exclude the literal and currency, properly, resulting in only getting the number as string. (Btw, the literal is the space between number and currency symbol).

const value = new Intl.NumberFormat('de-DE', {
    style: 'currency',
    currency: 'EUR',
}).formatToParts(12345.678).map(
    p => p.type != 'literal' && p.type != 'currency' ? p.value : ''
).join('')

console.log(value) // prints 12.345,68
like image 6
Martin Braun Avatar answered Oct 19 '22 14:10

Martin Braun