本文是接着上一篇文章写得,地址为:Moment.js 详细教程1

国际化

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

  1. 取得或设置全局语言,传入值表示设置,不传入值表示获取
// From 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.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('_'),
    monthsParseExact : true,
    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('_'),
    weekdaysParseExact : true,
    longDateFormat : {
        LT : 'HH:mm',
        LTS : 'HH:mm:ss',
        L : 'DD/MM/YYYY',
        LL : 'D MMMM YYYY',
        LLL : 'D MMMM YYYY HH:mm',
        LLLL : 'dddd D MMMM YYYY HH:mm'
    },
    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 : 'un an',
        yy : '%d ans'
    },
    dayOfMonthOrdinalParse : /\d{1,2}(er|e)/,
    ordinal : function (number) {
        return number + (number === 1 ? 'er' : 'e');
    },
    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.
    }
});
  1. 更改或获取局部语言,传参表示更改,不传参数表示获取
// 2.8.1 版本之前
moment().locale(String);
// 2.8.1 版本之后
moment().lang(String);
  1. Node.js中加载语言
    如果moment-root/locale/中已经存在语言文件,在首次调用moment.locale方法时,传入指定语言的key即可加载。
moment.locale(String);
  1. 浏览器中加载语言
<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>
  1. 列出当前使用语言的月份和星期
moment.months()
//["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
moment.monthsShort()
//["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
moment.weekdays()
//["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
moment.weekdaysShort()
//["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
moment.weekdaysMin()
//["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
moment.weekdays(true, 2)
//"Tuesday"
moment.monthsShort('-MMM-');
//["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
moment.monthsShort('-MMM-', 3);
//"Apr"
  1. 获取语言数据
    通过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

自定义

Moment.js可以非常简单的进行自定义。一般情况下,你需要创建一个您要进行自定义的语言的配置。

moment.locale('en-my-settings', {
    // 配置.
});

当然,你也可对已经载入的现有语言进行修改,第二个参数中传入null表示删除之前定义的语言

moment.locale('fr'); // 'fr'
moment.locale('en'); // 'en'
moment.locale('fr', null);
moment.locale('fr'); // 'en'

截止到2.12.0 版本你可以使用继承父类属性:

moment.defineLocale('en-foo', {
  parentLocale: 'en',
  /* */
});

截止到2.16.0 你定义子类语言时使用的父类可以没有定义或加载:

moment.defineLocale('fakeLocale', {parentLocale:'xyz'})

截止到2.12.0 ,你可以更新属性:

moment.updateLocale('en', {
  /**/
});

取消更新使用:

moment.updateLocale('en', null);

有如下属性可以进行定义或修改:

  • months 月份名
moment.updateLocale('en', {
    months : [
        "January", "February", "March", "April", "May", "June", "July",
        "August", "September", "October", "November", "December"
    ]
});
moment.updateLocale('en', {
    months : function (momentToFormat, format) {
        // momentToFormat是要格式化的时间
        // format是格式化字符串
        if (/^MMMM/.test(format)) { // 如果格式化格式为 'MMMM'
            return nominative[momentToFormat.month()];
        } else {
            return subjective[momentToFormat.month()];
        }
    }
});
  • monthsShort 月份名缩写
moment.updateLocale('en', {
    monthsShort : [
        "Jan", "Feb", "Mar", "Apr", "May", "Jun",
        "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
    ]
});
moment.updateLocale('en', {
    monthsShort : function (momentToFormat, format) {
        if (/^MMMM/.test(format)) {
            return nominative[momentToFormat.month()];
        } else {
            return subjective[momentToFormat.month()];
        }
    }
});
  • weekdays星期名
moment.updateLocale('en', {
    weekdays : [
        "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
    ]
});
moment.updateLocale('en', {
    weekdays : function (momentToFormat, format) {
        return weekdays[momentToFormat.day()];
    }
});
  • weekdaysShort星期名 (缩写)
moment.updateLocale('en', {
    weekdaysShort : ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
});
moment.updateLocale('en', {
    weekdaysShort : function (momentToFormat, format) {
        return weekdaysShort[momentToFormat.day()];
    }
});
  • weekdaysMin星期名 (极简缩写)
moment.updateLocale('en', {
    weekdaysMin : ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
});
moment.updateLocale('en', {
    weekdaysMin : function (momentToFormat, format) {
        return weekdaysMin[momentToFormat.day()];
    }
});
  • longDateFormat长日期格式
