如何使用百分号格式化百分比
使用 Intl.NumberFormat 的 percent 样式,根据不同语言环境以本地化方式显示百分比
简介
百分比在许多应用场景中都会出现,比如显示进度、利率或折扣金额。简单地将数字和百分号拼接虽然适用于基础场景,但无法满足不同语言和地区对百分比格式的要求。例如,在土耳其语中,百分号出现在数字前面,如 %50;法语中,数字和百分号之间有空格,如 50 %;阿拉伯语则使用专用的百分号字符,而不是标准的 % 符号。
JavaScript 的 Intl.NumberFormat API 能自动处理这些格式差异。只需将 style 选项设置为 "percent",即可为任意语言环境生成正确的百分比格式,无需编写特定于地区的代码。
为什么百分比格式因语言环境而异
不同语言环境对百分号的位置和空格有不同的规则。英语中,百分号紧跟在数字后面且无空格;法语中,数字和百分号之间有空格;土耳其语中,百分号位于数字前。这些差异反映了各自语言的阅读习惯和书写规范。
格式差异不仅体现在百分号的位置上,有些语言环境还会使用不同的百分号字符。例如,阿拉伯语使用 ٪(U+066A)而不是 ASCII 百分号。此外,小数点和千位分隔符的用法也会因地区而异,就像普通数字格式一样。
如果通过字符串拼接来硬编码百分比格式,所有用户都会看到同一种格式。例如,法国用户看到 50% 而不是 50 %,会觉得不自然;土耳其用户看到 50% 而不是期望的 %50 也会有同样的问题。Intl API 能根据不同语言环境自动应用正确的格式规则,解决这些问题。
将数字格式化为百分比
style 选项在 Intl.NumberFormat 中用于控制数字的格式化方式,可以设为普通数字、货币、百分比或单位。将 style 设置为 "percent",即可将数字格式化为百分比。
const formatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
console.log(formatter.format(0.75));
// Output: "75%"
console.log(formatter.format(0.05));
// Output: "5%"
console.log(formatter.format(1.5));
// Output: "150%"
格式化器会自动将输入值乘以 100,并添加百分号。这意味着你需要传入小数值。比如 0.75 会显示为 75%,1.5 会显示为 150%。
这种小数输入的约定与数学和大多数编程计算中的百分比用法一致。当你计算增长率或完成率等百分比时,结果通常是 0 到 1 之间的小数。你可以直接将这个值传递给格式化器,无需先转换为百分比。
理解小数输入值
百分比格式化器期望输入为小数,其中 1.0 代表 100%。这种设计与代码中百分比的计算方式一致。
const formatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
// Calculating completion percentage
const completed = 75;
const total = 100;
const ratio = completed / total;
console.log(formatter.format(ratio));
// Output: "75%"
// Calculating growth rate
const oldValue = 1000;
const newValue = 1250;
const growth = (newValue - oldValue) / oldValue;
console.log(formatter.format(growth));
// Output: "25%"
当你用已完成数除以总数时,得到 0.75。直接传递给格式化器后,会显示为 75%。当你计算增长率(变化量与原始值的比值)时,得到 0.25,格式化器会显示为 25%。
这种做法可以避免开发者在格式化前手动乘以 100,导致出现 7500% 而不是 75% 这样的常见错误。格式化器会自动处理乘法,你只需在代码中使用自然的小数表示。
处理超出 0-1 范围的数值
百分比并不局限于 0% 到 100% 之间。小于零的值表示负百分比,大于 1.0 的值表示超过 100% 的百分比。
const formatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
console.log(formatter.format(-0.15));
// Output: "-15%"
console.log(formatter.format(2.5));
// Output: "250%"
console.log(formatter.format(0.0025));
// Output: "0%"
负值会以负号格式显示。这对于展示减少、亏损或负增长率非常有用。大于 1.0 的数值会以超过 100% 的百分比格式显示,这在展示同比增长或新值超过基准值的对比时很常见。
由于默认的精度设置,非常小的数值可能会四舍五入为 0%。例如,值 0.0025(即 0.25%)会显示为 0%,因为百分比的默认最大小数位数为 0。下一节将介绍如何控制小数位数,以便准确显示这些较小的百分比。
在不同语言环境下格式化百分比
百分比格式会根据你指定的语言环境自动适配。每个语言环境都有自己的符号位置、空格和符号规则。
const enFormatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
console.log(enFormatter.format(0.5));
// Output: "50%"
const frFormatter = new Intl.NumberFormat("fr-FR", {
style: "percent"
});
console.log(frFormatter.format(0.5));
// Output: "50 %"
const trFormatter = new Intl.NumberFormat("tr-TR", {
style: "percent"
});
console.log(trFormatter.format(0.5));
// Output: "%50"
const arFormatter = new Intl.NumberFormat("ar-SA", {
style: "percent"
});
console.log(arFormatter.format(0.5));
// Output: "٪50"
英语将百分号紧跟在数字后面。法语在百分号前加一个空格。土耳其语将百分号放在数字前面。阿拉伯语使用阿拉伯百分号,并遵循从右到左的文本方向。
这些差异会根据 locale 参数自动处理,无需编写条件逻辑来适配不同语言环境。只需使用用户的 locale 创建格式化器,即可生成该语言环境下正确的输出。
控制百分比的小数位数
默认情况下,百分比格式不显示小数位。例如,0.755 会四舍五入为 76%。你可以通过 minimumFractionDigits 和 maximumFractionDigits 选项来控制小数位数。
const defaultFormatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
console.log(defaultFormatter.format(0.755));
// Output: "76%"
const oneDecimalFormatter = new Intl.NumberFormat("en-US", {
style: "percent",
minimumFractionDigits: 1,
maximumFractionDigits: 1
});
console.log(oneDecimalFormatter.format(0.755));
// Output: "75.5%"
const twoDecimalFormatter = new Intl.NumberFormat("en-US", {
style: "percent",
minimumFractionDigits: 2,
maximumFractionDigits: 2
});
console.log(twoDecimalFormatter.format(0.755));
// Output: "75.50%"
minimumFractionDigits 选项确保格式化器至少显示指定数量的小数位数,如有需要会补零。maximumFractionDigits 选项则限制小数位数,必要时会对数值进行四舍五入。
将两者设置为相同的值可以确保所有百分比的格式保持一致。这在需要所有百分比在表格和图表中视觉对齐时非常有用。
下一课将更深入地讲解小数位数的控制,包括如何处理末尾的零以及如何准确显示非常小的百分比。
百分比与符号显示的结合
百分比格式化可与 signDisplay 选项配合使用,显式显示正百分比的加号。当需要展示变化或增长率,并且符号用于指示方向时,这非常有用。
const formatter = new Intl.NumberFormat("en-US", {
style: "percent",
signDisplay: "always",
minimumFractionDigits: 1,
maximumFractionDigits: 1
});
console.log(formatter.format(0.0523));
// Output: "+5.2%"
console.log(formatter.format(-0.0341));
// Output: "-3.4%"
console.log(formatter.format(0));
// Output: "+0.0%"
signDisplay 选项已在前面的课程中介绍过。与百分比格式化结合使用时,可以明确百分比是表示增长还是减少。如果没有显式加号,在同时显示增减的场景下,正百分比可能会产生歧义。
百分比格式化零值
零默认格式化为 0%。如何处理零取决于零是表示无变化、无数值还是有意义的测量值。
const formatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
console.log(formatter.format(0));
// Output: "0%"
const withSignFormatter = new Intl.NumberFormat("en-US", {
style: "percent",
signDisplay: "exceptZero"
});
console.log(withSignFormatter.format(0.05));
// Output: "+5%"
console.log(withSignFormatter.format(0));
// Output: "0%"
使用 signDisplay: "exceptZero" 时,正负百分比会显示符号,但零不会显示符号。当零表示中性状态(如无变化)时,这样可以使其在视觉上更为突出。
何时使用百分比格式化
在显示自然以百分比表达的比率、速率或比例时,应使用百分比格式化。常见用例包括完成进度、利率、折扣金额、增长率、成功率和概率值等。
如果需要百分号在所有语言环境下都出现在特定位置,则不应使用百分比格式化。如果设计要求百分号始终出现在右侧以保持视觉一致性,应使用字符串拼接。但这样会牺牲国际化的正确性。
在处理已经乘以 100 的数值时,也要避免使用百分比格式化。如果你的数据以整数形式存储百分比(例如 75 表示 75%),请在格式化前先除以 100,或者直接使用普通数字格式并手动添加百分号。
理解百分比格式化的精度
百分比格式化的默认精度为 0 位小数。这与普通数字格式化不同,后者会根据输入值自动调整精度。百分比格式化会将数值四舍五入为整数百分比,除非你明确设置小数位数选项。
const formatter = new Intl.NumberFormat("en-US", {
style: "percent"
});
console.log(formatter.format(0.755));
// Output: "76%"
console.log(formatter.format(0.754));
// Output: "75%"
console.log(formatter.format(0.001));
// Output: "0%"
数值会四舍五入到最接近的整数百分比。例如,0.755 会四舍五入为 76%,0.754 会四舍五入为 75%。像 0.001 这样非常小的数值会四舍五入为 0%。
如果需要显示较小的百分比或带小数的百分比,请增加最大小数位数。下一课将详细介绍精度控制。