【问题标题】:Currency formatting using Intl.NumberFormat without currency symbol使用不带货币符号的 Intl.NumberFormat 进行货币格式化
【发布时间】: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。

【问题讨论】:

    标签: javascript number-formatting


    【解决方案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() 正是我在当前实现中所拥有的!非常好!
    猜你喜欢
    • 2019-02-23
    • 2012-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多