一般的方法中,2月28日和2月29日新增月份得到的日期都是28日或者29日,但是其他月份都是可以正常的加一个月的,所以可以回退一个月,遇到2月28日或2月29日时,可以退回1月31日,只要做好闰年的判断就好了。
1 function addMonthPerfect(num) { 2 var dateNow = new Date(); 3 if ((dateNow.getMonth()+1)==2) { 4 if (dateNow.getDate() == 29) { 5 dateNow = new Date(dateNow.getFullYear() + "-1-31"); 6 num += 1; 7 } else if(dateNow.getDate()==28) { 8 if (!isLeapYear(dateNow.getFullYear())) { 9 dateNow = new Date(dateNow.getFullYear() + "-1-31"); 10 num += 1; 11 } 12 } 13 } 14 return addMonth(dateNow, num).format("yyyy-MM-dd"); 15 } 16 17 function isLeapYear(year) { 18 var cond1 = year % 4 == 0; 19 var cond2 = year % 100 != 0; 20 var cond3 = year % 400 == 0; 21 var cond = cond1 && cond2 || cond3; 22 if (cond) { 23 return true; 24 } else { 25 return false; 26 } 27 } 28 29 function addMonth(date, num) { 30 num = parseInt(num); 31 var sDate = dateToDate(date); 32 33 var sYear = sDate.getFullYear(); 34 var sMonth = sDate.getMonth() + 1; 35 var sDay = sDate.getDate(); 36 37 var eYear = sYear; 38 var eMonth = sMonth + num; 39 var eDay = sDay; 40 while (eMonth > 12) { 41 eYear++; 42 eMonth -= 12; 43 } 44 45 var eDate = new Date(eYear, eMonth - 1, eDay); 46 47 while (eDate.getMonth() != eMonth - 1) { 48 eDay--; 49 eDate = new Date(eYear, eMonth - 1, eDay); 50 } 51 52 return eDate; 53 }; 54 55 function dateToDate(date) { 56 var sDate = new Date(); 57 if (typeof date == 'object' 58 && typeof new Date().getMonth == "function" 59 ) { 60 sDate = date; 61 } 62 else if (typeof date == "string") { 63 var arr = date.split('-'); 64 if (arr.length == 3) { 65 sDate = new Date(arr[0] + '-' + arr[1] + '-' + arr[2]); 66 } 67 } 68 69 return sDate; 70 } 71 Date.prototype.format = function (format) { 72 if (format) { } else { format = "yyyy-MM-dd"; } 73 var o = { 74 "M+": this.getMonth() + 1, //month 75 "d+": this.getDate(), //day 76 "h+": this.getHours(), //hour 77 "m+": this.getMinutes(), //minute 78 "s+": this.getSeconds(), //second 79 "q+": Math.floor((this.getMonth() + 3) / 3), //quarter 80 "S": this.getMilliseconds() //millisecond 81 } 82 if (/(y+)/.test(format)) format = format.replace(RegExp.$1, 83 (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 84 for (var k in o) if (new RegExp("(" + k + ")").test(format)) 85 format = format.replace(RegExp.$1, 86 RegExp.$1.length == 1 ? o[k] : 87 ("00" + o[k]).substr(("" + o[k]).length)); 88 return format; 89 }