在一个日期列表当中根据天、周、月、季度、年返回相应的统计数据

换了一家公司,当天便接到一个统计模块的开发,要求是从数据库当中提取到指定时间段的数据,并按照前端给的分割单位时间进行数据返回,统计什么呢?就是统计这些记录在某一天有几条,某一周有几条,以此类推。

例如:
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容器内。

不过后面才是正题,数据是抓取到了,不过我们又该怎样从这一堆数据当中,按照天、周、月、季度、年来分割数据呢?

  1. 首先我们先要获取到这个时间段的相差天数:
    开始时间为StartTime,结束时间为EndTime,由于这两个都是属于DateTime类型的变量,所以我们直接用EndTime减去StartTime就可以获得一个TimeSpan对象,直接获取该对象的Day属性,就能获得他们相差的天数了。
  2. 下面就是重点了,我们这里的目标
        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. 周统计:
        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. 月统计:
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;
        }

相对而言后面这些统计就十分简单了,在这里我们直接使用的一个字典来存储。结合之前的方法,我们可以很轻松地获得这个时间段所有天数的记录条数有多少。

那么我们直接使用年+月作为键,每当从字典中如果有这个键存在的话,就将其相对应的值进行增加即可。