简体   繁体   English

Javascript number.toLocaleString 没有货币符号的货币

[英]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我想要的是在语言环境“de-DE”中显示这个数字

123.456,79

in locale 'ja-JP' as在语言环境“ja-JP”中为

123,457

in locale 'en-US' as在语言环境“en-US”中

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.问题是 Javascript 的number.toLocaleString需要指定货币符号,我不知道如何告诉它根本不显示。

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 .该函数还具有选项currencyDisplay I tried the same values as above with currency option but with same result.我使用currency选项尝试了与上述相同的值,但结果相同。


UPDATE (2020-11-25)更新(2020-11-25)

A few people pointed to .resolvedOptions() .一些人指出.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.谢谢你。

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.当我想格式化没有任何符号的货币时,我使用货币代码对其进行格式化,然后从结果中删除 3 个字符的代码。

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.因此,在生产中使用之前,请仔细测试。

There is no way to pass parameter to toLocaleString and remove currency symbol.无法将参数传递给toLocaleString并删除货币符号。 so use this function instead.所以请改用此功能。

var convertedNumber = num.toLocaleString('de-DE', { minimumFractionDigits: 2 });

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

You can use the currencyDisplay: 'code' option, and since you know the currency code you can easily replace it by the symbol you want :您可以使用currencyDisplay: 'code'选项,并且由于您知道货币代码,您可以轻松地将其替换为您想要的符号:

return Intl.NumberFormat(language, {
    style: 'currency', currency: currency.code, currencyDisplay: 'code'
  }).format(amount).replace(currency.code, currency.symbol);

This way you're keeping all the currency formatting standards implied in NumberFormat and replacing only the symbol.这样,您就可以保留NumberFormat中隐含的所有货币格式标准并仅替换符号。 In your case the custom symbol would be an empty string ( '' ) and you may want to trim your string too with .trim() .在您的情况下,自定义符号将是一个空字符串( '' ),您可能也想用.trim()修剪您的字符串。

Slight variation on the OPs answer including the minimumFractionDigits包括 minimumFractionDigits 在内的 OP 答案略有不同

const resolvedOptions = new Intl.NumberFormat('en-GB', { style: 'currency', currency: 'GBP', }).resolvedOptions();
const currencyOptions = {
    minimumFractionDigits: resolvedOptions.minimumFractionDigits,
    maximumFractionDigits: resolvedOptions.maximumFractionDigits
}
const value = (12345.678).toLocaleString('en-GB', currencyOptions)

The solution proposed in the OP won't work for the fr-CH locale because there is a distinction between a “currency amount” and a “non-currency amount”. OP 中提出的解决方案不适用于fr-CH语言环境,因为“货币金额”和“非货币金额”之间存在区别。 The former uses a dot as decimal separator whereas the latter uses a comma:前者使用点作为小数分隔符,而后者使用逗号:

 const n = 1234.56 console.log(n.toLocaleString('fr-CH')) console.log(n.toLocaleString('fr-CH', { style: 'currency', currency: 'CHF' }))

Using .replace() either with a regex or directly with the currency code does seem to be the fastest solution but here is a solution with the .formatToParts() function of NumberFormat and how it can be used to solve the OP's question:.replace()与正则表达式一起使用或直接与货币代码一起使用似乎是最快的解决方案,但这是一个具有 NumberFormat 的.formatToParts()函数的解决方案,以及如何使用它来解决 OP 的问题:

 console.log(new Intl .NumberFormat('fr-CH', { style: 'currency', currency: 'CHF' }) .formatToParts(1234.56) // returns an array of the different parts of the amount .filter(p => p.type != 'currency') // removes the currency part .reduce((s, p) => s + p.value, '') // joins the remaining values .trim())

Do you need the currency sign?你需要货币符号吗? If not number.toLocaleString('de-DE') should do the trick.如果不是number.toLocaleString('de-DE')应该可以解决问题。

I found this thread by searching this use case, and the trick i use using class Intl.NumberFormat , with Regex of symbol it supported on Mozilla Firefox and Google Chrome.The trick is take currency symbol and using it as a needle for regex replace after localisation.我通过搜索这个用例找到了这个线程,以及我使用类Intl.NumberFormat使用的技巧,它在 Mozilla Firefox 和 Google Chrome 上支持符号正则表达式。诀窍是采用货币符号并将其用作正则表达式替换后的针本土化。

This sample code should do the trick:这个示例代码应该可以解决问题:

var number = 123456.789;

function getCurrencySymbol(locale, currency) {
  return (0).toLocaleString(locale, {
    style: 'currency',
    currency: currency,
    minimumFractionDigits: 0,
    maximumFractionDigits: 0
  }).replace(/\d/g, '').trim();
}
var numeric_format = new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', currencyDisplay: 'symbol' });
var localCurrencySymbol  = getCurrencySymbol('id-ID', 'IDR');
var CurrencySymbolNeedle = new RegExp(localCurrencySymbol, "g");

var amount = numeric_format.format(number);
console.log(localCurrencySymbol); // Rp
console.log(amount); // Rp 123.456,79
amount = amount.replace(CurrencySymbolNeedle, '').replace(/\s+/g, '');
console.log(amount); // 123.456,79

I don't test if this class support cross browser我不测试这个类是否支持跨浏览器

Edit: Function to get currency symbol take from Get the currency symbol for a locale编辑:获取货币符号的函数取自获取语言环境的货币符号

You just need to split the string with the sign , and then get the second value of the array.你只需要用符号分割字符串,然后得到数组的第二个值。

// value 350011
 const valueFormated = (value).toLocaleString('en-US', {
  style: 'currency',
  currency: 'USD',
 });

 valueFormated.split('$')
 // if you console.log the result would be
 (2) ['', '3,500.11']

 // here is the value formated
 valueFormated.split('$')[1]
 // 3,500.11

Just put options as:只需将选项设置为:

{ minimumFractionDigits: 2, maximumFractionDigits: 2 } { minimumFractionDigits: 2, maximumFractionDigits: 2 }

const s = 1234.567 
const options = { minimumFractionDigits: 2, maximumFractionDigits: 2 }
const result = new Intl.NumberFormat('pt-BR', options).format(s);

according to MDN you can use following format根据 MDN,您可以使用以下格式

new Intl.NumberFormat('de-DE', { maximumSignificantDigits: 3 }).format(number))

use maximumSignificantDigits option only仅使用maximumSignificantDigits选项

这就是你需要做的

new Intl.NumberFormat("en-US").format(6700); //return 6,700.00 without currency,

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM