JavaScript 国际化 API

深入解析 JavaScript Intl API:DateTimeFormat 的日期格式化、NumberFormat 的数字格式化、Collator 的字符串排序,以及 PluralRules 的复数处理。

为什么国际化是现代 Web 应用必备功能

现代 Web 应用面向全球用户,国际化(i18n)和本地化(l10n)是必备功能。JavaScript 内置的 Intl API 提供了语言敏感的日期、数字、字符串格式化能力,是前端国际化的基础。


一、Intl API 概述

1.1 Intl 对象

console.log(Intl.DateTimeFormat); // 构造函数
console.log(Intl.NumberFormat);   // 构造函数
console.log(Intl.Collator);       // 构造函数
console.log(Intl.PluralRules);   // 构造函数

1.2 Locale 标识符

// BCP 47 语言标签格式
'en-US';      // 英语(美国)
'zh-CN';      // 中文(中国)
'ja-JP';      // 日语(日本)
'de-DE';      // 德语(德国)
'en-GB';      // 英语(英国)

二、DateTimeFormat

2.1 基本用法

const date = new Date('2024-04-15T10:30:00');

new Intl.DateTimeFormat('en-US').format(date); // '4/15/2024'
new Intl.DateTimeFormat('zh-CN').format(date); // '2024/4/15'
new Intl.DateTimeFormat('ja-JP').format(date); // '2024/4/15'

2.2 格式化选项

const options = {
  year: 'numeric',
  month: 'long',
  day: 'numeric',
  weekday: 'long',
  hour: '2-digit',
  minute: '2-digit',
  second: '2-digit',
  timeZoneName: 'short'
};

new Intl.DateTimeFormat('en-US', options).format(date);
// 'Monday, April 15, 2024 at 10:30:00 AM PDT'

2.3 相对时间格式化

const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });

rtf.format(-1, 'day');   // 'yesterday'
rtf.format(0, 'day');    // 'today'
rtf.format(1, 'day');    // 'tomorrow'
rtf.format(7, 'day');    // 'in 7 days'
rtf.format(-2, 'week');   // '2 weeks ago'

三、NumberFormat

3.1 基本数字格式化

const num = 1234567.89;

new Intl.NumberFormat('en-US').format(num);  // '1,234,567.89'
new Intl.NumberFormat('zh-CN').format(num);  // '1,234,567.89'
new Intl.NumberFormat('de-DE').format(num); // '1.234.567,89'
new Intl.NumberFormat('fr-FR').format(num); // '1 234 567,89'

3.2 货币格式化

const amount = 1234.56;

new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
}).format(amount); // '$1,234.56'

new Intl.NumberFormat('zh-CN', {
  style: 'currency',
  currency: 'CNY'
}).format(amount); // '¥1,234.56'

new Intl.NumberFormat('ja-JP', {
  style: 'currency',
  currency: 'JPY'
}).format(amount); // '¥1,235' (无小数)

3.3 百分比格式化

const percent = 0.75;

new Intl.NumberFormat('en-US', {
  style: 'percent'
}).format(percent); // '75%'

3.4 单位格式化

new Intl.NumberFormat('en-US', {
  style: 'unit',
  unit: 'kilometer-per-hour'
}).format(50); // '50 km/h'

四、Collator

4.1 字符串排序

const fruits = ['apple', 'Banana', 'cherry', 'DATE'];

const enCollator = new Intl.Collator('en');
const sorted = fruits.sort((a, b) => enCollator.compare(a, b));
console.log(sorted); // ['apple', 'Banana', 'cherry', 'DATE']

4.2 敏感度选项

const collator = new Intl.Collator('en', {
  sensitivity: 'base' // 忽略大小写和重音
});

console.log(collator.compare('apple', 'APPLE')); // 0 (相等)
console.log(collator.compare('café', 'cafe'));   // 0 (相等)

4.3 中文排序

const zhNames = ['张三', '李四', '王五', '赵六', '孙七'];

// 按拼音排序
const pinyinCollator = new Intl.Collator('zh-CN', {
  sensitivity: 'base'
});
zhNames.sort((a, b) => pinyinCollator.compare(a, b));
console.log(zhNames); // 拼音顺序

五、PluralRules

5.1 复数规则

const pr = new Intl.PluralRules('en');

console.log(pr.select(0)); // 'other' (zero)
console.log(pr.select(1)); // 'one' (one)
console.log(pr.select(2)); // 'other' (two)
console.log(pr.select(3)); // 'other'

5.2 选择规则

const pr = new Intl.PluralRules('en', { type: 'ordinal' });

console.log(pr.select(1));  // 'one' (1st)
console.log(pr.select(2));  // 'two' (2nd)
console.log(pr.select(3));  // 'few' (3rd)
console.log(pr.select(4));  // 'other' (4th)

六、ListFormat

6.1 列表格式化

const items = ['Apple', 'Banana', 'Cherry'];

new Intl.ListFormat('en', { style: 'long', type: 'conjunction' }).format(items);
// 'Apple, Banana, and Cherry'

new Intl.ListFormat('en', { style: 'short', type: 'disjunction' }).format(items);
// 'Apple, Banana, or Cherry'

new Intl.ListFormat('zh-CN', { style: 'long', type: 'conjunction' }).format(items);
// 'Apple、 Banana 和 Cherry'

七、面试高频考点

考点 1:Intl API 的核心功能

Intl API 提供语言敏感的格式化能力,包括日期、数字、字符串排序、复数规则等。

考点 2:Locale 标识符

BCP 47 格式,如 'en-US'、'zh-CN'、'ja-JP'。

考点 3:DateTimeFormat 的格式化选项

year、month、day、hour、minute、second 等选项可以精确控制输出格式。


延展阅读