从Oracle数据库中查询前几个月数据时需要注意的一些问题
在最近的一个项目中,有一个需求就是要查询数据库中前几个月的历史数据,但是由于自己考虑不全面造成了程序的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之间,返回的天必须在当月的合理范围内,这个需要在写代码的时候十分注意,并及时作出总结,并未以后吸取经验和教训。