【大一暑期专辑二】计算两个给定日期值相距的天数

这一学期,我认识了一位新朋友——Java。由于种种原因,我没能在上课期间和这位朋友建立起深厚的友谊,所以呢,我就想在暑期好好地熟悉熟悉我的这位朋友。

这不,我在练习课本中的这道题目时,得到了某种意想不到的收获,所以,我就想将它分享给各位。

题目:如果有两个日期值,计算它们相距的天数。

读完题后,我的第一感受:简单嘛,不就计算一个相差的天数吗。第二感受:哇,挺复杂呀。这不是某月某日的问题,而是某年某月某日的问题,然后你还得考虑平闰年,大小月,以及会随平闰年变化的二月。我一下子就不想做了。我的性情很急躁,一碰上点儿麻烦事就想打退堂鼓,于是我合上课本出去溜达了。

不过,我明白如果我想有所提高,就必须去做这些对我来说有困难的事。我自许不是一个勇敢的人,但我还是鼓足了很大的勇气,重新翻开书本,打开eclipse和草稿本,我开始思考了。事实是,我并没有像传说中的励志人物一样,一旦开始振作,就一举成功。我经历了很多轮的烦躁,找了很多次的bug。今天总算是能正确地运行我的代码,这就是我的创造啊,我是多么兴奋啊,所以,我也迫不及待的想要分享给大家!

我不知道看到这篇博文的你此刻是什么心情,也许你觉得这简直简单得不值一提,也许你对这个题目同样感兴趣,不管怎样,我还是想和你分享一下我的故事,谢谢。

首先,你得有一个思路。

我的思路是这样的,先比较两个日期的年份,再依次比较两个日期的月份和日子。最简单的一种情况你或许已经想到——当两个日期的年份和月份都相同时,相距的天数就等于两个日子之差的绝对值。而如果年份相同而月份不同的话,我还要再细分,当小月份的日期小于大月份的日期时怎么计算天数,当小月份的日期大于大月份的日期时又该怎么计算。再讨论年份不同的情况,而把不同年份的复杂问题化为相同年份的简单问题也是檬檬代码中所要推荐的。

具体的实现过程呢,我用到函数来解决平闰年和大小月问题

完整代码如下:(为了方便分析,我就直接在文本上粘贴了,请见谅)

package sweet;
class dateOne                                   //这个类用来表示第一个给定的日期
{        
    public int year = 2017;
    public int month =2;
    public int day = 5;
}

class dateTwo                                 //这个类用来表示第二个给定的日期
{
    public int year =2017;
    public int month = 7;
    public int day =7;
}                                                      
public class detached
{
    public static void main(String[] args)
    {
        int interval = 0;                          //interval用来记录两个给定日期相距的天数,也就是题目中要求的最终数值
        dateOne d1 = new dateOne();
        dateTwo d2 = new dateTwo();     //分别定义一个日期类对象
        
        if(d1.year==d2.year)

                    interval = sameYear(d1,d2);                      
        else  interval = differentYear(d1,d2);         //比较两个日期的年份,决定调用哪一个函数来获取我们要找的天数
        System.out.println("日期一---"+d1.year+" "+d1.month+" "+d1.day+" "
                            + "和日期二--"+d2.year+" "+d2.month+" "+d2.day+" 相距的天数为:"+interval)
    }


    public static int  sameYear(dateOne d1,dateTwo d2)
   {

                 int interval = 0;             //局部变量interval,用于获取在两个日期年份相同时的相距天数
                int flag = commonOrLeap(d1.year);       //用一个函数来判断所给年份是平年还是闰年。若是闰年,flag = 0,若是平年,flag = 1(平闰年的这种区分方式,是为了方便后面计算天数)


                if(d1.month==d2.month)                //情况一、两个日期的月份相同
                {
                    interval =Math.abs(d1.day-d2.day) ;
                    
                }


                if(d1.month<d2.month)            //情况二、第一个日期的月份小于第二个日期的月份
                {
                    
                    
                    if(d1.day<=d2.day)              //按照日子的大小关系还要对月份进行细分
                    {
                        interval = (d2.month-d1.month)*30 +  dis(d1.month,d2.month,flag) + (d2.day-d1.day);
                                                            //例如2018.2.5和2018.7.7     
                    }
                    if(d1.day>d2.day)
                    {
                  interval = (d2.month-d1.month-1)*30+distance(d1.month,d2.month,flag)+(30-d1.day+d2.day)+bigOrSmall(d2.month-1,d2.year);                                           //例如2018.2.5和2018.7.3
                        
                    }
                }      
                
                if(d1.month>d2.month)                         //情况三、第一个日期月份大于第二个日期月份。例如2018.7.2和2018.2.5,如果再去思索新的方法,也不必要。这时我们可以交换两个日期中的值,把情况恢复成上面那种
                {
                    
                    int temp_month = 0;
                    int temp_day = 0;


                    temp_month = d1.month;
                    d1.month = d2.month;
                    d2.month = temp_month;
                    
                    temp_day = d1.day;
                    d1.day = d2.day;
                    d2.day = temp_day;


                    if(d1.day<=d2.day)
                    {
                        interval = (d2.month-d1.month)*30+(d2.day-d1.day)+    dis(d1.month,d2.month,flag);
                        
                    }
                    if(d1.day>d2.day)
                    {
                        interval = (d2.month-d1.month-1)*30+distance(d1.month,d2.month,flag)+(30-d1.day+d2.day)+bigOrSmall(d2.month-1,d2.year);
                        
                    }
                }
            
        return interval;
    }
    
