在做一个项目时,碰到的需要按月份进行统计,如果合同到期时间不在月初或者月末,需要计算月份开始时间(xxxx年xx月01日 00时00分00秒)与合同结束时间之间相差的月份。自己写了个方法,在此记录一下。
下面上代码:
1 #region 对日期的操作 2 /// <summary> 3 /// 获取月份的天数 4 /// </summary> 5 /// <param name="month"></param> 6 /// <returns></returns> 7 private int MonthDayNumber(int year, int month) 8 { 9 int num = 0; 10 switch (month) 11 { 12 case 1: 13 num = 31; 14 break; 15 case 2: 16 if (CheckCommonOrLeapYear(year)) 17 num = 29; 18 else num = 28; 19 break; 20 case 3: 21 num = 31; 22 break; 23 case 4: 24 num = 30; 25 break; 26 case 5: 27 num = 31; 28 break; 29 case 6: 30 num = 30; 31 break; 32 case 7: 33 num = 31; 34 break; 35 case 8: 36 num = 31; 37 break; 38 case 9: 39 num = 30; 40 break; 41 case 10: 42 num = 31; 43 break; 44 case 11: 45 num = 30; 46 break; 47 case 12: 48 num = 31; 49 break; 50 } 51 return num; 52 } 53 /// <summary> 54 /// 判断年份是平年还是闰年 55 /// </summary> 56 /// <param name="year"></param> 57 /// <returns>true:闰年,false:平年</returns> 58 private bool CheckCommonOrLeapYear(int year) 59 { 60 bool flag = true; 61 if (year % 4 == 0 && year % 100 != 0) 62 flag = true; 63 else 64 { 65 if (year % 400 == 0) 66 flag = true; 67 else 68 flag = false; 69 } 70 return flag; 71 } 72 /// <summary> 73 /// 获取查询统计的月份区间的月份数 74 /// </summary> 75 /// <param name="startDate"></param> 76 /// <param name="endDate"></param> 77 /// <returns></returns> 78 private int getSelectMonthNumber(DateTime startDate, DateTime endDate) 79 { 80 int monthNumber = 0; 81 if (startDate.Year == endDate.Year) 82 { 83 monthNumber = endDate.Month - startDate.Month + 1; 84 } 85 if (endDate.Year > startDate.Year) 86 { 87 monthNumber = (endDate.Year - startDate.Year) * 12 + endDate.Month + 1 - startDate.Month; 88 } 89 return monthNumber; 90 } 91 /// <summary> 92 /// 计算两个日期之间相差的月份 93 /// </summary> 94 /// <param name="startDate"></param> 95 /// <param name="endDate"></param> 96 /// <returns></returns> 97 private double getSelectMonthNumber(string startDate, string endDate) 98 { 99 DateTime timeStart = Convert.ToDateTime(startDate); 100 DateTime timeEnd = Convert.ToDateTime(endDate); 101 double monthNumber = 0; 102 if (timeStart.Year == timeEnd.Year) 103 { 104 if (timeEnd.Day >= timeStart.Day && timeEnd.Month >= timeStart.Month) 105 { 106 monthNumber = timeEnd.Month - timeStart.Month + (Convert.ToDouble(timeEnd.Day) - Convert.ToDouble(timeStart.Day)) / Convert.ToDouble(MonthDayNumber(timeEnd.Year, timeEnd.Month)); 107 } 108 else if (timeEnd.Day < timeStart.Day && timeEnd.Month > timeStart.Month) 109 { 110 if ((timeEnd.Month - timeStart.Month) > 1) 111 { 112 TimeSpan ts = timeEnd - timeStart.AddMonths(1); 113 monthNumber = timeEnd.Month - timeStart.Month - 1 + Convert.ToDouble(ts.Days) / Convert.ToDouble(MonthDayNumber(timeEnd.Year, timeEnd.Month)); 114 } 115 else 116 { 117 TimeSpan ts = timeEnd - timeStart; 118 monthNumber = Convert.ToDouble(ts.Days) / Convert.ToDouble(MonthDayNumber(timeEnd.Year, timeEnd.Month)); 119 } 120 } 121 } 122 if (timeEnd.Year > timeStart.Year) 123 { 124 if (timeEnd.Month >= timeStart.Month) 125 { 126 if (timeEnd.Day >= timeStart.Day) 127 { 128 monthNumber = timeEnd.Month - timeStart.Month + (Convert.ToDouble(timeEnd.Day) - Convert.ToDouble(timeStart.Day)) / Convert.ToDouble(MonthDayNumber(timeEnd.Year, timeEnd.Month)); 129 } 130 else 131 { 132 TimeSpan ts = timeEnd - timeStart.AddMonths(11); 133 monthNumber = timeEnd.Month - timeStart.Month - 1 + Convert.ToDouble(ts.Days) / Convert.ToDouble(MonthDayNumber(timeEnd.Year, timeEnd.Month)); 134 } 135 } 136 else 137 { 138 if (timeEnd.Day >= timeStart.Day) 139 { 140 monthNumber = timeEnd.Month + 12 - timeStart.Month + Convert.ToDouble(timeEnd.Day - timeStart.Day) / Convert.ToDouble(MonthDayNumber(timeEnd.Year, timeEnd.Month)); 141 } 142 else { 143 TimeSpan ts = timeEnd - timeStart.AddMonths(timeEnd.Month + 12 - timeStart.Month ); 144 monthNumber = timeEnd.Month + 12 - timeStart.Month + Convert.ToDouble(ts.Days) / Convert.ToDouble(MonthDayNumber(timeEnd.Year, timeEnd.Month)); 145 } 146 } 147 } 148 149 return monthNumber; 150 } 151 #endregion
下面贴上几张测试的图:
由于是实际业务中所使用的,调用方法前,就已经判定必须满足结束时间大于等于开始时间,所以在demo中没有加上结束时间大于开始时间的判断。