如何使用特定语言环境的符号格式化货币

为任何语言环境显示正确的货币符号、位置和格式的价格

介绍

货币符号用于标识价格所代表的货币。美元符号表示美元,欧元符号表示欧元,英镑符号表示英镑。这些符号对于国际化应用至关重要,因为用户需要知道他们正在查看或使用的是哪种货币。

不同国家的货币金额格式各不相同。美国人写作 $1,234.56,符号在金额前。德国人写作 1.234,56 €,符号在金额后,且使用不同的分隔符。法国格式为 1 234,56 €,数字组之间使用空格。如果您硬编码货币格式,例如 "$" + amount,就假设了所有用户都遵循相同的惯例。

JavaScript 提供了 Intl.NumberFormat API,用于以符合本地化符号和惯例的方式格式化货币金额。本课程将解释货币格式如何因地区而异,以及如何为任何语言或地区正确格式化价格。

货币符号因地区而异

不同的货币使用不同的符号。美元使用 $,欧元使用 €,英镑使用 £,日元使用 ¥,瑞士法郎根据上下文使用 Fr. 或 CHF。每个符号都帮助用户快速识别他们正在查看的货币。

某些符号代表多种货币。例如,美元符号 $ 用于美元、加元、澳元、墨西哥比索以及其他几种货币。如果没有额外的上下文,用户无法判断价格代表的是哪种美元货币。

货币符号的位置因地区而异。英语国家通常将符号放在金额前,如 $100。许多欧洲国家将符号放在金额后,如 100 €。有些国家在金额和符号之间加空格,而有些则不加。

这些差异意味着您不能简单地将符号和数字拼接在一起。您需要能够理解显示的货币和用户所在地区的格式化逻辑。

使用 Intl.NumberFormat 格式化货币

Intl.NumberFormat 构造函数在选项中传入 style: 'currency' 时会创建一个货币格式化器。您还必须使用 currency 选项指定要格式化的货币,并提供一个 ISO 4217 货币代码。

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

console.log(formatter.format(1234.56));
// 输出: "$1,234.56"

这会创建一个用于美式英语的格式化器,以美元显示金额。format() 方法将数字转换为带有美元符号、千位分隔符和两位小数的字符串。

currency 选项需要一个三字母的 ISO 4217 代码。常见的代码包括 USD(美元)、EUR(欧元)、GBP(英镑)、JPY(日元)和 CAD(加元)。

const usdFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

const eurFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'EUR'
});

const gbpFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'GBP'
});

console.log(usdFormatter.format(100));
// 输出: "$100.00"

console.log(eurFormatter.format(100));
// 输出: "€100.00"

console.log(gbpFormatter.format(100));
// 输出: "£100.00"

每个格式化器会自动插入相应的货币符号。您无需了解每个货币代码对应的符号。

区域设置决定符号位置和格式

区域设置参数控制货币金额的格式,包括符号位置、数字分组和小数分隔符。同一个货币代码在不同的区域设置下会产生不同的输出。

const usFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'EUR'
});

const deFormatter = new Intl.NumberFormat('de-DE', {
  style: 'currency',
  currency: 'EUR'
});

const frFormatter = new Intl.NumberFormat('fr-FR', {
  style: 'currency',
  currency: 'EUR'
});

console.log(usFormatter.format(1234.56));
// 输出: "€1,234.56"

console.log(deFormatter.format(1234.56));
// 输出: "1.234,56 €"

console.log(frFormatter.format(1234.56));
// 输出: "1 234,56 €"

这三个格式化器都显示欧元,但使用了不同的约定。美式英语格式化器将符号放在金额前面,并使用句号作为小数分隔符。德语格式化器将符号放在金额后面,使用空格,并用句号作为千位分隔符,逗号作为小数分隔符。法语格式化器使用空格作为千位分隔符。

Intl API 会根据您指定的区域设置自动处理这些差异。您无需了解每个区域设置的格式规则。

货币格式包括小数位

