笔者在做项目的时候,需要对日期和时间进行一些处理和操作,但是每次都用JS自带的Date对象很不方便,还要写一堆繁琐的代码,后续维护起来也很痛苦。在网上找了一下JS处理日期和时间的插件,发现了MomentJS很好用,学习了一下它的语法,发现十分的简洁易懂,而且可扩展性很强,调用方法灵活。很多的方法调用形式多样,支持多种传参数方式。下面简单的整理了一下使用方式

构造Moment对象

  MomentJS将时间封装成一个对象,moment对象,这个对象很多种构造方式,可以支持传入字符串、数组和对象的形式来构造。

当前系统时间

  如果什么都不传,就获取当前的系统时间。

1
var now = moment()

字符串构造

  可以传入字符串,首先会检查字符串的格式是否符合ISO 8601的格式,如果不符合,就调用new Date(string)来构造。

已知格式字符串

1
2
3
4
5
moment('2017-01-02');               //年月日
moment('2017-01-02 13'); //年月日 小时
moment('2017-01-02 13:12'); //年月日 小时分钟
moment('2017-01-02 13:12:52'); //年月日 小时分钟秒
moment('2017-01-02 13:12:52.123'); //年月日 小时分钟秒 毫秒

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

字符串+格式

  假如日期的格式不符合ISO 8601的格式,但是你知道输入的字符串的格式,也可以通过这种方式解析,解析的语法有以下四种格式:

1
2
3
4
moment(String, String);
moment(String, String, String);
moment(String, String, Boolean);
moment(String, String, String, Boolean);

  第一种已知某个时间的格式,将格式作为第二个参数传入

1
moment('12-25-1995 12/43/53', 'MM-DD-YYYY HH/mm/ss')

  格式字母代表的含义如下表

Input Example Description
YYYY 2014 4位数年份
YY 14 2位数年份
Q 1..4 季度,将月份设置成季度的第一个月
M MM 1..12 月份
MMM MMMM Jan..December 月份名称
D DD 1..31 一个月的第几天
DDD DDDD 1..365 一年的第几天
H HH 0..23 24小时制
h hh 1..12 12小时制
m mm 0..59 分钟
s ss 0..59

  第二种,可以将当地区域的关键符作为第三个参数传入。

1
2
moment('2012 juillet', 'YYYY MMM', 'fr');
moment('2012 July', 'YYYY MMM', 'en');

  MomentJS的匹配模式是十分宽松的,并且可能会导致一些我们不想要的行为。从2.3.0版本开始,我们可以在最后传入一个布尔值来让Moment使用严格模式匹配。严格模式要求输入的字符串和格式要完全相同。

1
2
3
moment('It is 2012-05-25', 'YYYY-MM-DD').isValid();       // true
moment('It is 2012-05-25', 'YYYY-MM-DD', true).isValid(); // false
moment('2012-05-25', 'YYYY-MM-DD', true).isValid(); // true

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

字符串+多格式

  假如你不知道输入的字符串确切是用的哪种格式,但是知道是某些格式中的一种,可以将多种格式用数组的形式传入,将会以最先匹配到的格式为输出结果。

1
moment("12-25-1995", ["MM-DD-YYYY", "YYYY-MM-DD"]);

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

对象

  我们也可以通过传入一个对象的形式来创建moment对象,传入的对象中包括一些时间单位的属性。

1
2
3
4
moment({ y    :2010, M     :3, d   :5, h    :15, m      :10, s      :3, ms          :123});
moment({ year :2010, month :3, day :5, hour :15, minute :10, second :3, millisecond :123});
moment({ years:2010, months:3, days:5, hours:15, minutes:10, seconds:3, milliseconds:123});
moment({ years:2010, months:3, date:5, hours:15, minutes:10, seconds:3, milliseconds:123});

  上面代码中的day和date都表示当前月的第几天。

Date 对象

  我们也可以传入JS原生的Date对象来创建moment对象。

1
2
var day = new Date(2011, 9, 16);
var dayWrapper = moment(day);

数组

  我们可以传入一个数字的数组来创建moment对象,数组中每个每个数字代表的含义如下:

1
2
3
// [年, 月, 日, 时, 分, 秒, 毫秒]
moment([2010, 1, 14, 15, 25, 50, 125]);
//2010年2月14日15时25分50秒125毫秒

  需要注意的是:数组中的月、时、分、秒、毫秒都是从0开始的,而年和日都是从1开始的。

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

