Intl 国际化基础
使用 Intl 对日期、数字、相对时间进行本地化格式化。
javascript
// 数字格式
const nf = new Intl.NumberFormat("zh-CN", {
style: "currency",
currency: "CNY",
});
console.log(nf.format(1234.5)); // ¥1,234.50
// 日期时间
const df = new Intl.DateTimeFormat("en-GB", {
dateStyle: "long",
timeStyle: "short",
});
console.log(df.format(new Date()));
// 相对时间
const rtf = new Intl.RelativeTimeFormat("zh-CN", { numeric: "auto" });
console.log(rtf.format(-1, "day")); // 昨天
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
场景:多语言 UI、地区化显示。
NumberFormat 更深入
javascript
new Intl.NumberFormat("de-DE").format(1234567.89); // '1.234.567,89'
new Intl.NumberFormat("en-US", { style: "percent" }).format(0.1234); // '12%'
// 货币
new Intl.NumberFormat("ja-JP", { style: "currency", currency: "JPY" }).format(
1234
);
1
2
3
4
5
6
7
2
3
4
5
6
7
参数提示:maximumFractionDigits
、minimumIntegerDigits
、notation: 'compact'
(如 1.2K)。
DateTimeFormat:时区与样式
javascript
new Intl.DateTimeFormat("zh-CN", {
dateStyle: "medium",
timeStyle: "short",
}).format(new Date());
// 指定时区
new Intl.DateTimeFormat("en-US", {
timeZone: "UTC",
timeStyle: "short",
}).format(new Date());
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
注意:时区、历法(如 calendar: 'gregory'
)与数字系统(如 numberingSystem
)。
RelativeTimeFormat:相对时间
javascript
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
rtf.format(-1, "day"); // 'yesterday'
rtf.format(2, "hour"); // 'in 2 hours'
1
2
3
2
3
ListFormat 与 DisplayNames
javascript
// 列表格式化
new Intl.ListFormat("en", { style: "long", type: "conjunction" }).format([
"A",
"B",
"C",
]);
// => 'A, B, and C'
// 地区/语言/脚本显示名
new Intl.DisplayNames(["en"], { type: "region" }).of("CN"); // 'China'
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
Segmenter:本地化分词
javascript
const seg = new Intl.Segmenter("zh", { granularity: "word" });
const input = "今天下雨了";
console.log(Array.from(seg.segment(input), (x) => x.segment));
1
2
3
2
3
用于按语言切词、光标移动、文本高亮等。
语言协商与回退
Intl
会根据传入的 locale 列表与系统支持度选择最匹配的语言(language negotiation)。建议传入优先列表:
javascript
new Intl.NumberFormat(["zh-Hans-CN", "zh-CN", "en-US"]).format(1000);
1
常见陷阱
- 时区不一致导致时间显示错乱(服务器与客户端差异);
- 货币小数位差异(JPY 没有小数);
- 不同浏览器/平台对某些 Intl API 支持度不同(需降级或 Polyfill)。
最佳实践
- 将
locale
存在用户设置中,并在所有格式化 API 统一使用; - 尽量使用
dateStyle/timeStyle
等高层选项; - 金额使用
NumberFormat
的货币样式,不手写格式化; - 为老设备准备 Polyfill(如
@formatjs/intl-*
)。
练习
- 实现一个
formatAmount(amount, currency, locale)
返回本地化货币字符串; - 实现一个根据用户语言设置的“相对时间”提示组件(
Intl.RelativeTimeFormat
); - 使用
Intl.Segmenter
将一段中文文本按词切分,并高亮每个词。