Angular中如何通过ng-translate实现日期的多语言本地化翻译?
用ng-translate实现多语言日期格式化的解决方案
这个需求我之前处理过,核心是得把翻译字符串模板和日期本地化格式化结合起来——毕竟不同语言不仅是文字差异,还有日期的显示规则(比如法语日在月前面,英语要加序数词,德语有自己的时间后缀)。下面是具体的实现步骤,非常好上手:
1. 先配置各语言的翻译文件
首先给英语、法语、德语分别准备翻译模板,把日期里动态变化的部分用占位符标记出来,这样后面可以把格式化好的日期片段填进去:
英语(en.json)
{ "DATE_DISPLAY": "{{month}} {{dayWithOrdinal}} at {{time}}" }
法语(fr.json)
{ "DATE_DISPLAY": "Le {{day}} {{month}} à {{time}}" }
德语(de.json)
{ "DATE_DISPLAY": "{{day}}. {{month}} um {{time}}" }
2. 处理日期的本地化格式化(关键步骤)
单纯的占位符不够,我们需要把日期拆解成符合各语言要求的片段:比如英语要带序数词的日期、法语要24小时制加"h"后缀、德语要日期加小数点。这里有两种常用的实现方式:
方式一:在控制器里处理(适合单页面场景)
注入$translate和Angular的DatePipe,根据当前语言格式化日期的各个部分,再拼进翻译模板:
app.controller('YourDateController', function($scope, $translate, $filter) { const datePipe = $filter('date'); const yourTargetDate = new Date('2024-12-24T13:00:00'); // 你的目标日期 // 获取本地化后的日期字符串 $scope.getLocalizedDate = function() { return $translate('DATE_DISPLAY').then(translationTemplate => { const currentLang = $translate.use(); let day, month, time; switch(currentLang) { case 'en': // 英语:月份全称、带序数词的日期、12小时制时间 month = datePipe(yourTargetDate, 'MMMM', 'en'); const dayNum = yourTargetDate.getDate(); const ordinalSuffix = getEnglishOrdinal(dayNum); time = datePipe(yourTargetDate, 'h a', 'en'); return translationTemplate .replace('{{month}}', month) .replace('{{dayWithOrdinal}}', `${dayNum}${ordinalSuffix}`) .replace('{{time}}', time); case 'fr': // 法语:数字日期、月份全称、24小时制带"h" day = yourTargetDate.getDate(); month = datePipe(yourTargetDate, 'MMMM', 'fr'); time = datePipe(yourTargetDate, 'HH\'h\'', 'fr'); // 输出13h return translationTemplate .replace('{{day}}', day) .replace('{{month}}', month) .replace('{{time}}', time); case 'de': // 德语:带小数点的日期、月份全称、24小时制带"Uhr" day = yourTargetDate.getDate(); month = datePipe(yourTargetDate, 'MMMM', 'de'); time = datePipe(yourTargetDate, 'HH \'Uhr\'', 'de'); // 输出13 Uhr return translationTemplate .replace('{{day}}', day) .replace('{{month}}', month) .replace('{{time}}', time); default: // 默认用浏览器本地格式 return datePipe(yourTargetDate); } }); }; // 英语序数词辅助函数 function getEnglishOrdinal(n) { const suffixes = ['th', 'st', 'nd', 'rd']; const remainder = n % 100; return suffixes[(remainder - 20) % 10] || suffixes[remainder] || suffixes[0]; } });
方式二:封装成自定义过滤器(复用性更强)
如果多个页面都需要这个功能,把逻辑封装成Angular过滤器会更方便,模板里直接调用就行:
app.filter('localizedDate', function($translate, $filter) { const datePipe = $filter('date'); return function(targetDate) { return $translate.use().then(currentLang => { switch(currentLang) { case 'en': // 先格式化基础字符串,再替换数字为带序数词的 let baseStr = datePipe(targetDate, "MMMM d 'at' h a", 'en'); return baseStr.replace(/(\d+)/, match => `${match}${getEnglishOrdinal(parseInt(match))}`); case 'fr': return datePipe(targetDate, "Le d MMMM 'à' HH'h'", 'fr'); case 'de': return datePipe(targetDate, "d. MMMM 'um' HH 'Uhr'", 'de'); default: return datePipe(targetDate); } }); }; function getEnglishOrdinal(n) { const suffixes = ['th', 'st', 'nd', 'rd']; const remainder = n % 100; return suffixes[(remainder - 20) % 10] || suffixes[remainder] || suffixes[0]; } });
然后在模板里直接使用这个过滤器:
<!-- 假设$scope.myDate是你的目标日期对象 --> <p>{{ myDate | localizedDate }}</p>
3. 几个注意点
- 确保你的Angular项目引入了对应语言的locale文件(比如
angular-locale_fr-fr.js、angular-locale_de-de.js),不然DatePipe没法正确输出本地化的月份名称。 - 如果用ng-translate的
$translateMessageFormatInterpolator插值器,可以把翻译模板里的{{}}换成{},写法更规范,比如英语的"DATE_DISPLAY": "{month} {dayWithOrdinal} at {time}"。 - 序数词也可以放到翻译文件里,比如英语的翻译文件加个
"DAY_ORDINALS": ["th", "st", "nd", "rd"],这样后续调整更灵活。
内容的提问来源于stack exchange,提问作者Mattew Eon
相关产品推荐
相关产品推荐

