Skip to content

MomentJS - 国际化

现代日期/时间处理:Moment.js 的国际化 (i18n)

Section titled “现代日期/时间处理:Moment.js 的国际化 (i18n)”

在用户的本地语言和格式中显示日期和时间(即国际化,Internationalization 或 i18n)对于全球化应用至关重要。Moment.js 提供了强大的 locale(区域设置)支持。

虽然 Moment.js 很好地处理了 i18n,但它的方法涉及加载 locale 数据,这会增加 bundle size(打包大小)。像 Day.js 这样的现代替代方案提供了按需加载 locale 的能力,而原生 Intl API 更是专为 i18n 设计,通常是最有效的选择。

要使用默认(英语)之外的 locale,你需要加载它们的定义文件。

  • 所有 Locales(浏览器端): 包含 moment-with-locales.js(或 moment-with-locales.min.js)而不是标准的 moment.js。这会打包所有可用的 locale,但显著增加文件大小。
  • <script src="path/to/moment-with-locales.min.js"></script>
  • 特定 Locales(浏览器/打包工具): 只加载你需要的 locale。这是推荐的、对性能更好的方法。
  • // Using ES6 imports with a bundler (Webpack, Rollup, etc.)
    import moment from 'moment';
    import 'moment/locale/fr'; // 加载法语
    import 'moment/locale/es'; // 加载西班牙语
    // Using require in Node.js or older bundler setups
    const moment = require('moment');
    require('moment/locale/de'); // 加载德语
  • Node.js: 当通过 npm (npm install moment) 安装时,所有 locale 文件通常都包含在 node_modules/moment/locale/ 目录中,并可以如上所示进行 require 导入。

你可以全局设置 locale,或针对特定实例进行设置:

  • 全局 Locale: moment.locale(String) 设置后续所有 Moment 操作的 locale。它返回成功设置的 locale 名称。
  • 局部 Locale: momentInstance.locale(String) 仅 为该特定的 Moment 实例以及所有从它 clone 出来的 Moment 实例设置 locale。这对于同时处理多种 locale 非常有用。
  • 获取 Locale: moment.locale()(全局)或 momentInstance.locale()(局部)返回当前活跃的 locale 字符串。
import moment from 'moment';
import 'moment/locale/fr';
import 'moment/locale/es';
// 将全局 locale 设置为法语
moment.locale('fr');
console.log(moment().format('LLLL')); // 输出示例:jeudi 26 octobre 2023 15:30
console.log(moment.locale()); // 输出:fr
// 创建一个 moment 实例并将其 locale 局部设置为西班牙语
const spanishTime = moment().locale('es');
console.log(spanishTime.format('LLLL')); // 输出示例:jueves, 26 de octubre de 2023 15:30
// 全局 locale 仍然是法语
console.log(moment().format('LLLL')); // 输出示例:jeudi 26 octobre 2023 15:30
// 将全局 locale 恢复为英语(默认)
moment.locale('en');
console.log(moment().format('LLLL')); // 输出示例:Thursday, October 26, 2023 3:30 PM

一旦 locale 被激活(全局或局部),许多 Moment.js 函数就会变成 locale 感知的:

  • .format():使用本地化的月份/星期名称和 locale 特定的长日期格式 (L, LL, LLL, LLLL)。
  • .fromNow(), .from(), .toNow(), .to():使用本地化单位显示相对时间。
  • .calendar():生成本地化的日历时间字符串。
  • 解析 (moment(string, format, locale)):如果在解析时指定了 locale,可以解析本地化的月份和星期名称。
moment.locale('de'); // 设置德语 locale
// Formatting
console.log(moment().format('dddd, Do MMMM YYYY')); // 输出示例:Donnerstag, 26. Oktober 2023
console.log(moment().subtract(2, 'days').calendar()); // 输出示例:Vorgestern um 15:30 Uhr
// Parsing
const parsedDate = moment('Di., 24. Okt. 2023', 'ddd, D. MMM YYYY', 'de');
console.log(parsedDate.isValid()); // true
console.log(parsedDate.format('YYYY-MM-DD')); // 2023-10-24

你可以直接访问当前已加载 locale 的数据:

  • moment.months():包含完整月份名称的数组。
  • moment.monthsShort():包含缩写月份名称的数组。
  • moment.weekdays():包含完整星期名称的数组(周日至周六)。
  • moment.weekdaysShort():包含缩写星期名称的数组。
  • moment.weekdaysMin():包含最短星期名称的数组。
  • moment.localeData(localeName):获取特定 locale 的完整 locale 数据对象(如果未提供名称,则获取当前 locale 的)。
moment.locale('fr');
console.log(moment.months()); // 输出示例:['janvier', 'février', ...]
console.log(moment.weekdaysShort()); // 输出示例:['dim.', 'lun.', ...]
const frLocaleData = moment.localeData('fr');
console.log(frLocaleData.firstDayOfWeek()); // 输出:1(周一)

国际化是 Moment.js 的一个关键优势,但在现代 Web 开发中,管理 locale 文件的加载及其对 bundle size 的影响是一个重要的考量因素。

参见官方 i18n 文档:https://momentjs.com/docs/#/i18n/