在最近的一個項目中,有一個需求就是要查詢數據庫中前幾個月的歷史數據,但是由於自己考慮不全面造成了程序的bug,現在將這一塊好好作一個總結,希望以后不再犯這種很低級的錯誤,首先貼出查詢中用到的一個子函數,然后就此作出詳細的分析:
private string AddMonths(string originalTime, int months) { string returnString = string.Empty; string[] dataAndTime = originalTime.Split(new char[] { ' ' }); if (dataAndTime.Length > 0) { string date = ""; if (!string.IsNullOrWhiteSpace(dataAndTime[0])) { date = dataAndTime[0]; string[] yearMonthDay = date.Split(new char[] { '/' }); int year = int.Parse(yearMonthDay[0]); int month = int.Parse(yearMonthDay[1]); int day = int.Parse(yearMonthDay[2]); if (months != 0) { if (month > months) { month = month - months; //判斷該月總共有多少天 int days = DateTime.DaysInMonth(year, month); if (day > days) day = days; returnString = year.ToString() + "/" + month.ToString() + "/" + day.ToString() + " " + dataAndTime[1]; } if (month ==months) { month = 12; year = year - 1; int days = DateTime.DaysInMonth(year, month); if (day > days) day = days; returnString = year.ToString() + "/" + month.ToString() + "/" + day.ToString() + " " + dataAndTime[1]; } if (month < months) { month = month + 12 - months; year = year - 1; int days = DateTime.DaysInMonth(year, month); if (day > days) day = days; returnString = year.ToString() + "/" + month.ToString() + "/" + day.ToString() + " " + dataAndTime[1]; } } else { returnString = originalTime; } } } return returnString; }
這個函數中有兩個參數,第一個originalTime代表的是從數據庫中查詢到的最近的日期,第二個參數就是months,表示從最近日期往前推多少個月,在我們的程序中首先通過分割字符串的方式來獲取當前的年月日,就我們當前的月份month和查詢周期months作比較,第一種情況就是當前月份大於查詢周期,這種情況獲取的最后月份就是month和months作差,在這里年不需要變化,但是必須注意到的一點是day的取值,舉個例子從數據庫中查詢到的當前剛好是12月31號,此時如果查詢周期為6個月,直接返回差值6月31號的話程序必然會出錯,因為6月份沒有31號,這點必須引起重視,所以我們在程序中才有了如下的判斷,
int days = DateTime.DaysInMonth(year, month)
if (day > days)
day = days;
這里面有個函數DateTime.DaysInMonth(year, month)這個函數是用來判斷某一年某一月總共有多少天,如果當前日期天數超過了查詢后的日期當月的天數那么只能取當月的最大天數了,就像12月31號往前推6個月一定是6月30號而不是6月31號,這些簡單的邏輯問題一定不能出錯,這個是需要特別注意的。根據month和months的關系必須分三種情況來討論,即:month>months和month=months以及month<months三種情況進行討論一種都不能少,總之返回的日期必須合理年,月份必須在1到12之間,返回的天必須在當月的合理范圍內,這個需要在寫代碼的時候十分注意,並及時作出總結,並未以后吸取經驗和教訓。