使用不带货币符号的 Intl.NumberFormat 进行货币格式化
Posted
技术标签:
【中文标题】使用不带货币符号的 Intl.NumberFormat 进行货币格式化【英文标题】:Currency formatting using Intl.NumberFormat without currency symbol 【发布时间】:2021-07-27 16:58:10 【问题描述】:我正在尝试使用 Intl 作为默认货币格式化程序,它几乎是完美的。
使用Intl.NumberFormat() constructor 中的示例:
const number = 123456.789;
console.log(new Intl.NumberFormat('de-DE', style: 'currency',
currency: 'EUR' ).format(number)); // expected output: "123.456,79 €"
// the Japanese yen doesn't use a minor unit
console.log(new Intl.NumberFormat('ja-JP', style: 'currency', currency: 'JPY'
).format(number)); // expected output: "¥123,457"
这几乎是完美的,但我实际上想从输出中删除符号。所以我希望看到:
// expected output: "123.456,79"
// expected output: "123,457"
奇怪的是,我花了一个多小时寻找解决方案,却只发现了某种替换/修剪用法。
为什么没有一个选项来格式化具有所有 Intl 功能的数字,而只删除货币符号?!?
希望我错过了,tbh。
【问题讨论】:
【参考方案1】:实现您想要的一种简单方法是使用String#replace()
从字符串中删除货币。为简化此操作,您可以将 currencyDisplay
设置为 "code"
,这将使用 ISO 货币代码 - 与传递给 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
这可以提取成一个函数:
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();
允许您进行更多控制的另一种方法是使用Intl.NumberFormat#formatToParts()
,它会格式化数字,但会为您提供可以以编程方式使用和操作的令牌。例如,使用locale = "de-DE"
和currency = "EUR"
的方法会得到以下输出:
[
"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"
]
这意味着您可以轻松过滤掉"type": "currency"
,然后将其余部分组合成一个字符串。例如:
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")
.map(x => x.value)
.join("")
.trim()
【讨论】:
感谢您的调查。我理解你说移除货币可能是一件奇怪的事情,但我不这么认为。我的用例是在表格列中显示成本。我不想在每个单元格中重复该符号。我只想将它添加到标题中。对我来说,格式和符号是两个不同的东西。在我看来,任何想以这种方式实现它的人都犯了一个错误。至少他们应该添加currencyDisplay: "none"
是的,我同意currencyDisplay: "none"
最有意义。但是,(在这里推测)设计者可能认为不需要它,因为可以移除货币。没有把握。也就是说,如果这是有意没有添加的。这可能是一个无意的遗漏。
话虽如此,我才发现昨天我显然完全失明了。我确实搜索了.formatToParts()
,我知道它存在日期但不知何故没有看到NumberFormat。我已将其添加为选项。
哈! .formatToParts()
正是我在当前实现中所拥有的!非常好!以上是关于使用不带货币符号的 Intl.NumberFormat 进行货币格式化的主要内容,如果未能解决你的问题,请参考以下文章