日期货币格式各写一套太麻烦,用Intl对象做本地化
一、背景:格式化这事别再自己造轮子
做国际化或者只是想让数字好看点,经常要处理日期、货币、百分比的显示。我见过有人为了显示「2026年09月12日」自己拼字符串,为了显示「¥1,234.50」手写 toFixed 加千分位正则。一旦要支持英文「Sep 12, 2026」、美元「$1,234.50」,这套手写逻辑就崩了,得再写一套,越写越乱。
其实浏览器和 Node 都内置了 Intl 这个国际化对象,日期、数字、货币、相对时间它全包了,而且跟着语言标签自动适配。这篇文章讲怎么用,以及几个性能上的注意点。
二、核心代码:日期和货币
日期格式化用 Intl.DateTimeFormat:
const fmt = new Intl.DateTimeFormat('zh-CN', {
year: 'numeric', month: '2-digit', day: '2-digit'
});
console.log(fmt.format(new Date())); // 2026/09/12
const en = new Intl.DateTimeFormat('en-US', {
year: 'numeric', month: 'short', day: 'numeric'
});
console.log(en.format(new Date())); // Sep 12, 2026
货币用 Intl.NumberFormat,传 style: 'currency' 和 currency 代码:
const cny = new Intl.NumberFormat('zh-CN', {
style: 'currency', currency: 'CNY'
});
console.log(cny.format(1234.5)); // ¥1,234.50
const usd = new Intl.NumberFormat('en-US', {
style: 'currency', currency: 'USD'
});
console.log(usd.format(1234.5)); // $1,234.50
不用自己管千分位和小数位,规则全按地区走,比手写正则稳妥太多。
三、相对时间与纯数字
「3 分钟前」这种相对时间,Intl.RelativeTimeFormat 直接给:
const rtf = new Intl.RelativeTimeFormat('zh-CN', { numeric: 'auto' });
console.log(rtf.format(-3, 'minute')); // 3分钟前
console.log(rtf.format(1, 'day')); // 明天
普通数字加千分位、百分比、单位也都能做:
new Intl.NumberFormat('zh-CN').format(1234567); // 1,234,567
new Intl.NumberFormat('zh-CN', { style: 'percent' }).format(0.42); // 42%
这基本能替掉大部分引入 dayjs 做显示格式化的场景,只有需要「解析、计算、复杂时间操作」时才上日期库。
四、重点
第一,时区。默认用的是运行环境的时区。format 不会自动帮你转 UTC,展示「服务器时间」时要显式传 timeZone: 'Asia/Shanghai',否则用户浏览器在哪个时区就显示哪个,前后端对不上。
第二,语言标签写错就降级。zh-CN 能识别,写个不存在的标签浏览器不会报错而是回退到默认格式,显示就会和你预期不一致,标签字符串要写准。
第三,性能。每次 new Intl.DateTimeFormat(...) 都有初始化开销,在列表里成百上千行循环格式化时,别在循环里 new,把 formatter 提到外面缓存复用,速度差几倍。
第四,Node 环境。Node 13 之后默认带完整 ICU 数据,老版本可能只支持 en,需要装 full-icu 才能显示中文格式,部署到服务端格式化时先确认 Node 版本。
第五,它只负责显示不负责解析。Intl 是输出用的,把字符串解析回 Date 还得用 Date 或日期库,别搞反用途。
五、小结
Intl 是浏览器和 Node 自带的国际化工具,日期、货币、百分比、相对时间一行 formatter 就搞定,比手写字符串拼接和正则靠谱。关键记住:时区要显式指定、语言标签写准、formatter 提出循环外缓存、它只管显示不管解析。日常展示类格式化优先用它,需要时间计算再上 dayjs 这类库,分工清楚代码也清爽。
- 点赞
- 收藏
- 关注作者
评论(0)