set操作還是有不少的,具體見 http://www.w3school.com.cn/jsref/jsref_obj_date.asp, 今天我就只說 setFullYear, setMonth, setDate,因為今天的應用只涉及到這三個。 這3個方法顧名思義分別設置年、月、日,之前我所瞭解到的 ...
set操作還是有不少的,具體見 http://www.w3school.com.cn/jsref/jsref_obj_date.asp,
今天我就只說 setFullYear, setMonth, setDate,因為今天的應用只涉及到這三個。
這3個方法顧名思義分別設置年、月、日,之前我所瞭解到的應用,比如“倒計時”中設置目標時間點的時候會用到,其他的暫時記不起來,回頭再補。
今天來說說“獲取當前月(季度/年)的最後一天”的用法
你可能想到了,每個月的天數是不應定的,有28、29(閏年2月)、30、31,總不能去算一下現在是幾月份,然後去arr或者map(json)裡邊去找對應的日期吧,當然這也是個方法,能達到效果(還要考慮閏年)。
那麼,不這麼繁瑣的話,怎麼搞呢?
其實,Date本來就會自動處理每月的天數,包括閏年什麼的特殊情況,所以,這個我們根本不用去關心。
這裡用到一個用法,估計大家有可能也用過,date.setDate(0)。沒錯,你沒看錯,就是0。(喂,這不是month啊,不用加1,你確定不是要用setDate(1) ?)
0是不存在的一天,date.setDate(0)之後,這一天不存在,或者說設置的是1號的前一天。那麼,1號的前一天,自然就是前一個月的最後一天
1 var date = new Date(); 2 console.log('今天是 ', date.getMonth() + 1, date.getDate()); 3 date.setDate(0); 4 console.log('上個月最後一天是 ', date.getMonth() + 1, date.getDate());
控制台跑一下上邊代碼,就會得到上個月最後一天了。
繼續,我們要得到的是這個月最後一天,怎麼破
先把月份設置到下個月,然後獲取這個月最後一天:
1 date.setMonth(date.getMonth() + 1); 2 date.setDate(0);
date就是這個月最後一天對應的date對象。
到此,簡單地獲取當月最後一天已經完了,改變setMonth可以讓你獲取任何一個月的最後一天了。
~~~~~~~~~~~~~~~~~~~~~~~~~ 分割線 ~~~~~~~~~~~~~~~~~~~~~~
下麵,來講獲取這一年的最後一天的date。
同理,我們只要設置到明年就可以了,然後設置月份到0月(就是1月),然後設置到0日,這樣就成了2017-01-00,也就是元旦的前一天,當然也就是2016-12-31這天了。
1 date.setFullYear(date.getFullYear() + 1); // 設置到明年 2 date.setMonth(0); // 明年的0月,也就是對應到1月,是存在的哦,不是不存在的0 3 date.setDate(0); // 明年的0日
~~~~~~~~~~~~~~~~~~~~~~~~~ 又來分割線 ~~~~~~~~~~~~~~~~~~~~~
然後,又到了獲取當前季度的最後一天。
Date中是沒有季度的概念的(如果有,請及時告訴我,讓我多個知識點),所以,首先我們要判斷當前月在哪個季度
1 var m = date.getMonth(); 2 var quarter = Math.floor(m / 3) + 1; // 從1開始,到4 3 var qLastMonth = quarter * 3;
其中,quarter 是第幾季度,qLastMonth 是這個季度的最後一個月是幾月 // 從1開始到12,當年可以減去1,從0到11。
既然拿到了這個季度的最後一個月是幾月,那再用上邊的獲取任一月份的最後天的方法來處理就好了
1 date.setMonth(qLastMonth); 2 date.setDate(0);
這時候,date就是當前季度的最後一天的date對象了。當然,做一下擴展就可以拿到任意季度的最後一天,只要在第一步設置(喂喂,幹嘛呢,繞遠了)
要拿到任意季度的最後一天,比如第2季度,只需要。。。
1 date.setMonth(6); // 4 || 5 || 6 都行 2 date.setDate(0);
最後,來一個項目中遇到的實際應用裡子
是醬紫的:
1、獲取本季度的最後一天; 當今天是當前季度最後一天切大於15日的時候(比如6月20日),返回下個季度的最後一天。
2、獲取本年最後一天;當今天是大於12月15日的時候,返回明年的最後一天。
開始的實現代碼如下:
1 /** 2 * 獲取 當前月/當前年/當前季度 的最後一天的date對象 3 * @param {String} type 類型選擇: month/m, year/y, quarter/q 4 * @return {object} 最後一天的date對象,目前只可用到天 5 */ 6 7 var SERVER_TIME = Date.now() / 1000; // 伺服器時間,這裡用本地時間代替 8 9 function getMaxDate(type) { 10 var date = new Date(SERVER_TIME * 1000); 11 var m = date.getMonth(); 12 var y = date.getFullYear(); 13 var d = date.getDay(); 14 var today = date.getDate(); 15 console.log(['SERVERTIME: ',y,'-',m+1,'-',today,' 星期',d].join('')); 16 switch (type) { 17 case 'm': 18 case 'month': 19 date.setMonth(m + 1); 20 date.setDate(0); 21 break; 22 case 'y': 23 case 'year': 24 if (m == 11 && today >= 15) { 25 date.setFullYear(y + 2); 26 } else { 27 date.setFullYear(y + 1); 28 } 29 date.setMonth(0); 30 date.setDate(0); 31 break; 32 case 'q': 33 case 'quarter': 34 var qLastMonth = (Math.floor(m / 3) + 1) * 3; 35 date.setMonth(qLastMonth); 36 date.setDate(0); 37 38 if (m === date.getMonth() && today >= 15) { 39 date.setMonth(qLastMonth + 3); 40 date.setDate(0); 41 } 42 break; 43 default: 44 date = null; 45 } 46 47 return date; 48 }
然後,這段代碼有個大坑,平時還不一定能遇到,這不到年底了麽,它就出來了(還好不是千年蟲之類的千年一遇)
季度選擇的時候,36行或導致後邊的38行的代碼塊出問題。
比如第2季度,是沒有問題的。36行設置date的日到30號,即6月30日;假如滿足38行代碼邏輯的話,39-40行設置月份到9月30日,沒毛病,完美~
但是,假如現在是第1季度,36行設置日期到3月31日;假如滿足38行代碼邏輯的話,39-40行設置月份到6月31日,阿西吧,6月沒有31日,那麼這時候得到的date,就會是~~~~沒錯,7月1日,自挖坑啊。
所以,改代碼
1 function getMaxDate(type) { 2 var date = new Date(SERVER_TIME * 1000); 3 var m = date.getMonth(); 4 var y = date.getFullYear(); 5 var d = date.getDay(); 6 var today = date.getDate(); 7 console.log(['SERVERTIME: ', y, '-', m + 1, '-', today, ' 星期', d].join('')); 8 switch (type) { 9 case 'm': 10 case 'month': 11 date.setMonth(m + 1); 12 date.setDate(0); 13 break; 14 case 'y': 15 case 'year': 16 if (m == 11 && today >= 15) { 17 date.setFullYear(y + 2); 18 } else { 19 date.setFullYear(y + 1); 20 } 21 date.setMonth(0); 22 date.setDate(0); 23 break; 24 case 'q': 25 case 'quarter': 26 var qLastMonth = (Math.floor(m / 3) + 1) * 3; 27 if (m === date.getMonth() && today >= 15) { 28 date.setMonth(qLastMonth + 3); 29 } else { 30 date.setMonth(qLastMonth); 31 } 32 date.setDate(0); // 得到當前季度最後一天的date 33 break; 34 default: 35 date = null; 36 } 37 38 return date; 39 }
這裡得到一個註意項,月份的相關判斷,一定要在日的設置之前做好,不要再日期設置後在操作月份;或者你把日期設置到1-28之間任意數字,也就是保證不會跑到下一個月去。
bla~bla~說了一堆,有些廢話,反正是有感而寫,就當一次記錄吧~~
see U