取值and赋值

  MomentJS使用可以重载的get和set方法,跟我们以前在jQuery中的形式很相似。我们可以调用这些方法不传参数作来获取,传入参数作来设置。

自带函数

获取或者设置毫秒,设置的范围0到999

1
2
3
4
moment().millisecond(Number);
moment().millisecond(); // Number
moment().milliseconds(Number);
moment().milliseconds(); // Number

获取或者设置秒,设置的范围0到59

1
2
3
4
moment().second(Number);
moment().second(); // Number
moment().seconds(Number);
moment().seconds(); // Number

获取或者设置分钟,设置的范围0到59

1
2
3
4
moment().minute(Number);
moment().minute(); // Number
moment().minutes(Number);
moment().minutes(); // Number

获取或者设置小时,设置的范围0到23

1
2
3
4
moment().hour(Number);
moment().hour(); // Number
moment().hours(Number);
moment().hours(); // Number

获取或者设置日期,设置的范围1到31

1
2
3
4
moment().date(Number);
moment().date(); // Number
moment().dates(Number);
moment().dates(); // Number

获取或者设置星期,设置的范围0(周日)到6(周六)

1
2
3
4
moment().day(Number|String);
moment().day(); // Number
moment().days(Number|String);
moment().days(); // Number

获取或者设置一年中的天数,设置的范围1到366

1
2
moment().dayOfYear(Number);
moment().dayOfYear(); // Number

获取或者设置一年中的周

1
2
3
4
moment().week(Number);
moment().week(); // Number
moment().weeks(Number);
moment().weeks(); // Number

获取或者设置一年中的月份,设置的范围0到11

1
2
3
4
moment().month(Number|String);
moment().month(); // Number
moment().months(Number|String);
moment().months(); // Number

获取或者设置季度,设置的范围1到4

1
2
moment().quarter(); // Number
moment().quarter(Number);

获取或者设置年,设置的范围-270000到270000

1
2
3
4
moment().year(Number);
moment().year(); // Number
moment().years(Number);
moment().years(); // Number

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

取值and赋值函数

  除了上面的这么多函数外,MomentJS还有一个用来统一取值和赋值的函数,get和set。

1
2
3
4
5
6
7
moment().get('year');
moment().get('month'); // 0 to 11
moment().get('date');
moment().get('hour');
moment().get('minute');
moment().get('second');
moment().get('millisecond');

  set函数接收单位作为第一个参数,单位的值作为第二个参数。如果要设置多个值的话,也可以通过传入一个对象。

1
2
3
4
5
6
7
8
9
moment().set('year', 2013);
moment().set('month', 3); //四月
moment().set('date', 1);
moment().set('hour', 13);
moment().set('minute', 20);
moment().set('second', 30);
moment().set('millisecond', 123);

moment().set({'year': 2013, 'month': 3});

max/min函数

  max函数可以返回给定的moment对象中最大的实例,也就是最靠近未来的实例。

1
2
3
var a = moment('2017-12-01');
var b = moment('2017-12-06');
moment.max(a, b); // b

  min函数可以返回给定的moment对象中最小的实例,也就是最靠近过去的实例。

1
2
3
var a = moment('2017-12-01');
var b = moment('2017-12-06');
moment.min(a, b); // a

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

操作

  有时候,我们需要对时间进行一系列的操作,最常见的就是加减计算。MomentJS提供了很多方法给我们来进行调用。
  MomentJS使用的模式跟jQuery相似,都是使用的函数的链式调用,可以让我们将操作链式执行下去,代码如下所示:

1
2
3
4
5
6
7
moment()
.add(7, 'days')
.subtract(1, 'months')
.year(2009)
.hours(0)
.minutes(0)
.seconds(0);

add加法

  add函数让我们把Moment对象的时间往后退,它的语法如下:

1
2
3
moment().add(Number, String);
moment().add(Duration);
moment().add(Object);

  我们可以传入想要的增加的时间数量和时间单位,比如要往后推迟7天:

1
moment().add(7, 'days');

  当然,add函数也允许我们提供时间单位的缩写:

1
moment().add(7, 'd');
时间单位 缩写
years y
quarters Q
months M
weeks W
days d
hours h
minutes m
seconds s
milliseconds ms

  如果想要同时增加不同时间单位,可以以对象的形式传入:

1
2
moment().add(7, 'days').add(1, 'months');
moment().add({days:7,months:1});

  需要注意的是,如果原始日期的天数比新增后的日期的月份的总天数还要多,就变为该月的最后一天:

1
2
3
4
5
6
// 01-31
moment([2010, 0, 31]);

// 02-28
moment([2010, 0, 31]).add(1, 'months');
//2月份没有31号,自动变为最后一天,即28号

subtract减法

  subtract函数的用法和add相似,不同的是把时间往前推。

1
2
3
moment().subtract(Number, String);
moment().subtract(Duration);
moment().subtract(Object);

startOf开始时间

  startOf函数将Moment对象的时间设置为传入单位的开始时间。

1
2
3
4
5
6
7
8
9
10
moment()                    //当前时间2017-12-09
moment().startOf('year'); //今年年初2017-01-01
moment().startOf('month'); //这个月开始2017-12-01
moment().startOf('quarter');//这个季度开始2017-10-01
moment().startOf('week'); //这周开始2017-12-03(周日为开始)
moment().startOf('isoWeek');//这周开始2017-12-04(根据ISO 8601,周一为开始)
moment().startOf('day'); //今天的开始时间2017-12-09 00:00:00:000
moment().startOf('hour'); //今天当前小时开始2017-12-09 13:00:00:000
moment().startOf('minute'); //今天当前分钟开始2017-12-09 13:14:00:000
moment().startOf('second'); //今天当前秒钟开始2017-12-09 13:14:15:000

endOf结束时间

  endOf函数将Moment对象的时间设置为传入单位的结束时间。使用方式和startOf相似。

1
moment().endOf(String);

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

显示

  当我们解析和操作完Moment对象后,我们就需要对最后的结果进行展示。

format格式化

  format函数接收token字符串,并且将token替换成对应的值。

1
2
3
moment().format();                                // "2014-09-08T08:02:17-05:00" (ISO 8601)
moment().format("dddd, MMMM Do YYYY, h:mm:ss a"); // "Sunday, February 14th 2010, 3:25:50 pm"
moment().format("ddd, hA"); // "Sun, 3PM"

  对应的关系如下表:

- Token 输入
M 1 2 .. 11 12
Mo 1st 2nd … 11th 12th
MM 01 02 … 11 12
MMM Jan Feb … Nov Dec
MMMM January February … November December
季度 Q 1 2 3 4
月份中的天 D 1 2 … 30 31
Do 1st 2nd … 30th 31st
DD 01 02 … 30 31
年份中的天 DDD 1 2 … 365 366
DDDo st 2nd … 365th 366th
DDDD 001 002 … 365 366
星期中的天 d 0 1 … 5 6
do 0th 1st … 5th 6th
dd Su Mo … Fr Sa
ddd Sun Mon … Fri Sat
dddd Sunday Monday … Friday Saturday
年中的星期 w 1 2 … 52 53
wo 1st 2nd … 52nd 53rd
ww 01 02 … 52 53
YY 70 71 … 29 30
YYYY 1970 1971 … 2029 2030
AM/PM A AM PM
a am pm
小时 H 0 1 … 22 23
HH 00 01 … 22 23
h 1 2 … 11 12
hh 01 02 … 11 12
分钟 m 0 1 … 58 59
mm 00 01 … 58 59
s 0 1 … 58 59
ss 00 01 … 58 59
毫秒 ms 000 001 … 998 999

diff时差

  语法

1
2
3
moment().diff(Moment|String|Number|Date|Array);
moment().diff(Moment|String|Number|Date|Array, String);
moment().diff(Moment|String|Number|Date|Array, String, Boolean);

  diff函数可以帮我们获取到两个Moment对象的时间差,默认的单位是毫秒。

1
2
3
var a = moment([2017, 12, 29]);
var b = moment([2017, 12, 28]);
a.diff(b) // 86400000

  除了得到毫秒为单位,diff函数还支持获取其他的时间单位,将其作为第二个参数传入:

1
2
3
var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days') // 1

  支持的测量单位有years、months、weeks、days、hours、minutes、seconds和milliseconds。默认返回的数值会向下取舍,去掉小数。假如想要精确一点,得到小数类型的数值,第三个参数传入一个true。

