在跨语言、跨地区的应用开发中,国际化格式化是核心需求之一,实现一套独立的JavaScript国际化格式化库,可以灵活适配不同项目的多语言场景,避免依赖过重的第三方库。我们可以从基础能力拆分出发,一步步搭建这个库的核心功能。

核心需求梳理
一个基础的国际化格式化库需要覆盖以下核心场景:
- 支持多
locale(区域设置)切换,比如zh-CN、en-US等 - 日期时间的区域化格式化,比如中文显示2024年5月1日,英文显示May 1, 2024
- 数字的格式化,包括千分位分隔、小数位处理、货币格式等
- 字符串翻译能力,支持带参数的翻译文本替换
- 可扩展的配置机制,方便后续新增区域规则
基础架构设计
我们首先定义库的整体结构,核心是一个I18n类,对外暴露初始化、切换区域、各类格式化方法:
// 基础I18n类结构
class I18n {
constructor(options = {}) {
// 默认区域
this.locale = options.locale || 'zh-CN';
// 区域对应的格式化规则配置
this.localeConfigs = options.localeConfigs || {};
// 翻译字典
this.messages = options.messages || {};
}
// 切换区域
setLocale(locale) {
this.locale = locale;
}
// 获取当前区域的配置
getConfig() {
return this.localeConfigs[this.locale] || {};
}
}
export default I18n;
日期时间格式化实现
日期格式化需要根据不同区域的规则,拼接年、月、日、时、分、秒的展示形式,我们可以先定义不同区域的日期模板:
// 区域日期配置示例
const localeDateConfigs = {
'zh-CN': {
dateTemplate: 'YYYY年MM月DD日',
timeTemplate: 'HH时mm分ss秒',
monthNames: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
dayNames: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
},
'en-US': {
dateTemplate: 'MM/DD/YYYY',
timeTemplate: 'HH:mm:ss',
monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
}
};
// 给I18n类添加日期格式化方法
I18n.prototype.formatDate = function(date, type = 'date') {
const config = this.getConfig();
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
const hours = String(d.getHours()).padStart(2, '0');
const minutes = String(d.getMinutes()).padStart(2, '0');
const seconds = String(d.getSeconds()).padStart(2, '0');
let template = type === 'date' ? config.dateTemplate : config.timeTemplate;
if (!template) {
template = type === 'date' ? 'YYYY-MM-DD' : 'HH:mm:ss';
}
return template
.replace('YYYY', year)
.replace('MM', month)
.replace('DD', day)
.replace('HH', hours)
.replace('mm', minutes)
.replace('ss', seconds);
};
数字格式化实现
数字格式化主要处理千分位分隔、小数位保留、货币符号添加等场景,同样基于区域配置实现:
// 区域数字配置示例
const localeNumberConfigs = {
'zh-CN': {
thousandSeparator: ',',
decimalSeparator: '.',
currencySymbol: '¥'
},
'en-US': {
thousandSeparator: ',',
decimalSeparator: '.',
currencySymbol: '$'
}
};
// 给I18n类添加数字格式化方法
I18n.prototype.formatNumber = function(num, options = {}) {
const config = this.getConfig();
const {
decimals = 2,
currency = false
} = options;
// 处理小数位
let fixedNum = Number(num).toFixed(decimals);
let [integerPart, decimalPart] = fixedNum.split('.');
// 添加千分位分隔
const thousandSep = config.thousandSeparator || ',';
integerPart = integerPart.replace(/B(?=(d{3})+(?!d))/g, thousandSep);
let result = integerPart;
if (decimalPart !== undefined) {
const decimalSep = config.decimalSeparator || '.';
result += decimalSep + decimalPart;
}
// 处理货币格式
if (currency) {
const symbol = config.currencySymbol || '';
result = symbol + result;
}
return result;
};
字符串翻译实现
字符串翻译需要支持从翻译字典中匹配对应区域的文本,同时支持参数替换:
// 翻译字典示例
const messages = {
'zh-CN': {
'hello': '你好',
'welcome': '欢迎,{name}',
'cart_count': '购物车有{count}件商品'
},
'en-US': {
'hello': 'Hello',
'welcome': 'Welcome, {name}',
'cart_count': 'There are {count} items in the cart'
}
};
// 给I18n类添加翻译方法
I18n.prototype.t = function(key, params = {}) {
const localeMessages = this.messages[this.locale] || {};
let text = localeMessages[key] || key;
// 替换参数
Object.keys(params).forEach(paramKey => {
const reg = new RegExp(`\{${paramKey}\}`, 'g');
text = text.replace(reg, params[paramKey]);
});
return text;
};
完整使用示例
将以上模块整合后,我们可以按照如下方式使用这个国际化格式化库:
// 初始化i18n实例
const i18n = new I18n({
locale: 'zh-CN',
localeConfigs: {
...localeDateConfigs,
...localeNumberConfigs
},
messages: messages
});
// 日期格式化
console.log(i18n.formatDate(new Date())); // 输出类似 2024年05月01日
console.log(i18n.formatDate(new Date(), 'time')); // 输出类似 14时30分00秒
// 数字格式化
console.log(i18n.formatNumber(1234567.89)); // 输出 1,234,567.89
console.log(i18n.formatNumber(1234567.89, { currency: true })); // 输出 ¥1,234,567.89
// 切换区域到英文
i18n.setLocale('en-US');
console.log(i18n.formatDate(new Date())); // 输出类似 05/01/2024
console.log(i18n.formatNumber(1234567.89, { currency: true })); // 输出 $1,234,567.89
// 字符串翻译
console.log(i18n.t('hello')); // 输出 Hello
console.log(i18n.t('welcome', { name: '张三' })); // 输出 Welcome, 张三
扩展建议
以上实现是基础版本,实际使用中可以根据需求扩展更多能力:
- 添加更多区域的内置配置,覆盖更多小语种场景
- 支持相对时间格式化,比如刚刚、1小时前、1天前等
- 支持复数规则处理,比如英文中1 item和2 items的差异
- 支持从外部文件加载翻译字典和区域配置,减少主包体积
通过这样的模块化实现,我们可以灵活控制库的体积和功能,完全适配项目的实际国际化需求。
i18nJavaScript国际化格式化库locale修改时间:2026-06-11 08:12:21