moment.updateLocale('en', {
    longDateFormat : {
        LT: "h:mm A",
        LTS: "h:mm:ss A",
        L: "MM/DD/YYYY",
        l: "M/D/YYYY",
        LL: "MMMM Do YYYY",
        ll: "MMM D YYYY",
        LLL: "MMMM Do YYYY LT",
        lll: "MMM D YYYY LT",
        LLLL: "dddd, MMMM Do YYYY LT",
        llll: "ddd, MMM D YYYY LT"
    }
});
  • relativeTime相对时间
moment.updateLocale('en', {
    relativeTime : {
        future: "in %s",
        past:   "%s ago",
        s  : 'a few seconds',
        ss : '%d seconds',
        m:  "a minute",
        mm: "%d minutes",
        h:  "an hour",
        hh: "%d hours",
        d:  "a day",
        dd: "%d days",
        M:  "a month",
        MM: "%d months",
        y:  "a year",
        yy: "%d years"
    }
});
  • meridiem上午下午
moment.updateLocale('zh-cn', {
    meridiem : function (hour, minute, isLowercase) {
        if (hour < 9) {
            return "早上";
        } else if (hour < 11 && minute < 30) {
            return "上午";
        } else if (hour < 13 && minute < 30) {
            return "中午";
        } else if (hour < 18) {
            return "下午";
        } else {
            return "晚上";
        }
    }
});
  • meridiemParse上午下午解析
moment.updateLocale('en', {
    isPM : function (input) {
        return ((input + '').toLowerCase()[0] === 'p');
    }
});
  • calendar日历
moment.locale('en', {
    calendar : {
        lastDay : '[Yesterday at] LT',
        sameDay : '[Today at] LT',
        nextDay : '[Tomorrow at] LT',
        lastWeek : '[last] dddd [at] LT',
        nextWeek : 'dddd [at] LT',
        sameElse : 'L'
    }
});
  • calendarFormat 日历格式化
moment.calendarFormat = function (myMoment, now) {
    var diff = myMoment.diff(now, 'days', true);
    var nextMonth = now.clone().add(1, 'month');

    var retVal =  diff < -6 ? 'sameElse' :
        diff < -1 ? 'lastWeek' :
        diff < 0 ? 'lastDay' :
        diff < 1 ? 'sameDay' :
        diff < 2 ? 'nextDay' :
        diff < 7 ? 'nextWeek' :
        // introduce thisMonth and nextMonth
        (myMoment.month() === now.month() && myMoment.year() === now.year()) ? 'thisMonth' :
        (nextMonth.month() === myMoment.month() && nextMonth.year() === myMoment.year()) ? 'nextMonth' : 'sameElse';
    return retVal;
};
  • ordinal比较
moment.updateLocale('en', {
    ordinal : function (number, token) {
        var b = number % 10;
        var output = (~~ (number % 100 / 10) === 1) ? 'th' :
            (b === 1) ? 'st' :
            (b === 2) ? 'nd' :
            (b === 3) ? 'rd' : 'th';
        return number + output;
    }
});
  • relativeTimeThreshold相对时间临界值,例如,超过45秒会被认为是一分钟,超过22小时会被认为是一天
 // 返回当前使用的临界值
  moment.relativeTimeThreshold('s');  // 45
  moment.relativeTimeThreshold('m');  // 45
  moment.relativeTimeThreshold('h');  // 22
  moment.relativeTimeThreshold('d');  // 26
  moment.relativeTimeThreshold('M');  // 11

  // 设置新的临界值
  moment.relativeTimeThreshold('s', 40);
  moment.relativeTimeThreshold('m', 40);
  moment.relativeTimeThreshold('h', 20);
  moment.relativeTimeThreshold('d', 25);
  moment.relativeTimeThreshold('M', 10);
  • relativeTimeRounding相对时间近似求值方法
var roundingDefault = moment.relativeTimeRounding();
// Round relative time evaluation down
moment.relativeTimeRounding(Math.floor);
moment.relativeTimeThreshold('s', 60);
moment.relativeTimeThreshold('m', 60);
moment.relativeTimeThreshold('h', 24);
moment.relativeTimeThreshold('d', 31);
moment.relativeTimeThreshold('M', 12);
var a = moment();
a.subtract({hours: 23, minutes: 59, seconds: 59});
a.toNow()  // == 'in 23 hours'  'Round down towards the nearest hour'
// back to default
moment.relativeTimeRounding(roundingDefault);
  • moment.now修改默认返回的时间值
moment.now = function () { return +new Date(); } //默认的方法,你可以自定义自己的方法

时间段

  1. 创建时间段