1
2
3
4
var a = moment([2008, 6]);
var b = moment([2007, 0]);
a.diff(b, 'years'); // 1
a.diff(b, 'years', true); // 1.5

daysInMonth获取当前月份的天数

  daysInMonth获取当前月的总天数

1
2
moment("2012-02", "YYYY-MM").daysInMonth() // 29
moment("2012-01", "YYYY-MM").daysInMonth() // 31

toDate转为Date对象

  将Moment对象转为js原生的Date对象

toArray转为数组

  返回时间数组,和构造Moment对象时传入的数组代表的含义相同。

1
moment().toArray(); // [2017, 12, 9, 13, 40, 16, 154];

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

toObject

  将Moment对象转为包含年月日时分秒毫秒的对象。

1
2
3
4
5
6
7
8
9
moment().toObject()  // {
// years: 2017
// months: 12
// date: 9,
// hours: 13,
// minutes: 40,
// seconds: 18,
// milliseconds: 600
// }

查询

  查询操作主要用来判断Moment是否满足某些条件。

isBefore是否之前

1
2
moment().isBefore(Moment|String|Number|Date|Array);
moment().isBefore(Moment|String|Number|Date|Array, String);

  isBefore判断一个moment对象是否在某个时间点之前。

1
moment('2010-10-20').isBefore('2010-10-21'); // true

  默认的比较单位是毫秒,但是假如我们想要限制到其他的时间单位,我们可以将其作为第二个参数传入。接受的单位和startOf支持的单位一样。

1
2
3
console.log(moment('2017-11-03').isBefore('2017-11-06'))
console.log(moment('2017-11-03').isBefore('2017-11-06', 'year'))
console.log(moment('2017-11-03').isBefore('2018-11-06', 'year'))

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

isSame是否相同

1
2
moment().isSame(Moment|String|Number|Date|Array);
moment().isSame(Moment|String|Number|Date|Array, String);

  isSame判断一个moment对象是否和另一个moment对象相同。

1
2
moment('2010-10-20').isSame('2010-10-20'); // true
moment('2010-10-20').isSame('2010-10-21'); // false

  同样的,我们如果要将比较的单位改为其他的,也可以作为第二个参数传入。接受的单位和startOf支持的单位一样。

1
2
moment('2010-10-20').isSame('2009-12-31', 'year');  // false
moment('2010-10-20').isSame('2010-01-01', 'year'); // true

  当传入第二个参数时,它会匹配所有相同或者更大的单位。比如传入了月份,将会比较年和月,传入了日期,将会比较年月日

1
2
3
4
5
// false, 不同的年
moment('2010-01-01').isSame('2011-01-01', 'month');

// false, 不同的月
moment('2010-01-01').isSame('2010-02-01', 'day');

isAfter是否之后

  isBefore判断一个moment对象是否在某个时间点之后。接受的单位和startOf支持的单位一样。

1
moment('2010-10-20').isAfter('2010-10-19'); // true

isBetween是否之间

1
2
3
moment().isBetween(moment-like, moment-like);
moment().isBetween(moment-like, moment-like, String);
//moment-like 表示 Moment|String|Number|Date|Array

  判断一个moment对象是否在两个其他时间点之间。

1
moment('2017-10-20').isBetween('2017-10-19', '2017-10-25'); // true

  传入第二个参数作为限制的单位。接受的单位和startOf支持的单位一样。

1
2
moment('2010-10-20').isBetween('2010-01-01', '2012-01-01', 'year'); // false
moment('2010-10-20').isBetween('2009-12-31', '2012-01-01', 'year'); // true

谢小飞博客专用防爬虫链接,想要看最新的前端博客请点这里

isLeapYear是否闰年

  是闰年就返回true,不是就返回false。

1
2
3
moment([2000]).isLeapYear() // true
moment([2001]).isLeapYear() // false
moment([2100]).isLeapYear() // false

isMoment 是否Moment对象

  判断是否Moment对象

1
2
3
moment.isMoment() // false
moment.isMoment(new Date()) // false
moment.isMoment(moment()) // true

isDate是否Date对象

  判断是否Date对象

1
2
3
moment.isDate(); // false
moment.isDate(new Date()); // true
moment.isDate(moment()); // false

本文地址: http://xieyufei.com/2017/12/06/JS-Moment.html