货币格式化程序会根据货币自动确定适当的小数位数。大多数货币使用两位小数来表示分或等值的分数。

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

console.log(formatter.format(100));
// 输出: "$100.00"

console.log(formatter.format(100.5));
// 输出: "$100.50"

console.log(formatter.format(100.567));
// 输出: "$100.57"

对于美元,格式化程序始终显示两位小数,必要时用零填充,并在输入具有更高精度时进行四舍五入。

某些货币没有小数位。例如,日元没有分的单位,因此金额以整数形式显示。

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'JPY'
});

console.log(formatter.format(1234.56));
// 输出: "¥1,235"

格式化程序会四舍五入到最接近的整数,因为日元金额不包括小数单位。Intl API 知道每种货币的小数精度,并自动应用。

根据用户的区域设置格式化货币

与硬编码特定区域设置不同,您可以使用用户的浏览器语言偏好。navigator.language 属性返回用户的首选区域设置。

const userLocale = navigator.language;

const formatter = new Intl.NumberFormat(userLocale, {
  style: 'currency',
  currency: 'USD'
});

console.log(formatter.format(1234.56));
// 输出因用户的区域设置而异
// 对于 en-US: "$1,234.56"
// 对于 de-DE: "1.234,56 $"
// 对于 fr-FR: "1 234,56 $US"

这种方法根据每个用户的格式化期望显示货币金额。德国用户会看到符号在金额之后并使用德国分隔符,而美国用户会看到符号在金额之前并使用美国分隔符。

您还可以传递整个 navigator.languages 数组,以便在用户的首选项不可用时启用回退行为。

const formatter = new Intl.NumberFormat(navigator.languages, {
  style: 'currency',
  currency: 'USD'
});

console.log(formatter.format(1234.56));

API 使用数组中支持的第一个区域设置,提供自动回退处理。

重用货币格式化器

创建一个新的 Intl.NumberFormat 实例需要加载区域设置数据并处理选项。当您使用相同的区域设置和货币格式化多个价格时,请创建一次格式化器并重复使用。

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

const prices = [19.99, 29.99, 49.99, 99.99];

prices.forEach(price => {
  console.log(formatter.format(price));
});
// 输出:
// "$19.99"
// "$29.99"
// "$49.99"
// "$99.99"

这种模式比为每个价格创建一个新的格式化器更高效。当格式化包含许多值的数组或列表时,性能差异会变得显著。

在应用程序中显示价格

您可以在任何向用户显示价格的地方使用货币格式化器。这包括产品列表、购物车、结账页面、发票和财务仪表板。

const formatter = new Intl.NumberFormat(navigator.language, {
  style: 'currency',
  currency: 'USD'
});

const productPrice = 29.99;
const taxAmount = 2.40;
const totalPrice = productPrice + taxAmount;

document.getElementById('product-price').textContent = formatter.format(productPrice);
document.getElementById('tax-amount').textContent = formatter.format(taxAmount);
document.getElementById('total-price').textContent = formatter.format(totalPrice);

格式化后的字符串与其他字符串值一样。您可以将它们插入到文本内容、属性或任何显示信息给用户的上下文中。

处理多种货币

支持多种货币的应用程序需要为每种货币创建单独的格式化器。货币代码决定显示的符号,而区域设置决定金额的格式。

const locale = navigator.language;

const usdFormatter = new Intl.NumberFormat(locale, {
  style: 'currency',
  currency: 'USD'
});

const eurFormatter = new Intl.NumberFormat(locale, {
  style: 'currency',
  currency: 'EUR'
});

const gbpFormatter = new Intl.NumberFormat(locale, {
  style: 'currency',
  currency: 'GBP'
});

console.log(usdFormatter.format(100));
console.log(eurFormatter.format(100));
console.log(gbpFormatter.format(100));

每个格式化器都会显示适当的符号,并遵循用户区域设置中该货币的约定。这确保了无论使用哪种货币或区域设置组合,价格都既准确又易于阅读。