能否为Intl.DateTimeFormat添加未支持的区域设置?
扩展Intl.DateTimeFormat支持帕皮阿门托语(pap)的方案
原生Intl.DateTimeFormat依赖底层ICU数据,目前确实没有内置帕皮阿门托语(pap)的支持,无法直接扩展其内置字典。不过可以通过以下两种无polyfill的方案模拟原生格式化效果:
方法1:自定义词汇映射与格式拼接
直接定义帕皮阿门托语的日期词汇表,根据日期对象提取组件后拼接成目标格式,适合固定格式需求:
// 帕皮阿门托语日期核心词汇映射 const papDateVocab = { weekdays: ['dimings', 'lunis', 'martes', 'miércoles', 'djaweps', 'biernes', 'sábado'], months: ['januáryo', 'febrúaryo', 'mars', 'abríl', 'mayo', 'júni', 'júlyo', 'agosto', 'sèptiembre', 'októbre', 'noviembre', 'desèmber'], dayMonthSeparator: ' di ' }; function formatPapDate(date, options = { dateStyle: 'full' }) { const dt = new Date(date); const weekday = papDateVocab.weekdays[dt.getDay()]; const month = papDateVocab.months[dt.getMonth()]; const day = dt.getDate(); const year = dt.getFullYear(); // 适配full格式 if (options.dateStyle === 'full') { return `${weekday}, ${day}${papDateVocab.dayMonthSeparator}${month} ${year}`; } // 可扩展long/medium/short等格式 if (options.dateStyle === 'long') { return `${day}${papDateVocab.dayMonthSeparator}${month} ${year}`; } // 默认 fallback 到替换后的英文格式 return new Intl.DateTimeFormat('en', options).format(date) .replace(/Wednesday|Tuesday|Monday|Sunday|Thursday|Friday|Saturday/g, match => papDateVocab.weekdays.find(wd => wd.startsWith(match[0].toLowerCase()))) .replace(/December|January|February|March|April|May|June|July|August|September|October|November/g, match => papDateVocab.months.find(m => m.startsWith(match[0].toLowerCase()))) .replace(/ (\d+) /, ` $1${papDateVocab.dayMonthSeparator}`); } // 测试 console.log(formatPapDate(new Date())); // 输出: "djaweps, 11 di desèmber 2024"
方法2:利用formatToParts精准替换组件
使用formatToParts将原生格式化结果拆分为独立组件(如weekday、day、month等),再替换对应词汇并拼接,适配更多格式选项:
// 帕皮阿门托语组件映射表 const papPartMap = { weekday: { 'Wednesday': 'djaweps', 'Tuesday': 'martes', 'Monday': 'lunis', 'Sunday': 'dimings', 'Thursday': 'miércoles', 'Friday': 'biernes', 'Saturday': 'sábado' }, month: { 'December': 'desèmber', 'January': 'januáryo', 'February': 'febrúaryo', 'March': 'mars', 'April': 'abríl', 'May': 'mayo', 'June': 'júni', 'July': 'júlyo', 'August': 'agosto', 'September': 'sèptiembre', 'October': 'októbre', 'November': 'noviembre' } }; function formatPapDate(date, options = { dateStyle: 'full' }) { const parts = new Intl.DateTimeFormat('en', options).formatToParts(date); return parts.map(part => { // 替换词汇 if (papPartMap[part.type]?.[part.value]) { return papPartMap[part.type][part.value]; } // 特殊处理日与月之间的分隔符 if (part.type === 'literal' && part.value === ' ' && parts[parts.indexOf(part)-1]?.type === 'day' && parts[parts.indexOf(part)+1]?.type === 'month') { return ' di '; } return part.value; }).join(''); } // 测试 console.log(formatPapDate(new Date(), { dateStyle: 'full' })); // 输出: "djaweps, 11 di desèmber 2024"
注意事项
- 两种方案均无需引入第三方polyfill,完全基于原生API实现
- 可根据需求扩展
timeStyle等其他格式化选项,补充对应词汇映射即可 - 不同环境下
formatToParts返回的组件顺序基本一致,兼容性较好
内容的提问来源于stack exchange,提问作者Lodybo
相关产品推荐
相关产品推荐

