Moment.js中文文档系列之六日期时间的国际化(i18n)

 2015年10月28日    19636     声明


Moment.js非常键全的支持日期时间的国际化。你可以载入多个区域的时间,并且可以轻松的在它们之间切换。你也可以将某个详细区域的时间,设置为全局时间。

  1. 更改全局语言设置:locale()
  2. 更改局部语言设置:locale(String)
  3. Node.js中加载语言:locale(String)
  4. 浏览器中加载语言:locale(String, Object)
  5. 为Moment.js增加语言:locale()
  6. 查看当前时间:locale()
  7. 列出月份和星期:months()……
  8. 获取语言数据:localeData()


1. 更改全局语言设置:moment.locale()

// 2.8.1 版本之后
moment.locale(String);
moment.locale(String[]);
moment.locale(String, Object);

//  2.8.1 版本之前
moment.lang(String);
moment.lang(String[]);
moment.lang(String, Object);

默认情况下Moment.js使用英语显示字符串。如果需要其它语,就在使用前载入到Moment.js中。

加载语言时,通过moment.locale设置,设置时需要传入key和对应的字符串值。

详细的关于语言包将在后续customization章节介绍,敬请期待。

moment.locale('fr', {
    months : "janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre".split("_"),
    monthsShort : "janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.".split("_"),
    weekdays : "dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi".split("_"),
    weekdaysShort : "dim._lun._mar._mer._jeu._ven._sam.".split("_"),
    weekdaysMin : "Di_Lu_Ma_Me_Je_Ve_Sa".split("_"),
    longDateFormat : {
        LT : "HH:mm",
        LTS : "HH:mm:ss",
        L : "DD/MM/YYYY",
        LL : "D MMMM YYYY",
        LLL : "D MMMM YYYY LT",
        LLLL : "dddd D MMMM YYYY LT"
    },
    calendar : {
        sameDay: "[Aujourd'hui à] LT",
        nextDay: '[Demain à] LT',
        nextWeek: 'dddd [à] LT',
        lastDay: '[Hier à] LT',
        lastWeek: 'dddd [dernier à] LT',
        sameElse: 'L'
    },
    relativeTime : {
        future : "dans %s",
        past : "il y a %s",
        s : "quelques secondes",
        m : "une minute",
        mm : "%d minutes",
        h : "une heure",
        hh : "%d heures",
        d : "un jour",
        dd : "%d jours",
        M : "un mois",
        MM : "%d mois",
        y : "une année",
        yy : "%d années"
    },
    ordinalParse : /\d{1,2}(er|ème)/,
    ordinal : function (number) {
        return number + (number === 1 ? 'er' : 'ème');
    },
    meridiemParse: /PD|MD/,
    isPM: function (input) {
        return input.charAt(0) === 'M';
    },
    // in case the meridiem units are not separated around 12, then implement
    // this function (look at locale/id.js for an example)
    // meridiemHour : function (hour, meridiem) {
    //     return /* 0-23 hour, given meridiem token and hour 1-12 */
    // },
    meridiem : function (hours, minutes, isLower) {
        return hours < 12 ? 'PD' : 'MD'; }, week : { dow : 1, // Monday is the first day of the week. doy : 4 // The week that contains Jan 4th is the first week of the year. } });

一旦载入一种语言后,其将成为正在使用语言。修改正在使用的语言,一个简单的方法是使用moment.locale方法并传入对应的key将其载入。

moment.locale('fr');
moment(1316116057189).fromNow() // il y a une heure
moment.locale('en');
moment(1316116057189).fromNow() // an hour ago

moment.locale会返回使用过的语言。这很有用,因为在你没有明确指定的情况下Moment不会修改语言。

moment.locale('fr'); // 'fr'
moment.locale('tq'); // 'fr'

当你指定一个语言列表时,Moment会使用其中的第一个进行本地化。

moment.locale(['tq', 'fr']); // 'fr'

Moment会尝试匹配子字符串,从最多匹配到最后匹配,直到匹配到可识别的语言。

moment.locale('en-NZ'); // 'en'

Moment也会从一个语言列表和它们的子字符串中,智能识别可用语言。

moment.locale('en-NZ', 'en-AU'); // 'en-au', 非'en'


2. 更改局部语言设置:moment()locale(String)

// 2.8.1 版本之前
moment().locale(String);

// 2.8.1 版本之后
moment().lang(String);

全局设置语言后,可能会造成一些不便,当你格式化时间,可能会需要使用不同的语言。

1.7.0版中,我们添加了首选时间配置。

moment.locale('en'); // 默认语言 英语
var localLocale = moment();

localLocale.locale('fr'); // 在这个实例中设置为 法语
localLocale.format('LLLL'); // dimanche 15 juillet 2012 11:01
moment().format('LLLL'); // Sunday, July 15 2012 11:01 AM

moment.locale('es'); // 修改全局语言为 西班牙语
localLocale.format('LLLL'); // dimanche 15 juillet 2012 11:01
moment().format('LLLL'); // Domingo 15 Julio 2012 11:01

localLocale.locale(false); // 重置实例的语言
localLocale.format('LLLL'); // Domingo 15 Julio 2012 11:01
moment().format('LLLL'); // Domingo 15 Julio 2012 11:01

在不传参数的情况下调用moment().locale()方法,可以返回正在使用的语言。

var fr = moment().locale('fr');
fr.localeData().months(moment([2012, 0])) // "janvier"
fr.locale('en');
fr.localeData().months(moment([2012, 0])) // "January"


3. Node.js中加载语言:locale(String)

moment.locale(String);

Node.js中加载语言包相当简单。如果moment-root/locale/中已经存在语言文件,在首次调用moment.locale方法时,传入指定语言的key即可加载。

var moment = require('moment');
moment.locale('fr');
moment(1316116057189).fromNow(); // il y a une heure

如果想加载自定义语言,请参考:Moment.js增加语言:locale()


4. 浏览器中加载语言:locale(String, Object)

// 2.8.1 版本之后
moment.locale(String, Object);

// 2.8.1 版本之前
moment.lang(String, Object);

在浏览器中加载语言包时,只需引入语言文件即可使用。

<script src="moment.js"></script>
<script src="locale/fr.js"></script>
<script src="locale/pt.js"></script>
<script>
  moment.locale('fr');  // Set the default/global locale
  // ...
</script>

所有的语言包都提供了压缩版。

<script src="moment.js"></script>
<script src="min/locales.js"></script>


5. 为Moment.js增加语言:locale()

添加你自定义的语言时,需要提交两个文件:一个语言文件,一个测试文件。可以参考:moment/locale/fr.jsmoment/test/locale/fr.js两个文件。

在Node.js中执行测试时,先执行npm install,然后执行grunt命令。

测试通过后,提交请求,感谢你的贡献。


6. 查看当前时间:locale()

// 2.8.1 版本之后
moment.locale();

// 2.8.1 版本之前
moment.lang();

如果你经常修改语言包,你可能会需要查看当前正在使用哪种语言。一个简单的查询方式是,不传入任何参数调用moment.locale方法。

moment.locale('en'); // 设置为 英语
moment.locale(); // 返回 'en'
moment.locale('fr'); // 设置为 法语
moment.locale(); // 返回 'fr'



7. 列出月份和星期:months()……

moment.months()
moment.monthsShort()
moment.weekdays()
moment.weekdaysShort()
moment.weekdaysMin()

有时会需要列出月份和星期,如,在下拉列表中使用时。

moment.months();

返回结果如下:

[ 'January',
  'February',
  'March',
  'April',
  'May',
  'June',
  'July',
  'August',
  'September',
  'October',
  'November',
  'December' ]

同样的,moment.monthsShort会返回月份的缩写,moment.weekdaysmoment.weekdaysShortmoment.weekdaysMin会返回各种形式的星期。


8. 获取语言数据:localeData()

localeData = moment.localeData()
localeData.months()
localeData.monthsShort()
localeData.monthsParse()
localeData.weekdays()
localeData.weekdaysShort()
localeData.weekdaysMin()
localeData.weekdaysParse()
localeData.longDateFormat()
localeData.isPM()
localeData.meridiem()
localeData.calendar()
localeData.relativeTime()
localeData.pastFuture()
localeData.ordinal()
localeData.preparse()
localeData.postformat()
localeData.weeks()
localeData.invalidDate()
localeData.firstDayOfWeek()
localeData.firstDayOfYear()

通过moment.localeData(key)函数,你可以查看当前载入语言的各种属性。

var currentLocaleData = moment.localeData();
var frLocaleData = moment.localeData('fr');

返回对象中包含以下方法:

localeData.months(aMoment);  // 指定时间月份的全名
localeData.monthsShort(aMoment);  // 指定时间月份的缩写
localeData.monthsParse(longOrShortMonthString);  // 返回输入月份的序号 (0 〜 11) 
localeData.weekdays(aMoment);  // 指定时间星期的全名
localeData.weekdaysShort(aMoment);  // 指定时间星期的缩写
localeData.weekdaysMin(aMoment);  // 指定时间星期的缩写
localeData.weekdaysParse(minShortOrLongWeekdayString);  // 返回输入星期的序号 (0 〜 6) 
localeData.longDateFormat(dateFormat);  // 返回指定日期时间缩写格式的全写,如:LT, L, LL等
localeData.isPM(amPmString);  // 是否 AM、PM 字符串
localeData.meridiem(hours, minutes, isLower);  // 返回指定日期大小写形式的 am/pm 字符串
localeData.calendar(key, aMoment);  // 返回日历格式。Key可以是:'sameDay', 'nextDay', 'lastDay', 'nextWeek', 'prevWeek', 'sameElse'
localeData.relativeTime(number, withoutSuffix, key, isFuture);  // 返回一个相对时间的字符串。Key可以是:'s', 'm', 'mm', 'h', 'hh', 'd', 'dd', 'M', 'MM', 'y', 'yy'
localeData.pastFuture(diff, relTime);  // 转换实际时间 relTime 到过去或未来的 diff的值
localeData.ordinal(number);  // 转换数字到序数 1 -> 1st
localeData.preparse(str);  // 调用转换之前的字符串
localeData.postformat(str);  // 调用格式之后的字符串
localeData.week(aMoment);  // 返回指定时间年中的周数
localeData.invalidDate();  // 返回 'Invalid date'
localeData.firstDayOfWeek();  // 0-6 (周日到周六)
localeData.firstDayOfYear();  // 0-15