筆者在做專案的時候,需要對日期和時間進行一些處理和操作,但是每次都用JS自帶的Date物件很不方便,還要寫一堆繁瑣的程式碼,後續維護起來也很痛苦。在網上找了一下JS處理日期和時間的外掛,發現了MomentJS很好用,學習了一下它的語法,發現十分的簡潔易懂,而且可擴充套件性很強,呼叫方法靈活。很多的方法呼叫形式多樣,支援多種傳引數方式。下面簡單的整理了一下使用方式
構造Moment物件
MomentJS將時間封裝成一個物件,moment物件,這個物件很多種構造方式,可以支援傳入字串、陣列和物件的形式來構造。
當前系統時間
如果什麼都不傳,就獲取當前的系統時間。
var now = moment()
複製程式碼
字串構造
可以傳入字串,首先會檢查字串的格式是否符合ISO 8601
的格式,如果不符合,就呼叫new Date(string)
來構造。
已知格式字串
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
的格式,但是你知道輸入的字串的格式,也可以通過這種方式解析,解析的語法有以下四種格式:
moment(String, String);
moment(String, String, String);
moment(String, String, Boolean);
moment(String, String, String, Boolean);
複製程式碼
第一種已知某個時間的格式,將格式作為第二個引數傳入
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 | 秒 |
第二種,可以將當地區域的關鍵符作為第三個引數傳入。
moment('2012 juillet', 'YYYY MMM', 'fr');
moment('2012 July', 'YYYY MMM', 'en');
複製程式碼
MomentJS的匹配模式是十分寬鬆的,並且可能會導致一些我們不想要的行為。從2.3.0
版本開始,我們可以在最後傳入一個布林值來讓Moment使用嚴格模式匹配。嚴格模式要求輸入的字串和格式要完全相同。
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
複製程式碼
字串+多格式
假如你不知道輸入的字串確切是用的哪種格式,但是知道是某些格式中的一種,可以將多種格式用陣列的形式傳入,將會以最先匹配到的格式為輸出結果。
moment("12-25-1995", ["MM-DD-YYYY", "YYYY-MM-DD"]);
複製程式碼
物件
我們也可以通過傳入一個物件的形式來建立moment物件,傳入的物件中包括一些時間單位的屬性。
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物件。
var day = new Date(2011, 9, 16);
var dayWrapper = moment(day);
複製程式碼
陣列
我們可以傳入一個數字的陣列來建立moment物件,陣列中每個每個數字代表的含義如下:
// [年, 月, 日, 時, 分, 秒, 毫秒]
moment([2010, 1, 14, 15, 25, 50, 125]);
//2010年2月14日15時25分50秒125毫秒
複製程式碼
需要注意的是:陣列中的月、時、分、秒、毫秒都是從0開始的,而年和日都是從1開始的。
取值and賦值
MomentJS使用可以過載的get和set方法,跟我們以前在jQuery中的形式很相似。我們可以呼叫這些方法不傳引數作來獲取,傳入引數作來設定。
自帶函式
獲取或者設定毫秒,設定的範圍0到999
moment().millisecond(Number);
moment().millisecond(); // Number
moment().milliseconds(Number);
moment().milliseconds(); // Number
複製程式碼
獲取或者設定秒,設定的範圍0到59
moment().second(Number);
moment().second(); // Number
moment().seconds(Number);
moment().seconds(); // Number
複製程式碼
獲取或者設定分鐘,設定的範圍0到59
moment().minute(Number);
moment().minute(); // Number
moment().minutes(Number);
moment().minutes(); // Number
複製程式碼
獲取或者設定小時,設定的範圍0到23
moment().hour(Number);
moment().hour(); // Number
moment().hours(Number);
moment().hours(); // Number
複製程式碼
獲取或者設定日期,設定的範圍1到31
moment().date(Number);
moment().date(); // Number
moment().dates(Number);
moment().dates(); // Number
複製程式碼
獲取或者設定星期,設定的範圍0(週日)到6(週六)
moment().day(Number|String);
moment().day(); // Number
moment().days(Number|String);
moment().days(); // Number
複製程式碼
獲取或者設定一年中的天數,設定的範圍1到366
moment().dayOfYear(Number);
moment().dayOfYear(); // Number
複製程式碼
獲取或者設定一年中的周
moment().week(Number);
moment().week(); // Number
moment().weeks(Number);
moment().weeks(); // Number
複製程式碼
獲取或者設定一年中的月份,設定的範圍0到11
moment().month(Number|String);
moment().month(); // Number
moment().months(Number|String);
moment().months(); // Number
複製程式碼
獲取或者設定季度,設定的範圍1到4
moment().quarter(); // Number
moment().quarter(Number);
複製程式碼
獲取或者設定年,設定的範圍-270000到270000
moment().year(Number);
moment().year(); // Number
moment().years(Number);
moment().years(); // Number
複製程式碼
取值and賦值函式
除了上面的這麼多函式外,MomentJS還有一個用來統一取值和賦值的函式,get和set。
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函式接收單位作為第一個引數,單位的值作為第二個引數。如果要設定多個值的話,也可以通過傳入一個物件。
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物件中最大的例項,也就是最靠近未來的例項。
var a = moment('2017-12-01');
var b = moment('2017-12-06');
moment.max(a, b); // b
複製程式碼
min函式可以返回給定的moment物件中最小的例項,也就是最靠近過去的例項。
var a = moment('2017-12-01');
var b = moment('2017-12-06');
moment.min(a, b); // a
複製程式碼
操作
有時候,我們需要對時間進行一系列的操作,最常見的就是加減計算。MomentJS提供了很多方法給我們來進行呼叫。 MomentJS使用的模式跟jQuery相似,都是使用的函式的鏈式呼叫,可以讓我們將操作鏈式執行下去,程式碼如下所示:
moment()
.add(7, 'days')
.subtract(1, 'months')
.year(2009)
.hours(0)
.minutes(0)
.seconds(0);
複製程式碼
add加法
add函式讓我們把Moment物件的時間往後退,它的語法如下:
moment().add(Number, String);
moment().add(Duration);
moment().add(Object);
複製程式碼
我們可以傳入想要的增加的時間數量和時間單位,比如要往後推遲7天:
moment().add(7, 'days');
複製程式碼
當然,add函式也允許我們提供時間單位的縮寫:
moment().add(7, 'd');
複製程式碼
時間單位 | 縮寫 |
---|---|
years | y |
quarters | Q |
months | M |
weeks | W |
days | d |
hours | h |
minutes | m |
seconds | s |
milliseconds | ms |
如果想要同時增加不同時間單位,可以以物件的形式傳入:
moment().add(7, 'days').add(1, 'months');
moment().add({days:7,months:1});
複製程式碼
需要注意的是,如果原始日期的天數比新增後的日期的月份的總天數還要多,就變為該月的最後一天:
// 01-31
moment([2010, 0, 31]);
// 02-28
moment([2010, 0, 31]).add(1, 'months');
//2月份沒有31號,自動變為最後一天,即28號
複製程式碼
subtract減法
subtract函式的用法和add相似,不同的是把時間往前推。
moment().subtract(Number, String);
moment().subtract(Duration);
moment().subtract(Object);
複製程式碼
startOf開始時間
startOf函式將Moment物件的時間設定為傳入單位的開始時間。
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相似。
moment().endOf(String);
複製程式碼
顯示
當我們解析和操作完Moment物件後,我們就需要對最後的結果進行展示。
format格式化
format函式接收token字串,並且將token替換成對應的值。
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時差
語法
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物件的時間差,預設的單位是毫秒。
var a = moment([2017, 12, 29]);
var b = moment([2017, 12, 28]);
a.diff(b) // 86400000
複製程式碼
除了得到毫秒為單位,diff函式還支援獲取其他的時間單位,將其作為第二個引數傳入:
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。
var a = moment([2008, 6]);
var b = moment([2007, 0]);
a.diff(b, 'years'); // 1
a.diff(b, 'years', true); // 1.5
複製程式碼
daysInMonth獲取當前月份的天數
daysInMonth獲取當前月的總天數
moment("2012-02", "YYYY-MM").daysInMonth() // 29
moment("2012-01", "YYYY-MM").daysInMonth() // 31
複製程式碼
toDate轉為Date物件
將Moment物件轉為js原生的Date物件
toArray轉為陣列
返回時間陣列,和構造Moment物件時傳入的陣列代表的含義相同。
moment().toArray(); // [2017, 12, 9, 13, 40, 16, 154];
複製程式碼
toObject
將Moment物件轉為包含年月日時分秒毫秒的物件。
moment().toObject() // {
// years: 2017
// months: 12
// date: 9,
// hours: 13,
// minutes: 40,
// seconds: 18,
// milliseconds: 600
// }
複製程式碼
查詢
查詢操作主要用來判斷Moment是否滿足某些條件。
isBefore是否之前
moment().isBefore(Moment|String|Number|Date|Array);
moment().isBefore(Moment|String|Number|Date|Array, String);
複製程式碼
isBefore判斷一個moment物件是否在某個時間點之前。
moment('2010-10-20').isBefore('2010-10-21'); // true
複製程式碼
預設的比較單位是毫秒,但是假如我們想要限制到其他的時間單位,我們可以將其作為第二個引數傳入。接受的單位和startOf支援的單位一樣。
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是否相同
moment().isSame(Moment|String|Number|Date|Array);
moment().isSame(Moment|String|Number|Date|Array, String);
複製程式碼
isSame判斷一個moment物件是否和另一個moment物件相同。
moment('2010-10-20').isSame('2010-10-20'); // true
moment('2010-10-20').isSame('2010-10-21'); // false
複製程式碼
同樣的,我們如果要將比較的單位改為其他的,也可以作為第二個引數傳入。接受的單位和startOf支援的單位一樣。
moment('2010-10-20').isSame('2009-12-31', 'year'); // false
moment('2010-10-20').isSame('2010-01-01', 'year'); // true
複製程式碼
當傳入第二個引數時,它會匹配所有相同或者更大的單位。比如傳入了月份,將會比較年和月,傳入了日期,將會比較年月日
// false, 不同的年
moment('2010-01-01').isSame('2011-01-01', 'month');
// false, 不同的月
moment('2010-01-01').isSame('2010-02-01', 'day');
複製程式碼
isAfter是否之後
isBefore判斷一個moment物件是否在某個時間點之後。接受的單位和startOf支援的單位一樣。
moment('2010-10-20').isAfter('2010-10-19'); // true
複製程式碼
isBetween是否之間
moment().isBetween(moment-like, moment-like);
moment().isBetween(moment-like, moment-like, String);
//moment-like 表示 Moment|String|Number|Date|Array
複製程式碼
判斷一個moment物件是否在兩個其他時間點之間。
moment('2017-10-20').isBetween('2017-10-19', '2017-10-25'); // true
複製程式碼
傳入第二個引數作為限制的單位。接受的單位和startOf支援的單位一樣。
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。
moment([2000]).isLeapYear() // true
moment([2001]).isLeapYear() // false
moment([2100]).isLeapYear() // false
複製程式碼
isMoment 是否Moment物件
判斷是否Moment物件
moment.isMoment() // false
moment.isMoment(new Date()) // false
moment.isMoment(moment()) // true
複製程式碼
isDate是否Date物件
判斷是否Date物件
moment.isDate(); // false
moment.isDate(new Date()); // true
moment.isDate(moment()); // false
複製程式碼