如何将两个日期进行分类计算

        可能做过报表的朋友和我有同样的感受,就是老板可能会说,我要****年**月**日到****年**月**日之间各年度、各季度、各月份的销售情况比较的报表。 
        马上我们想的就是如何来划分这些时间段吧。举个例子,比如日期是从2006年3月15日到2007年3月15日,如何来划分呢?我们知道.NET有System.DateTime类,今天我们讲的就是如何来灵活的使用它,构建我们划分时间段的组件。
        当然我想我需要先讲讲我们的划分原则,如上面的时间段所示,如果我们分年度来比较,那就是从06年3月15日到06年12月31日为一段,07年1月1日到3月15日为另一段;分季度的话当然是06-3-15至06-03-31、06-04-01至06-06-30... ...以此类推,再加上07-01-01至07-03-15一共5段;分月份不用多说,也是06-03-15至06-03-31、06-04-01至06-04-30... ... 07-02-01至07-02-28、07-03-01至07-03-15,一共13段。
         好了,原则讲了,接下来就是看代码的实现了,我们这里假设销售的日期就是订单下达的日期(OrderDate)。
         我们先建一个类DateDiffObject,并让它可序列化:

None.gif [Serializable]
None.gif    
public   class  DateDiffObject
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
public ArrayList SeperateDateByYear = new ArrayList();
InBlock.gif        
public ArrayList SeperateDateByQuarter = new ArrayList();
InBlock.gif        
public ArrayList SeperateDateByMonth = new ArrayList();
InBlock.gif
InBlock.gif        
public DateDiffObject()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

          上面三个ArrayList分别就是记录我把时间段按不同标准划分后的结果。
           然后,我们需要对用户输入进来的时间段进行各类分割了:

None.gif public  DateDiffObject GetDateDiffObject(DateTime BeginDate,DateTime EndDate)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            DateDiffObject dateobj 
= new DateDiffObject();
InBlock.gif                        
//string[] quarter length is 12, record the quarter of each month
ExpandedSubBlockStart.gifContractedSubBlock.gif
            string[] quarter = dot.gif{"1","1","1","2","2","2","3","3","3","4","4","4"};
InBlock.gif
InBlock.gif            
if(BeginDate.Year==EndDate.Year)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//Same Year
InBlock.gif
                if(quarter[BeginDate.Month - 1== quarter[EndDate.Month - 1])
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
//Same Quarter
InBlock.gif
                    if(BeginDate.Month!=EndDate.Month)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
//Different Month
InBlock.gif
                        for(int i=0; i<=EndDate.Month - BeginDate.Month; i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            
if(i==0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                            
dot.gif{
InBlock.gif                                    
//Seperate the first date period
InBlock.gif
                                this.dateobj.SeperateDateByMonth.Add(" and OrderDate between '"+BeginDate.ToString("yyyy-MM-dd")+"' and '"+GetMonthLastDay(BeginDate)+"");
ExpandedSubBlockEnd.gif                            }

InBlock.gif                            
else if(i==EndDate.Month - BeginDate.Month)
ExpandedSubBlockStart.gifContractedSubBlock.gif                            
dot.gif{
InBlock.gif                                    
//Seperate the last date period
InBlock.gif
                                this.dateobj.SeperateDateByMonth.Add(" and OrderDate between '"+GetMonthFirstDay(EndDate)+"' and '"+EndDate.ToString("yyyy-MM-dd")+"");
ExpandedSubBlockEnd.gif                            }

InBlock.gif                            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                            
dot.gif{
InBlock.gif                                    
//Seperate the middle date period
InBlock.gif
                                this.dateobj.SeperateDateByMonth.Add(" and OrderDate between '"+GetMonthFirstDay(BeginDate.AddMonths(i))+"' and '"+GetMonthLastDay(BeginDate.AddMonths(i))+"");
ExpandedSubBlockEnd.gif                            }

ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

InBlock.gif                
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
//Different Quarter
InBlock.gif
                    for(int j=0; j<=Convert.ToInt32(quarter[EndDate.Month - 1]) - Convert.ToInt32(quarter[BeginDate.Month - 1]); j++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                        
if(j==0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                               
//Seperate the first date period
InBlock.gif
                            this.dateobj.SeperateDateByQuarter.Add(" and OrderDate between '"+BeginDate.ToString("yyyy-MM-dd")+"' and '"+GetQuarterLastDay(BeginDate)+"");
ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
else if(j==EndDate.Month - BeginDate.Month)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                                
//Seperate the last date period
InBlock.gif
                            this.dateobj.SeperateDateByQuarter.Add(" and OrderDate between '"+GetQuarterFirstDay(EndDate)+"' and '"+EndDate.ToString("yyyy-MM-dd")+"");
ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                                
//Seperate the middle date period
InBlock.gif
                            this.dateobj.SeperateDateByQuarter.Add(" and OrderDate between '"+GetQuarterFirstDay(BeginDate.AddMonths(3*- ((BeginDate.Month - 1% 3)))+"' and '"+GetQuarterLastDay(BeginDate.AddMonths(3*- ((BeginDate.Month - 1% 3)))+"");
ExpandedSubBlockEnd.gif                        }

ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//Different Year
InBlock.gif
                for(int k=0; k<=EndDate.Year - BeginDate.Year; k++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    
if(k==0)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                            
//Seperate the first date period  --- Year
InBlock.gif
                        this.dateobj.SeperateDateByYear.Add(" and OrderDate between '"+BeginDate.ToString("yyyy-MM-dd")+"' and '"+GetYearLastDay(BeginDate)+"");
InBlock.gif                        DateDiffObject newdateobj 
= new DateDiffObject();
InBlock.gif                        
//Use itself --- Recursion Method
InBlock.gif
                        newdateobj = GetDateDiffObject(DateType,BeginDate,DateTime.Parse(GetYearLastDay(BeginDate)));
InBlock.gif                        
for(int p=0; p<newdateobj.SeperateDateByQuarter.Count;p++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            dateobj.SeperateDateByQuarter.Add(newdateobj.SeperateDateByQuarter[p]);
ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
for(int p=0; p<newdateobj.SeperateDateByMonth.Count;p++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            dateobj.SeperateDateByMonth.Add(newdateobj.SeperateDateByMonth[p]);
ExpandedSubBlockEnd.gif                        }
                
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
else if(k==EndDate.Year - BeginDate.Year)
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                            
//Seperate the last date period  --- Year
InBlock.gif
                        this.dateobj.SeperateDateByYear.Add(" and OrderDate between '"+GetYearFirstDay(EndDate)+"' and '"+EndDate.ToString("yyyy-MM-dd")+"");
InBlock.gif                        DateDiffObject newdateobj 
= new DateDiffObject();
InBlock.gif                        
//Use itself --- Recursion Method
InBlock.gif
                        newdateobj = GetDateDiffObject(DateType,DateTime.Parse(GetYearFirstDay(EndDate)),EndDate);
InBlock.gif                        
for(int p=0; p<newdateobj.SeperateDateByQuarter.Count;p++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            dateobj.SeperateDateByQuarter.Add(newdateobj.SeperateDateByQuarter[p]);
ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
for(int p=0; p<newdateobj.SeperateDateByMonth.Count;p++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            dateobj.SeperateDateByMonth.Add(newdateobj.SeperateDateByMonth[p]);
ExpandedSubBlockEnd.gif                        }
        
ExpandedSubBlockEnd.gif                    }

InBlock.gif                    
else
ExpandedSubBlockStart.gifContractedSubBlock.gif                    
dot.gif{
InBlock.gif                            
//Seperate the middle date period  --- Year
InBlock.gif
                        this.dateobj.SeperateDateByYear.Add(" and OrderDate between '"+GetYearFirstDay(BeginDate.AddYears(k))+"' and '"+GetYearLastDay(BeginDate.AddYears(k))+"");
InBlock.gif                        DateDiffObject newdateobj 
= new DateDiffObject();
InBlock.gif                        
//Use itself --- Recursion Method
InBlock.gif
                        newdateobj = GetDateDiffObject(DateType,DateTime.Parse(GetYearFirstDay(BeginDate.AddYears(k))),DateTime.Parse(GetYearLastDay(BeginDate.AddYears(k))));
InBlock.gif                        
for(int p=0; p<newdateobj.SeperateDateByQuarter.Count;p++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            dateobj.SeperateDateByQuarter.Add(newdateobj.SeperateDateByQuarter[p]);
ExpandedSubBlockEnd.gif                        }

InBlock.gif                        
for(int p=0; p<newdateobj.SeperateDateByMonth.Count;p++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                        
dot.gif{
InBlock.gif                            dateobj.SeperateDateByMonth.Add(newdateobj.SeperateDateByMonth[p]);
ExpandedSubBlockEnd.gif                        }
        
ExpandedSubBlockEnd.gif                    }

ExpandedSubBlockEnd.gif                }

ExpandedSubBlockEnd.gif            }

InBlock.gif            
return dateobj;
ExpandedBlockEnd.gif        }

          以上方法是用递归算法来截取个时间段然后返回一个DateDiffObject的对象。 其实大家可以看出来填入对象中各个ArrayList的数据就是SQL语句的一段,作为我们查询数据库的条件。
          接下来就是我们在上面看到的例如GetMonthFirstDay(EndDate),GetMonthLastDay(BeginDate.AddMonths(i))等方法的实现,大家可以从方法名里看出它们将要实现的功能,就是获得每年、每季度、每月的第一天和最后一天:

None.gif public   string  GetMonthFirstDay(DateTime date)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
return date.ToString("yyyy-MM-01");
ExpandedBlockEnd.gif        }

None.gif
None.gif        
public   string  GetMonthLastDay(DateTime date)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
return DateTime.Parse(date.ToString("yyyy-MM-01")).AddMonths(1).AddDays(-1).ToShortDateString();
ExpandedBlockEnd.gif        }

None.gif
None.gif        
public   string  GetQuarterFirstDay(DateTime date)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
return date.AddMonths(0 - ((date.Month - 1% 3)).ToString("yyyy-MM-01");
ExpandedBlockEnd.gif        }

None.gif
None.gif        
public   string  GetQuarterLastDay(DateTime date)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
return DateTime.Parse(date.AddMonths(3 - ((date.Month - 1% 3)).ToString("yyyy-MM-01")).AddDays(-1).ToShortDateString();
ExpandedBlockEnd.gif        }

None.gif
None.gif        
public   string  GetYearFirstDay(DateTime date)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
return DateTime.Parse(date.ToString("yyyy-01-01")).ToShortDateString();
ExpandedBlockEnd.gif        }

None.gif
None.gif        
public   string  GetYearLastDay(DateTime date)
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
return DateTime.Parse(date.ToString("yyyy-01-01")).AddYears(1).AddDays(-1).ToShortDateString();
ExpandedBlockEnd.gif        }

       都是用DateTime类来实现的,原理很简单,每个月的第一天当然是****-**-01,最后一天就是下个月的第一天减去一天所得到的,季度和年份也是同理,大家有兴趣可以推敲一下,这里就不再赘述了。^^
       最后,就是调用它的时候了,我们先讲它序列化为一个XML文档,存放在一个特定目录下,我们这里用一个组件来管理它:
None.gif public   class  DateDiffObjectSerialize : iDateObjectSerialize
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
private string strPath = "./XMLDoc/"+HttpContext.Current.Request.Cookies["UserID"].Value + "/DateDiffObject.xml";
InBlock.gif        
private DateDiffObject dateobj = new DateDiffObject();
InBlock.gif
InBlock.gif        
public DateDiffObjectSerialize()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public DateDiffObjectSerialize(string Path)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.strPath = Path;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void SerializeDateObject(DateDiffObject dateobj)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            FileInfo fi 
= new FileInfo(strPath);
InBlock.gif            
if(fi.Exists)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                fi.Delete();
ExpandedSubBlockEnd.gif            }

InBlock.gif            XmlSerializer s 
= new XmlSerializer(typeof(DateDiffObject));
InBlock.gif            Stream stream 
= new FileStream(HttpContext.Current.Server.MapPath(strPath),FileMode.Create);
InBlock.gif            s.Serialize(stream, dateobj);
InBlock.gif            stream.Close();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public void SerializeDateObject(DateDiffObject dateobj,string FilePath)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            strPath 
= FilePath;
InBlock.gif
InBlock.gif            FileInfo fi 
= new FileInfo(strPath);
InBlock.gif            
if(fi.Exists)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                fi.Delete();
ExpandedSubBlockEnd.gif            }