    public static int differentYear(dateOne d1,dateTwo d2)       //当两个年份不同时,调用此函数
    {
        int interval = 0;
        if(d1.year<d2.year)                               //第一个年份小于第二个年份
        {
            
            if(d1.month<=d2.month)
            {
                interval += (d2.year-d1.year)*365+distanceYear(d1.year,d2.year);           //把第一个日期的年份化为第二个日期的年份所间隔的天数。例如2015.2.5和2017.7.7,把第一个日期先化为2017.2.5,然后就可转化为同年的情况,而月份的大小关系决定着是应该加还是减化成同年后相隔的天数。
                d1.year = d2.year;
                interval += sameYear(d1,d2);
                
            }
            if(d1.month>d2.month)
            {
                
                interval+= (d2.year-d1.year)*365 + distanceYear(d1.year,d2.year);
                d1.year = d2.year;
                if(d1.month<d2.month)
                interval += sameYear(d1,d2);
                else interval -= sameYear(d1,d2);
            }
        }
        
        if(d1.year>d2.year)                        //第一个年份大于第二个年份(类似月份,进行交换后,化成第一个年份小于第二个年份的情况)
        {
            
            int temp_year1 = 0;
            int temp_month1 = 0;
            int temp_day1 = 0;
            
            temp_year1 = d1.year;
            d1.year = d2.year;
            d2.year = temp_year1;
            
            temp_month1 = d1.month;
            d1.month = d2.month;
            d2.month = temp_month1;
            
            temp_day1 = d1.day;
            d1.day = d2.day;
            d2.day = temp_day1;
            if(d1.month<=d2.month)
            {
                interval += (d2.year-d1.year)*365+distanceYear(d1.year,d2.year);
                d1.year = d2.year;
                interval += sameYear(d1,d2);
                
            }
            if(d1.month>d2.month)
            {
                
                interval+= (d2.year-d1.year)*365 + distanceYear(d1.year,d2.year);
                d1.year = d2.year;
                if(d1.month<d2.month)
                interval += sameYear(d1,d2);
                else interval -= sameYear(d1,d2);
            }
        }
        return interval;
    }
    public static int commonOrLeap(int year)  //判断某一年是平年还是闰年
    {
        int temp = 0;
        if(year%4 == 0)temp = 1;
        if(year%4 != 0)temp = 0;
        return temp;
    }
    
    public static int bigOrSmall(int month,int flag)  //判断某年的某月是大月、小月还是平月
    {
        int temp = 0;
        switch(month)
        {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:  temp =  1;break;
        case 4:
        case 6:
        case 9:
        case 11: temp = 0;break;
        case 2:
            {if(flag==1) {temp =  -1;break;}
            if(flag==0) {temp =  -2;break;}}
        
        }
        
        return temp;
    
        
        
    }
    public static int distance(int a,int b,int flag)  //判断并对第a月到第b-1月的每一个月份的大、小、平情况,并把它们相加和(用于当1天数大于2天数时求月份间产生的差值)
    {
        int k = 0;
        for(int i = a;i<b-1;i++)
        {
            
            k+=bigOrSmall(i,flag);
        }
        return k;
    }


    public static int dis(int a,int b,int flag)  //判断并对第a月到第b月的每一个月份的大、小、平情况,并把它们相加和(用于当1天数小于2天数时求月份间产生的差值)
    {
        int k = 0;
        for(int i = a;i<b;i++)
        {
            
            k+=bigOrSmall(i,flag);
        }
        return k;
    }
    
    
    
    public static int distanceYear(int c,int d)                 //判断从第c年到第d年中的年份是平年还是闰年,并求和(1月份<2月份)
    {
        int t = 0;
        for(int j = c;j<d;j++)
        {
            t += commonOrLeap(j);
        }
        return t;
    }
    }
    思想精华:把所有的年都当做平年365天计算,再设置一个函数根据平闰年确定相差的天数;

                     把所有的月都当做30天来计算,再设置函数根据具体情况确定相差的天数。
    (声明:本博文是博主有感之作,纰漏颇多,请多指教)

猜你喜欢

转载自blog.csdn.net/zh_momotaotao/article/details/81359665