换了一家公司,当天便接到一个统计模块的开发,要求是从数据库当中提取到指定时间段的数据,并按照前端给的分割单位时间进行数据返回,统计什么呢?就是统计这些记录在某一天有几条,某一周有几条,以此类推。
例如:
0 2016/8/12 12:00 xxxxxxx
1 2016/8/12 14:51 xxxxxxx
2 2016/8/13 01:52 xxxxxxx
3 2016/8/18 20:14 xxxxxxx
4 2016/8/18 20:16 xxxxxxx
5 2016/8/13 12:08 xxxxxxx
提取数据简单,因为用的EF框架,所以直接从DBSession当中用linq抓取数据即可,我们将这些日期数据存储在List容器内。
不过后面才是正题,数据是抓取到了,不过我们又该怎样从这一堆数据当中,按照天、周、月、季度、年来分割数据呢?
- 首先我们先要获取到这个时间段的相差天数:
开始时间为StartTime,结束时间为EndTime,由于这两个都是属于DateTime类型的变量,所以我们直接用EndTime减去StartTime就可以获得一个TimeSpan对象,直接获取该对象的Day属性,就能获得他们相差的天数了。
- 下面就是重点了,我们这里的目标
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
private List<resultModel> getAllDays(int diffDay, string StartTime, List<DateTime> dateList)
{
var _num_Date_List = new List<resultModel>(diffDay);
var d1 = Convert.ToDateTime(StartTime);
for (int i = 0; i < diffDay; i++)
{
int count = 0;
for (int j = 0; j < dateList.Count; j++)
{
if (d1.Date == dateList[j].Date) count++;
}
// 仅保留年月日,不储存详细时间信息
string _time = string.Format("{0}年{1}月{2}日", d1.Year, d1.Month, d1.Day);
_num_Date_List.Add(new resultModel { Time = _time, Count = count });
d1 = d1.AddDays(1);
}
return _num_Date_List;
}
|
好了,我们来解析一下上面代码的意思,首先我们用一个List来存储即将要返回的结果列表,这里的resultModel其实很简单,里面只有两个属性,一个Time用于保存具体事件,一个Count用于保存该时间有几条记录。
下面我们使用了一个DateTime d1来进行日期计数,默认是从这个时间段的开始时间开始进行统计。
主要代码是一个双重循环,外循环遍历这个时间段,内循环则从dateList当中取出记录,将其日期与d1进行比较,如果日期相同则count计数自增1,结束内循环之后将符合d1这个日期的数据进行统计,放入_num_Date_List返回结果当中。
并且d1随着外循环的不断进行,自己也会从第一天遍历到指定时间段的最后一天。
- 周统计:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
private List<resultModel> getWeeks(int diffDay,string StartTime,List<DateTime> dateList)
{
var _days = getAllDays(diffDay, StartTime, dateList);
var _result = new List<resultModel>();
int _week_count = 1,_count = 1,sum = 0,_global = 0;
for(int i=0;i<(diffDay/7)*7;i++,_count++)
{
_global++;
if (_count == 7)
{
sum += _days[i].Count;
_result.Add(new resultModel { Time = string.Format("第{0}周", _week_count), Count = sum });
_week_count++;
// 重置
sum = 0;
_count = 1;
continue;
}
sum += _days[i].Count;
}
int _week_out = diffDay % 7;
if (_result.Count == 0) _global = 0;
int _week_out_sum = 0;
for(int i=0;i<_week_out;i++)
{
_week_out_sum+=_days[_global].Count;
_global++;
}
if(_week_out_sum >0)
{
_result.Add(new resultModel { Time = string.Format("第{0}周", _week_count), Count = _week_out_sum });
}
return _result;
}
|
在这里按周统计要复杂得多,原理很简单,因为一周有7天,如果你选择的这个时间段小于七天则只按一周来进行计算,如果你选的时间是18天,你只需要对其进行除以操作,就能得到有几周,剩下的天数则可以用这个间隔时间对7取模来得到。
- 月统计:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
private List<resultModel> getMonths(int diffDay,string StartTime,List<DateTime> dateList)
{
var _days = getAllDays(diffDay, StartTime, dateList);
var _result = new List<resultModel>();
var _tmp = new Dictionary<string, int>(); // 月份分割结果
for(int i = 0;i<diffDay;i++)
{
var _time = Convert.ToDateTime(_days[i].Time);
var _strTime = string.Format("{0}年{1}月", _time.Year, _time.Month);
// 检测该月份的数据是否存在
if(_tmp.ContainsKey(_strTime))
{
_tmp[_strTime]+=_days[i].Count;
}
else
{
_tmp.Add(_strTime, _days[i].Count);
}
}
foreach(var item in _tmp)
{
_result.Add(new resultModel { Time = item.Key, Count = item.Value });
}
return _result;
}
|
相对而言后面这些统计就十分简单了,在这里我们直接使用的一个字典来存储。结合之前的方法,我们可以很轻松地获得这个时间段所有天数的记录条数有多少。
那么我们直接使用年+月作为键,每当从字典中如果有这个键存在的话,就将其相对应的值进行增加即可。