国际化 API(Intl 对象) ,是 ECMAScript 国际化规范提供的原生工具,用于处理日期、时间、数字、货币、列表、相对时间、复数规则 等与语言文化相关的格式化。它的最大优势是无需第三方库,且能自动适配不同地区(locale)的格式习惯,如千位分隔符、日期顺序、货币符号位置等。
下面分模块详细展开,并附上代码示例。
一、Intl 对象概述
Intl 是一个全局对象,包含多个构造函数 和方法,核心有:
Intl.DateTimeFormat:日期时间格式化Intl.NumberFormat:数字(含货币、百分比、科学计数)格式化Intl.RelativeTimeFormat:相对时间(如"3 天前")Intl.ListFormat:列表格式化(如"A、B 和 C")Intl.PluralRules:单复数规则Intl.Collator:字符串比较(排序)
每个构造函数接受两个主要参数:
locales:地区标识符字符串或数组,如'zh-CN'、'en-US'、'ja-JP'。可选,默认使用运行环境的默认地区。options:格式化选项对象,控制输出的细节。
二、Intl.DateTimeFormat -- 日期时间格式化
基础用法
js
const date = new Date('2026-04-28T15:30:00');
// 中文(简体中国)格式
const dtZh = new Intl.DateTimeFormat('zh-CN');
console.log(dtZh.format(date)); // "2026/4/28"
// 美国英语格式
const dtEn = new Intl.DateTimeFormat('en-US');
console.log(dtEn.format(date)); // "4/28/2026"
// 日本格式
const dtJa = new Intl.DateTimeFormat('ja-JP');
console.log(dtJa.format(date)); // "2026/4/28"
主要选项(options)
js
const options = {
dateStyle: 'full', // 'full' | 'long' | 'medium' | 'short'
timeStyle: 'medium', // 同上
weekday: 'long', // 'narrow' | 'short' | 'long'
year: 'numeric', // '2-digit' | 'numeric'
month: 'long', // 'numeric' | '2-digit' | 'short' | 'long'
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: true, // 是否使用12小时制
timeZone: 'Asia/Shanghai',
};
const formatter = new Intl.DateTimeFormat('zh-CN', options);
console.log(formatter.format(date));
// 输出示例:"2026年4月28日星期二 下午03:30:00"
formatToParts -- 获取格式化后的各段内容
js
const parts = dtZh.formatToParts(date);
// [{type:'year', value:'2026'}, {type:'month', value:'4'}, ...]
使用 Intl.DateTimeFormat 快速格式化内置方法
也可以直接使用 date.toLocaleString(),它在内部调用了 Intl.DateTimeFormat:
js
console.log(date.toLocaleString('zh-CN', { dateStyle: 'long' }));
// "2026年4月28日"
三、Intl.NumberFormat -- 数字、货币、百分比
基础用法
js
const num = 1234567.89;
new Intl.NumberFormat('en-US').format(num); // "1,234,567.89"
new Intl.NumberFormat('de-DE').format(num); // "1.234.567,89"
new Intl.NumberFormat('zh-CN').format(num); // "1,234,567.89"
主要选项
js
const options = {
style: 'currency', // 'decimal'(默认) | 'currency' | 'percent' | 'unit'
currency: 'CNY', // ISO 货币代码,如 'USD', 'EUR', 'JPY', 'CNY'
currencyDisplay: 'symbol', // 'symbol' | 'code' | 'name'
minimumFractionDigits: 2,
maximumFractionDigits: 2,
useGrouping: true, // 是否使用千位分隔符
notation: 'compact', // 'standard' | 'scientific' | 'engineering' | 'compact'
compactDisplay: 'short', // 'short' (1.2万) | 'long' (1.2万)
};
示例
js
// 货币
console.log(new Intl.NumberFormat('zh-CN', { style: 'currency', currency: 'USD' }).format(1234.5));
// "US$1,234.50"
// 百分比
console.log(new Intl.NumberFormat('zh-CN', { style: 'percent' }).format(0.1234));
// "12%"
// 紧凑显示(单位后缀)
console.log(new Intl.NumberFormat('zh-CN', { notation: 'compact' }).format(12500));
// "1.25万"
四、Intl.RelativeTimeFormat -- 相对时间
基础用法
js
const rtf = new Intl.RelativeTimeFormat('zh-CN', { numeric: 'auto' });
console.log(rtf.format(-1, 'day')); // "昨天"
console.log(rtf.format(3, 'day')); // "3天后"
console.log(rtf.format(10, 'minute'));// "10分钟后"
可用的时间单位
'year', 'quarter', 'month', 'week', 'day', 'hour', 'minute', 'second'。
选项
numeric:'always'(总是用数字,如"1天前")或'auto'(可能用"昨天"、"明天")。style:'long'("3 days ago")、'short'("3 days ago" 较短)、'narrow'。
实际应用:计算距今天数
js
function timeAgo(date) {
const rtf = new Intl.RelativeTimeFormat('zh-CN', { numeric: 'auto' });
const diffDays = Math.round((date - new Date()) / (1000 * 60 * 60 * 24));
return rtf.format(diffDays, 'day');
}
console.log(timeAgo(new Date('2026-04-26'))); // 2天前(取决于今天日期)
五、Intl.ListFormat -- 列表连接
基础用法
js
const list = ['苹果', '香蕉', '橘子'];
const lf = new Intl.ListFormat('zh-CN', { style: 'long', type: 'conjunction' });
console.log(lf.format(list)); // "苹果、香蕉和橘子"
选项
style:'long'("A, B, and C")、'short'、'narrow'(通常无逗号)。type:'conjunction'("和")、'disjunction'("或")、'unit'("米/秒"风格)。
六、Intl.PluralRules -- 单复数判定
主要用于根据数字选择正确词形(如英语中的 1 book / 2 books)。中文场景相对简单,但对某些语言必须。
js
const pr = new Intl.PluralRules('en-US');
console.log(pr.select(1)); // "one"
console.log(pr.select(2)); // "other"
七、Intl.Collator -- 语言敏感的字符串比较(排序)
js
const names = ['张三', '李四', '王五', '陈六'];
const collator = new Intl.Collator('zh-CN', { sensitivity: 'base' });
names.sort(collator.compare);
console.log(names); // 按拼音排序
八、关键知识点与注意事项
1. 地区标识符(locale)
- 标准格式:
语言-国家/地区(如zh-CN、en-GB、zh-TW)。 - 可以使用
-u-扩展指定更多细则,如zh-CN-u-ca-chinese(使用农历)。
2. 性能影响
- 通常每次构造
Intl对象有一定开销。如果频繁使用,应将构造好的实例缓存起来复用。
3. 浏览器兼容性
- 主流现代浏览器和 Node.js 均完美支持。老旧浏览器(如 IE11)不支持,但如今基本可忽略。
4. 与 Date.prototype.toLocaleString / Number.prototype.toLocaleString 的关系
- 这些原型方法是
IntlAPI 的简易封装。两者选其一均可,但Intl构造函数更清晰地隔离配置,且在需要多次调用同一格式时性能更好(复用实例)。
九、实际项目组合示例
js
// 格式化当前时间 + 金额总计
const now = new Date();
const price = 12345.6;
const dateFormatter = new Intl.DateTimeFormat('zh-CN', { dateStyle: 'full', timeStyle: 'medium' });
const moneyFormatter = new Intl.NumberFormat('zh-CN', { style: 'currency', currency: 'CNY' });
console.log(`订单时间:${dateFormatter.format(now)}`);
console.log(`总金额:${moneyFormatter.format(price)}`);
// 输出示例:
// 订单时间:2026年4月28日星期二 下午03:30:00
// 总金额:¥12,345.60
总结
Intl 对象是 JavaScript 原生国际化方案的基石,它:
- 消除了手工拼接数字、日期的繁琐。
- 自动处理不同地区文化习惯(尽管中文和英文习惯差异不大,但对德、法、阿拉伯语等差异很大)。
- 无需引入 moment.js / numeral.js 等库,性能更好,体积更小。
在你的日常开发中,如果需要跨地区展示 或严格遵循本地化格式 ,应优先使用 Intl API。对于简单的不涉及本地化的场景(如仅拼接字符串),模板字符串仍然是最轻量的选择。
如果还有关于某个具体构造函数或选项的疑问,欢迎继续提问!