InBlock.gif            XmlSerializer s 
= new XmlSerializer(typeof(DateDiffObject));
InBlock.gif            Stream stream 
= new FileStream(HttpContext.Current.Server.MapPath(strPath),FileMode.Create);
InBlock.gif            s.Serialize(stream, dateobj);
InBlock.gif            stream.Close();
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public DateDiffObject DeserializeDateObject()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            FileStream s 
= File.OpenRead(HttpContext.Current.Server.MapPath(strPath));
InBlock.gif            XmlSerializer xs 
= new XmlSerializer(typeof(DateDiffObject));
InBlock.gif            dateobj 
= (DateDiffObject)xs.Deserialize(s);
InBlock.gif            s.Close();
InBlock.gif            
return dateobj;
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public DateDiffObject DeserializeDateObject(string FilePath)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            strPath 
= FilePath;
InBlock.gif            FileStream s 
= File.OpenRead(HttpContext.Current.Server.MapPath(strPath));
InBlock.gif            XmlSerializer xs 
= new XmlSerializer(typeof(DateDiffObject));
InBlock.gif            dateobj 
= (DateDiffObject)xs.Deserialize(s);
InBlock.gif            s.Close();
InBlock.gif            
return dateobj;
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

       要调用DateDiffObject时只是需要将它反序列化出来,按需提取里面的数据,然后组装到你查询语句中就行了。
       结束语:
      至于为什么要把它进行序列化,主要是我对方便使用的考量在里面,我就碰到这样的要求,不但要看报表,还要看相应的图片显示,年度、季度、月份的比较可以随时切换,当然你也可以不讲他序列化了,这个就见仁见智吧。

转载于:https://www.cnblogs.com/Louistin/archive/2007/03/17/677568.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值