moment.duration(Number, String);
moment.duration(Number);
moment.duration(Object);
moment.duration(String);
moment.duration(100); // 100 毫秒
moment.duration(2, 'seconds'); //也可以传入简写形式s
moment.duration(2, 'minutes');//也可以传入简写形式m
moment.duration(2, 'hours');//也可以传入简写形式h
moment.duration(2, 'days');//也可以传入简写形式d
moment.duration(2, 'weeks');//也可以传入简写形式w
moment.duration(2, 'months');//也可以传入简写形式M
moment.duration(2, 'years');//也可以传入简写形式y
moment.duration({
    seconds: 2,
    minutes: 2,
    hours: 2,
    days: 2,
    weeks: 2,
    months: 2,
    years: 2
});
moment.duration('23:59:59'); //23小时59分59秒
moment.duration('23:59:59.999');//23小时59分59秒999毫秒
moment.duration('7.23:59:59.999');//7天23小时59分59秒999毫秒
  1. 克隆时间段
moment.duration().clone();
  1. 人性化
moment.duration().humanize();
  1. 取值
moment.duration().milliseconds(); //毫秒数
moment.duration().asMilliseconds();//毫秒级别的时间段长度
moment.duration().seconds(); //秒数
moment.duration().asSeconds();//秒级时间段长度
moment.duration().minutes(); //分数
moment.duration().asMinutes();//分钟级别时间段长度
moment.duration().hours();
moment.duration().asHours();
moment.duration().days();
moment.duration().asDays();
moment.duration().months();
moment.duration().asMonths();
moment.duration().years();
moment.duration().asYears();
  1. 增加时间,减少时间
moment.duration().add(Number, String);
moment.duration().add(Number);
moment.duration().add(Duration);
moment.duration().add(Object);
moment.duration().subtract(Number, String);
moment.duration().subtract(Number);
moment.duration().subtract(Duration);
moment.duration().subtract(Object);
  1. 使用diff
    你可以使用diff和duration获取两个时间点之间的时间段
var duration = moment.duration(x.diff(y))
var x = new moment()
var y = new moment()
var duration = moment.duration(x.diff(y))
  1. 单位转换
moment.duration().as(String);
duration.as('hours');
duration.as('minutes');
duration.as('seconds');
duration.as('milliseconds');
  1. 使用get取值
moment.duration().get(String);
duration.get('hours');
duration.get('minutes');
duration.get('seconds');
duration.get('milliseconds');
  1. 转换为JSON
moment.duration().toJSON();

将时间段对象序列化成JSON时,其会按ISO8601标准的字符串进行转换。

JSON.stringify({
    postDuration : moment.duration(5, 'm')
}); // '{"postDuration":"PT5M"}'
  1. 是否时间段
moment.isDuration(obj);
moment.isDuration() // false
moment.isDuration(new Date()) // false
moment.isDuration(moment()) // false
moment.isDuration(moment.duration()) // true
moment.isDuration(moment.duration(2, 'minutes')) // true
  1. 转换为As ISO 8601 字符串
moment.duration().toISOString();
  1. 本地化
moment.duration().locale();
moment.duration().locale(String);
moment.duration(1, "minutes").locale("en").humanize(); // a minute
moment.duration(1, "minutes").locale("fr").humanize(); // une minute
moment.duration(1, "minutes").locale("es").humanize(); // un minuto

工具类

  1. 标准化单位
moment.normalizeUnits(String);

Moment中的很多函数都允许访问器传入单位枚举的别名。例如,下面所有的get都相等。

var m = moment();
m.get('y');
m.get('year');
m.get('years');

如果你正在对类库进行扩展,通过对Moment功能的调整,您可以更容易的访问其中的特性

moment.normalizeUnits('y');      // 'year'
moment.normalizeUnits('Y');      // 'year'
moment.normalizeUnits('year');   // 'year'
moment.normalizeUnits('years');  // 'year'
moment.normalizeUnits('YeARS');  // 'year'
  1. 无效对象
moment.invalid(Object);

你可以创建你自己的无效Moment对象,在这你自己定义的解析器中非常有用。

var m = moment.invalid();
m.isValid();                      // false
m.format();                       // 'Invalid date'
m.parsingFlags().userInvalidated; // true

invalid同样接受对象形式的参数,其中包含对解析标识的一些设置。这不会设置userInvalidated解析标识,除非通过属性指定。

var m = moment.invalid({invalidMonth: 'Actober'});
m.parsingFlags().invalidMonth; // 'Actober'

你不必指定Moment中的解析标识,因为这在Moment中是无效的,转换标识会由parsingFlags()返回。