Moment.js
它是一款JavaScript日期处理类库,方便我们日常开发中处理日期时间的一些特殊需求。例如:格式化日期、日期之间比较、运算。
官网地址:https://momentjs.com
中文网地址:http://momentjs.cn
初入门使用
1. 获取moment.js扩展库的资源包
下载地址:https://cdnjs.com/libraries/moment.js
2. 创建页面并引入资源
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Moment初入门示例</title>
<!-- 引入moment.js资源包 -->
<script src="./moment-2.29.4/moment.min.js"></script>
<!-- 引入本地化资源文件,一般情况下无需引入 -->
<script src="./moment-2.29.4/locale/zh-cn.min.js"></script>
</head>
<body>
<script>
// 使用简体中文本地化资源
moment.locale('zh-cn');
// 输出格式化字符串"2022年8月9日星期二下午2点31分"
alert(moment().format('LLLL'));
</script>
</body>
</html>
- 我们只需要在页面引入"moment.min.js"资源文件就可以使用该扩展库。
3. 页面显示效果
详细API
1. 解析并获取日期时间
Moment.js并没有修改Date对象的原型链,而是为Date对象创建了一个包装器。通过moment()方法可以获取到此包装器对象。此方法可传入表示日期时间的字符串、数值等。
1.1 获取当前时间的包装器对象
// 获取当前的日期和时间
var now = moment();
1.2 获取指定日期时间的包装器对象(未指定格式)
// 获取指定日期时间的包装器对象(未指定字符串日期时间格式)
var now2 = moment('2021-10-20');
console.log(now2.year());//2021
- 可以传入日期时间格式的字符串数据来生成指定日期时间的包装器对象。
- 此字符串格式首先根据已知的 ISO 8601 格式匹配;若未匹配上,则再降维到 new Date(string) 之前检查字符串是否与 RFC 2822 日期时间格式匹配。
1.3 获取指定日期时间的包装器对象(指定格式)
// 获取指定日期时间的包装器对象(指定字符串日期时间格式)
var now2 = moment('2021-10-20', 'YYYY-MM-DD');
console.log(now2.year()); //2021
指定的日期格式标识如下所示
- YYYY:4位数字的年份。
- YY:2位数字的年份。
- Q:年份的季度。例如:1…4
- M MM:月份数字。例如:1…12
- D DD:月的某天。例如:1…31
- H HH:小时(24 小时制)。例如:0…23
- h hh:小时(使用
a A
的 12 小时制)。例如:1…12 - k kk:小时(从 1 到 24 的 24 小时制)。例如:1…24
- a A:上午或下午(单一字符
a p
也被视为有效)。例如:am pm - m mm:分钟。例如:0…59
- s ss:秒钟。例如:0…59
- S SS SSS:带分数的秒钟。例如:0…999
- DDD DDDD:年的某天。例如:1…365
- X:Unix 时间戳。例如:1410715640.579
- x:Unix 毫秒时间戳。例如:1410715640579
不常用的格式化字符如下
1.4 获取指定日期时间的包装器对象(指定多格式)
// 获取指定日期时间的包装器对象(指定多个字符串日期时间格式)
var now2 = moment('2021-10-20', ['YYYY-MM-DD','MM-DD-YYYY']);
console.log(now2.year());
- 从数组的左侧到右侧格式依次尝试,返回满足格式的一个日期时间的包装器对象。
- 不推荐使用,比单一格式慢的多。
1.5 获取指定日期时间的包装器对象(内置固定格式)
// 获取指定日期时间的包装器对象(内置特定格式)
var now4 = moment('2021-10-20', moment.HTML5_FMT.DATE);
console.log(now4.year());
固定格式类型如下:
1.6 获取指定日期时间的包装器对象(指定日期时间对象)
// 获取指定日期时间的包装器对象
var now5 = moment({
year: 2021, // 年
month: 2, // 月
day: 5, // 日
hour: 13, // 时
minute: 5, // 分
second: 30, // 秒
millisecond: 200 // 毫秒
});
console.log(now5.format('YYYY-MM-DD HH:mm:ss')); //2021-03-05 13:05:30
1.7 获取指定日期时间的包装器对象(指定毫秒数)
var now6 = moment(1318781876406);
console.log(now6.format('YYYY-MM-DD HH:mm:ss')); //2011-10-17 00:17:56
注:值必须是数值。
1.8 获取指定日期时间的包装器对象(根据原生Date对象)
var now7 = moment(new Date(2011, 8, 23));
console.log(now7.format('YYYY-MM-DD HH:mm:ss')); //2011-09-23 00:00:00
1.9 获取指定日期时间的包装器对象(根据数值数组)
// 数组对应下标值表示 [year, month, day, hour, minute, second, millisecond]
var now8 = moment([2011, 10, 22, 5, 12, 23, 400]);
console.log(now8.format('YYYY-MM-DD HH:mm:ss')); //2011-11-22 05:12:23
注意月份值显示。
1.10 获取指定日期时间的包装器对象(显示克隆已有包装器对象)
var a = moment([2012]);
var b = moment(a); //克隆对象
a.year(2000); //该表原有的值
console.log(b.year()); //2012,克隆对象的值不随原有对象值改变而改变
重点:
- 所有Moment对象的值设置或修改都会影响到自己本身。
- 克隆对象的值不会随原有对象的值改变而改变。
1.11 获取指定日期时间的包装器对象(检验是否有效的日期时间包装器对象)
var now9 = moment([2015, 25, 35]);
console.log(now9.isValid()); // true-正确日期时间 false-非正确日期时间
console.log(now9.invalidAt()); // 出错的位置
- isValid方法:判断包装器对象是否含有正常的日期时间对象,true - 正常 false - 异常。
- invalidAt方法:获取出现异常的位置。
- 0:年份
- 1:月份
- 2:日期
- 3:小时
- 4:分钟
- 5:秒钟
- 6:毫秒
1.12 获取指定日期时间的包装器对象(指定固定值,其他都为默认值)
moment(5, "HH"); // 今天 5:00:00.000
moment({hour: 5}); // 今天 5:00:00.000
moment({hour: 5, minute: 10}); // 今天 5:10.00.000
moment({hour: 5, minute: 10, seconds: 20}); // 今天 5:10.20.000
moment({hour: 5, minute: 10, seconds: 20, milliseconds: 300}); // 今天 5:10.20.300
默认值为当前日期时间,除了设置值外,其他都是默认。
2. 取值/赋值
Moment.js 使用重载的 getter 和 setter 方法。不带参数调用这些方法会作为 getter,而带参数调用则会作为 setter。这些会映射到原生 Date
对象上的相应函数。
moment().seconds(30).valueOf() === new Date().setSeconds(30);
moment().seconds() === new Date().getSeconds();
2.1 毫秒值
// millisecond() --> 获取毫秒值
var num1 = moment().millisecond();
console.log(num1); // 824
// millisecond(600) --> 设置毫秒值
var now1 = moment().millisecond(600);
num1 = now1.millisecond();
console.log(num1); // 600
注:毫秒值设置的数值范围为 0 ~ 999 。若这个值超过了这个范围,则溢出到秒钟值,相应的秒钟值也会增加。
2.2 秒钟值
// second() --> 获取秒钟值
var num1 = moment().second();
console.log(num1); // 12
// second(40) --> 设置秒钟值
var now1 = moment().second(40);
num1 = now1.second();
console.log(num1); // 40
注:秒钟值设置的数值范围为 0 ~ 59 。若这个值超过了这个范围,则溢出到分钟值,相应的分钟值也会增加。
2.3 分钟值
// minute() --> 获取分钟值
var num1 = moment().minute();
console.log(num1); // 3
// minute(40) --> 设置分钟值
var now1 = moment().minute(40);
num1 = now1.minute();
console.log(num1); // 40
注:分钟值设置的数值范围为 0 ~ 59 。若这个值超过了这个范围,则溢出到小时值,相应的小时值也会增加。
2.4 小时值
// hour() --> 获取小时值
var num1 = moment().hour();
console.log(num1); // 21
// hour(12) --> 设置小时值
var now1 = moment().hour(12);
num1 = now1.hour();
console.log(num1); // 12
注:小时值设置的数值范围为 0 ~ 23 。若这个值超过了这个范围,则溢出到日期值,相应的日期值也会增加。
2.5 日期值
// date() --> 获取日期值
var num1 = moment().date();
console.log(num1); // 9
// date(12) --> 设置日期值
var now1 = moment().date(12);
num1 = now1.date();
console.log(num1); // 12
// 溢出的天数按照当月总共的天数算
var now1 = moment("6", "MM").date(31);
console.log(now1.format('YYYY-MM-DD')); // 2022-07-01
注:日期值设置的数值范围为 1 ~ 31 。若这个值超过了这个范围,则溢出到月份值,相应的月份值也会增加。同时如果这个月没有31天,则获取到的日期值为30。
2.6 星期几值
var now1 = moment().day(0);
console.log(now1.format('YYYY-MM-DD')); // 2022-08-07 当前日期为2022-08-12,星期五
-
设置或获取星期几值,其中星期日为 0、星期六为 6。
-
如果超出范围,则它将会冒泡到其他星期。
moment().day(-7); // 上个星期日 (0 - 7) moment().day(0); // 这个星期日 (0) moment().day(7); // 下个星期日 (0 + 7) moment().day(10); // 下个星期三 (3 + 7) moment().day(24); // 从现在起第 3 个星期三 (3 + 7 + 7 + 7)
2.7 月份值
var now1 = moment().month(1);
console.log(now1.format('YYYY-MM-DD')); //2022-02-12,当前日期:2022-08-12
-
获取或设置月份。接受 0 到 11 之间的数字。
-
如果超出范围,则它将会冒泡到年份。
-
如果当前月份的日期值为31超过了设置月份的天数,则强制限制在目标月份的月末。
moment([2012, 0, 31]).month(1).format("YYYY-MM-DD"); // 2012-02-29
2.8 季度值
var now1 = moment().quarter(2);
console.log(now1.format('YYYY-MM-DD')); //2022-05-12,当前日期:2022-08-12
- 获取或设置季度值。接受 1 到 4 之间数字。
- 如果超出范围,则它将会冒泡到年份。
2.9 年份值
var now1 = moment().year(2020);
console.log(now1.format('YYYY-MM-DD')); //2020-08-12,当前日期:2022-08-12
- 获取或设置年份值。接受 -270,000 到 270,000 之间的数字。
2.10 获取对应的值
var now1 = moment().get('year');
console.log(now1); // 2022
- 通过get方法获取对应的数值。
- get中的参数值可选如下:year (years, y)、month (months, M)、date (dates, D)、hour (hours, h)、minute (minutes, m)、second (seconds, s)、millisecond (milliseconds, ms)。
2.11 设置对应的值
var now1 = moment().set('year', 2020);
console.log(now1.format('YYYY-MM-DD')); // 2020-08-12
var now2 = moment().set({"year": 2020, month: 9});
console.log(now2.format('YYYY-MM-DD'));// 2020-10-12
- 通过set方法设置对应的日期数据。
- 两种形式:
- 第一种:第一个参数设置关键字,第二个参数设置数值。
- 第二种:对象,对象键名为设置关键字,第二个参数为设置的数值。
- 关键字可选如下: year (years, y)、month (months, M)、date (dates, D)、hour (hours, h)、minute (minutes, m)、second (seconds, s)、millisecond (milliseconds, ms)。
2.12 比较多个日期值并返回较大值
var now1 = moment().set('year', 2020);
var now2 = moment().set({"year": 2020, month: 9});
var now3 = moment.max(now1, now2);
console.log(now3.format('YYYY-MM-DD'));// 2020-10-12
- 通过max方法获取日期中的较大值。
- 该方法可传两个或两个以上的参数,并返回多个日期中的较大值。
- 若第一个参数不是有效的moment对象,返回无效moment对象。
2.13 比较多个日期值并返回较小值
var now1 = moment().set('year', 2020);
var now2 = moment().set({"year": 2020, month: 9});
var now3 = moment.max(now1, now2);
console.log(now3.format('YYYY-MM-DD'));// 2020-08-12
- 通过min方法获取日期中的较小值。
- 该方法可传两个或两个以上的参数,并返回多个日期中的较小值。
- 若第一个参数不是有效的moment对象,返回无效moment对象。
3. 操作
注:这些操作方法会直接改变原始的moment对象。所以一定要注意。
3.1 增加时间
var now1 = moment().add(7, 'days'); //当前时间为2022-08-12
console.log(now1.format('YYYY-MM-DD')); //2022-08-19
var now2 = moment().add({ days:7 }); //当前时间为2022-08-12
console.log(now2.format('YYYY-MM-DD')); //2022-08-19
var now3 = moment([2010, 0, 31]).add(1, 'months'); //当前时间为2010-01-31
console.log(now3.format('YYYY-MM-DD')); //2022-02-28
- add方法可以在当前时间的基础上加上设置日期数值。
- 如果原始日期的月份中的日期大于最终月份中的天数,则该月份中的日期将会更改为最终月份中的最后一天。
- 快捷键如下:
- years:y
- quarters:Q
- months:M
- weeks:w
- days:d
- hours:h
- minutes:m
- seconds:s
- milliseconds:ms
3.2 减少时间
var now1 = moment().subtract(7, 'days'); //当前时间为2022-08-12
console.log(now1.format('YYYY-MM-DD')); //2022-08-19
var now2 = moment().subtract({ days:7 }); //当前时间为2022-08-12
console.log(now2.format('YYYY-MM-DD')); //2022-08-19
var now3 = moment([2010, 2, 31]).subtract(1, 'months'); //当前时间为2010-01-31
console.log(now3.format('YYYY-MM-DD')); //2022-02-28
- subtract方法可以在当前时间的基础上减去设置日期数值。
- 当为日期和月份传入小数时,它们会被四舍五入到最接近的整数。
3.3 设置时间以某个时间单位开头的时间
moment().startOf('year'); // 设置为今年一月1日 00:00:00
moment().startOf('month'); // 设置为本月1日 00:00:00
moment().startOf('quarter'); // 设置为当前季度的开始,即每月的第一天 00:00:00
moment().startOf('week'); // 设置为本周的第一天 00:00:00
moment().startOf('date'); // 设置为今天 00:00:00
moment().startOf('hour'); // 设置为当前时间,但是 0 分钟、0 秒钟、0 毫秒
moment().startOf('minute'); // 设置为当前时间,但是 0 秒钟、0 毫秒
moment().startOf('second'); // 与 moment().milliseconds(0); 相同
3.4 设置时间以某个时间单位结尾的时间
moment().endOf("year"); // 将 moment 设置为今年的 12 月 31 日 23:59:59.999
4. 显示
一旦解析和操作完成后,需要某些方式来显示 moment。
4.1 格式化输出字符串
console.log(moment().format('YYYY-MM-DD HH:mm:ss')); //2022-08-19 15:03:12
格式化符号表示含义
- 年份:YY(两位年份)、YYYY(四位年份)
- 季度:Q(1 2 3 4)
- 月份:M(1 2 … 11 12)、MM(01 02 … 11 12)
- 月份的日期:D(1 2 … 30 31)、DD(01 02 … 30 31)
- 年份的日期:DDD(1 2 … 364 365)、DDDD(001 002 … 364 365)
- 星期几:d(0 1 … 5 6)
- 年份的星期:w(1 2 … 52 53)、ww(01 02 … 52 53)
- 小时:H(0 1 … 22 23)、HH(00 01 … 22 23)
- 分钟:m(0 1 … 58 59)、mm(00 01 … 58 59)
- 秒钟:s(0 1 … 58 59)、ss(00 01 … 58 59)
- 毫秒钟:SSS(000 001 … 998 999)
4.2 相对于当前时间的时间间隔
console.log(moment([2007, 0, 29]).fromNow()); // 16 years ago
console.log(moment([2007, 0, 29]).fromNow(true)); // 16 years
console.log(moment([2027, 0, 29]).fromNow()); // in 4 years
console.log(moment([2027, 0, 29]).fromNow(true)); // 4 years
- 若加了参数true,表示没有描述符修饰。
- age表示什么之前,in表示什么之后。
- toNow方法为此方法的相反方法,表示相比较当前之间之后。
4.3 相对于指定时间的时间间隔
console.log(moment([2007, 0, 29]).from(moment([2008, 0, 29]))); // a year ago
console.log(moment([2007, 0, 29]).from([2008, 0, 29])); // a year ago
console.log(moment([2007, 0, 29]).from(new Date(2008, 0, 29))); // a year ago
console.log(moment([2007, 0, 29]).from("2008-01-29")); // a year ago
- from的参数表示指定的参照时间。
- 参数的形式可以有四种。例如moment对象、日期设置数组、Date对象、日期格式字符串。
- to方法为此方法的想法方法,表示相比较指定时间之后的时间。
4.4 两个时间之间的差值(可设置单位)
var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days'); // 1
- diff:比较a比b多设置计量单位的差值。
- 第二个参数如果不设置,默认为毫秒值。
4.5 获取moment对象秒数
moment().valueOf(); //1318874398806
- valueOf表示自该纪元以来的秒数。(时间戳)
4.6 获取当月的天数
moment().daysInMonth(); //31
4.7 获取原生的Date对象
moment().toDate();
4.8 获取设置的日期时间数组
moment().toArray(); // [2013, 1, 4, 14, 40, 16, 154];
- 数组的值从左到右依次是:年、月、日、时、分、秒、毫秒。
4.9 获取包含日期时间的对象
moment().toObject() // {
// years: 2015
// months: 6
// date: 26,
// hours: 1,
// minutes: 53,
// seconds: 14,
// milliseconds: 600
// }
5. 查询(对比)
5.1 对比某个时间是否在另外一个时间之前
格式:moment().isBefore(Moment|String|Number|Date|Array, String);
// 若第二个参数不传,表示比较粒度限制为毫秒
moment('2010-10-20').isBefore('2010-10-21'); // true
// 若第二个参数设置,表示比较粒度限制为第二个参数
moment('2010-10-20').isBefore('2010-12-31', 'year'); // false
moment('2010-10-20').isBefore('2011-01-01', 'year'); // true
5.2 对比两个时间是否相同
格式:moment().isSame(Moment|String|Number|Date|Array, String);
// 若第二个参数不传,表示比较粒度限制为毫秒
moment('2010-10-20').isSame('2010-10-20'); // true
// 若第二个参数设置,表示比较粒度限制为第二个参数
moment('2010-10-20').isSame('2009-12-31', 'year'); // false
moment('2010-10-20').isSame('2010-01-01', 'year'); // true
5.3 对比某个时间是否在另外一个时间之后
格式:moment().isAfter(Moment|String|Number|Date|Array, String);
// 若第二个参数不传,表示比较粒度限制为毫秒
moment('2010-10-20').isAfter('2010-10-19'); // true
// 若第二个参数设置,表示比较粒度限制为第二个参数
moment('2010-10-20').isAfter('2010-01-01', 'year'); // false
moment('2010-10-20').isAfter('2009-12-31', 'year'); // true
5.4 对比某个时间是否等于或在另外一个时间之前
格式:moment().isSameOrBefore(Moment|String|Number|Date|Array, String);
// 若第二个参数不传,表示比较粒度限制为毫秒
moment('2010-10-20').isSameOrBefore('2010-10-21'); // true
moment('2010-10-20').isSameOrBefore('2010-10-20'); // true
moment('2010-10-20').isSameOrBefore('2010-10-19'); // false
// 若第二个参数设置,表示比较粒度限制为第二个参数
moment('2010-10-20').isSameOrBefore('2009-12-31', 'year'); // false
moment('2010-10-20').isSameOrBefore('2010-12-31', 'year'); // true
moment('2010-10-20').isSameOrBefore('2011-01-01', 'year'); // true
5.5 对比某个时间是否等于或在另外一个时间之后
格式:moment().isSameOrAfter(Moment|String|Number|Date|Array, String);
// 若第二个参数不传,表示比较粒度限制为毫秒
moment('2010-10-20').isSameOrAfter('2010-10-19'); // true
moment('2010-10-20').isSameOrAfter('2010-10-20'); // true
moment('2010-10-20').isSameOrAfter('2010-10-21'); // false
// 若第二个参数设置,表示比较粒度限制为第二个参数
moment('2010-10-20').isSameOrAfter('2011-12-31', 'year'); // false
moment('2010-10-20').isSameOrAfter('2010-01-01', 'year'); // true
moment('2010-10-20').isSameOrAfter('2009-12-31', 'year'); // true
5.6 对比某个时间是否在某个时间范围内
格式:moment().isBetween(moment-like, moment-like, String);
// 若第二个参数不传,表示比较粒度限制为毫秒
moment('2010-10-20').isBetween('2010-10-19', '2010-10-25'); // true
// 若第二个参数设置,表示比较粒度限制为第二个参数
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
5.7 判断是否是闰年
moment().isLeapYear();
- 若是闰年,则返回true,否则返回false。
5.8 判断是否是moment对象
moment.isMoment(obj);
5.9 判断是否是原生Date对象
moment.isDate(obj);