这两天的收获

来源:互联网 发布:中轴线北京徒步知乎 编辑:程序博客网 时间:2024/04/30 08:21

这两天没有做用wicket完成某地方的地理信息数据的时序分析与拓扑分析,而是帮一个同学编了几个关于数据表处理的程序,还是蛮有收获的。

下面是问题描述:

1、有4个站点的降雨量,50年左右每天的数据都有,保存在excel里面,日期是按yymmdd的方式给出的(如:540323表示54年3月23日),另外就是降雨量值prcp(mm),要求求出每年每一个月的平均雨量、和每一个季度的雨量汇总,冬季为12-2月,春季为3-5月、夏季为6-8月,秋季为9-11月。

2、同样是该4个站点,另外根据某模型,得出了模拟100年左右的降雨量,分三种模拟方式进行,分别是F、L、Y格式模拟数据,而这三种格式模拟的降雨量也存在excel中,分为4列:用“year”,“mo”,“da”,“prcp”分别表示年、月、日、降雨量。要求对这三种格式的数据进行季度雨量汇总。

一开始,我觉得挺简单的,但是做起来还是费了不少功夫呀?对于第一种日期,想办法进行拆分,这是我最先、也是最直接的想法。当然对于这种yymmdd格式的日期拆分,应该有多种方法,而且也比较简单,我想的也是最普通的办法:把它们当作整形从数据库取出来采用ResultSet.getInt("index")的办法,然后再当作10级的整数进行除10的n次方取整的办法,把它们分别剥出来(貌似这是计算机二、三级最常见的考题呀^_^):

 static int years = 0;
 static int months = 0;
 static int days = 0;

public static void getdate(int date)
{

  int[] year = new int[2];
  int[] month = new int[2];
 
  year[0] = date/100000;   //年份最高位
  year[1] = (date-year[0]*100000)/10000; //年份最低位
  month[0] = (date-year[0]*100000-year[1]*10000)/1000;  //月份最高位
  month[1] = (date-year[0]*100000-year[1]*10000-month[0]*1000)/100; //月份最低位

  days = date-year[0]*100000-year[1]*10000-month[0]*1000-month[1]*100;
  years = year[0]*10 + year[1];
  months = month[0]*10 + month[1];

 }

每一个月结束,是按照switch(getmonth)——case month:的方式进行判断的,季度也一样,只是把12-2、3-5、6-8、9-11再融合在一起,于是就成了switch(getseason)——case season:的方式进行判断。这些都没有问题。

最大的问题来自2月的结束判断,其它月是确定的,我只要获取得月份第一个表处理后的“months”和第二个表中的“mo”,就知道这个月有多少天,就好在case里面设置汇数据累加汇总退出条件。但是对于2月判断,真是伤透了脑筋,我知道很多人都会抬出经典的判断闰年的程序来说,但是在这里情况有点不一样,因为每天、每个月、每年的数据都是实实在存在的,年份在第二张表中,是抽象年份,只知道从1-100年,并不是实际的历法年份。这样看来,年份是混乱的,但是月份和天数没有混乱,反正都是一天一天,一月一月来排的,2月有28天的,也有29天的。。。

因此我想的是通过直接判断2月的数来作为结束2月的条件,不要用年份,但是怎么直接判断呢?

 

我一开始还蛮高兴的写了这句话当作判断(还有点洋洋得意):

if(rs.isLast || (days == 29 || days == 28) && (month == 2))

.......................................................................................

//如果那个月天days == 29,肯定不用判断days == 28那个条件了,再且月为2,肯定2月结束了,汇总输出。但是万万没有想到如果那个月是有29天,但是当days == 28的时候呢,条件也成立了,这里如果也汇总输出,那么闰年的28号与29号都会输出汇总结果。。。这就导致了后面汇总插入数据库的时候就出现了两个winter的现象。。。

后面,实在没有相去别的办法,就采用了两种遍历的方式,第一个遍历是找出其中的闰年,也不用闰年算法,只看2月就没有29,如果两个条件满足,那这个年份肯定是闰年,至少像闰年一样对待。。。然后将这个年份插入数据库,以便第二个遍历中判断闰年;第二个遍历是完全遍历,当春季末在:从数据库中查出是闰年 && getdays == 29 && getmonths == 2,显然,这定是闰年的冬季结束那天,汇总返回。

否则当从数据库中查出不是闰年 && getdays == 28 && getmonths == 2,那么也显然这必定是非闰年的冬季最后一天,汇总返回:

      if((rest.isLast())||((!thisyearIsLeap)&&(dd == 28)&&(mm == 2)))
      {
       System.out.println("本年是普通年,当表结束或者这天巧好是2月28号,说明这一年冬季完鸟^_^");
       System.out.println(yy+"年冬季的总降雨量为:"+sumrainfall);
       sqlinsert(yy, seas, sumrainfall);
       sumrainfall = 0.0;
      }
      else if((rest.isLast())||(thisyearIsLeap&&(dd == 29)&&(mm == 2)))

      {
       System.out.println("本年是闰年,当表结束或者这天恰好是2月29号,说明这一年冬季完鸟^_^");
       System.out.println(yy+"年冬季的总降雨量为:"+sumrainfall);
       sqlinsert(yy, seas, sumrainfall);
       sumrainfall = 0.0;
      }

基于这种思想基本搞对了程序,不过4个站点,每份excel的数据量大概有3万多条记录,我又难得新建数据表,所以,所以就不停的导入、运行、导出如果反复,而且最后面的和年还是有个Bug,就是如果最后一年有12月,还是会出现两个Winter的数据插入数据库,但是其它年份绝对没有,只有4个季节,我查看了一下,就在上段代码中,应该判断结束有两个条件,一个是表是否是最后了,一个是2月底,想了想,正是因为这两个条件之一就可结束,而进行冬季汇总,所以,最后一年在2月底会汇总一次,在表最后还会汇总一次,所以...,所以2个Winter跑出来了!!

 

现在不想弄这个Bug了,以后有空再想想吧!!

 

原创粉丝点击