日历计算java

问题描述

该问题主要解决已知起始时间和延续时长求总天数。
比如:起始日期为2019.9.1,已知期限为三个月,那么终止时间为2019.12.1。根据以上来求这三个月到底有多长时间。

解决思路

这道题的本质在于平年闰年的判断和日期循环规律的掌握和应用。以三个月为例,我们需要注意的关键点有一下几点:
1、这三个月是否是同一年份的三个月;
2、如果不是同一年的三个月需要判断改日期的下一年是平年还是闰年;
3、在月份数加三的时候,会产生超过12的月份数,此时应该如何处理;
4、虽然说是一共三个月,但是实际计算的时候需要考虑四个月每一个月具体有多少天;
根据以上关键点,可以得出以下的思维导图(以三个月为例):
在这里插入图片描述

具体过程

1、在类中定义两个数组分别表示平年表和闰年表

	public int[] a={0,31,29,31,30,31,30,31,31,30,31,30,31};  //闰年月份表  a[i]=x表示i月有x天(其中a[0]和b[0]没有使用)
	public int[] b={0,31,28,31,30,31,30,31,31,30,31,30,31};  //平年月份表

(其实这里a[i]表示第i+1月会在后面省去很多不必要的麻烦,但是这里我为了逻辑清晰就直接用a[i]表示第i月)
2、后续就是用if_else语句判断年月的类型,然后根据年月类型进行相应计算了。具体条件判断分支可参考我上面那张思维导图。
该类对应的接口如下:

public interface CalendarInterface {

	int getYear();

	void setYear(int year);

	int getMonth();

	void setMonth(int month);

	int getDay();

	void setDay(int day);

	int getMyDays(int category);

	String getEndDate(int category);

具体代码如下:

public class MyCalendar implements CalendarInterface {
	public static int THREE_MONTH=3;
	public static int SIX_MONTH=6;
	public static int ONE_YEAR=12;
	public int[] a={0,31,29,31,30,31,30,31,31,30,31,30,31};  //闰年月份表  a[i]=x表示i月有x天(其中a[0]和b[0]没有使用)
	public int[] b={0,31,28,31,30,31,30,31,31,30,31,30,31};  //平年月份表
	
	private int year;
	private int month;
	private int day;

	
	public MyCalendar() {
		
	}
	
	public MyCalendar(Calendar now) {
		this.year=now.get(Calendar.YEAR);
		this.month=now.get(Calendar.MONTH)+1;
		this.day=now.get(Calendar.DAY_OF_MONTH);
		
	}
	
	
	
	@Override
	public int getYear() {
		return year;
	}

	@Override
	public void setYear(int year) {
		this.year = year;
	}

	@Override
	public int getMonth() {
		return month;
	}

	@Override
	public void setMonth(int month) {
		this.month = month;
	}

	@Override
	public int getDay() {
		return day;
	}

	@Override
	public void setDay(int day) {
		this.day = day;
	}

	@Override
	public int getMyDays(int category) {  //已知下单时间计算出总天数
		int num;
		//System.out.println(year+"-"+month+"-"+day);
		if(category==THREE_MONTH) {
			num=getThDays(year,month,day);//三个月产品
		}else {
			if(category==SIX_MONTH) {
				num=getSiDays(year, month, day);//六个月产品
			}else {
				num=getOnyDays(year, month, day);//一年产品
			}
		}
		return num;
	}
	
	@Override
	public String getEndDate(int category) {
		String endDate="";
		if(category==THREE_MONTH) {
			endDate+=getThDate(year, month, day);
		}else {
			if(category==SIX_MONTH) {
				endDate+=getSiDate(year, month, day);
			}else {
				endDate+=getOnyDate(year, month, day);
			}
		}
		return endDate;
	}
	
	
	private int getThDays(int year,int month,int day) {//形参为起始日期
		int num=0;
		if(year%4==0&&year%100!=0) {  //普通闰年
			if(month<=9) {          //四个月都包含在当前年份;9=12-3
				for(int i=month;i<=month+3;i++) {
					num+=getEveDay(i, month, month+3, a);
//					System.out.println("eve:"+getEveDay(i, month, month+3, a));
				}
			}else {                  //四个月跨越两个年份,那么闰年的第二年一定是平年
				for(int i=month;i<=month+3;i++) {
					if(i<=12) {
						num+=getEveDay(i, month, month+3, a);
//						System.out.println("eve:"+getEveDay(i, month, month+3, a));
					}else {
						num+=getEveDay(i%12, month, (month+3)%12, b);
//						System.out.println("eve:"+getEveDay(i%12, month, (month+3)%12, b));
					}
				}
			}
			
		}else {                       //平年
			if(month<=9) {           //四个月都包含在当前年份
				for(int i=month;i<=month+3;i++) {
					num+=getEveDay(i, month, month+3, b);
//					System.out.println("eve:"+getEveDay(i, month, month+3, b));
				}
			}else {                 //四个月跨越两个年份,那么平年的第二年可能是平年也可能是闰年
				if((year+1)%4==0&&(year+1)%100!=0) {  //第二年为闰年
					for(int i=month;i<=month+3;i++) {
						if(i<=12) {
							num+=getEveDay(i, month, month+3, b);
//							System.out.println("eve:"+getEveDay(i, month, month+3, b));
						}else {
							num+=getEveDay(i%12, month, (month+3)%12, a);
//							System.out.println("eve:"+getEveDay(i%12, month, (month+3)%12, a));
						}
					}
				}else {             //第二年还为平年
					for(int i=month;i<=month+3;i++) {
						if(i<=12) {
							num+=getEveDay(i, month, month+3, b);
//							System.out.println("eve:"+getEveDay(i, month, month+3, b));
						}else {
							num+=getEveDay(i%12, month, (month+3)%12, b);
//							System.out.println("eve:"+getEveDay(i%12, month, (month+3)%12, b));
						}
					}
				}
				
			}
		}
		return num;
	}
	
    private int getSiDays(int year,int month,int day) {//六个月
    	int num=0;
		if(year%4==0&&year%100!=0) {  //普通闰年
			if(month<=6) {          //六个月都包含在当前年份
				for(int i=month;i<=month+6;i++) {
					num+=getEveDay(i, month, month+6, a);
//					System.out.println("eve:"+getEveDay(i, month, (month+6)%12, a));
				}
			}else {                  //六个月跨越两个年份,那么闰年的第二年一定是平年
				for(int i=month;i<=month+6;i++) {
					if(i<=12) {
						num+=getEveDay(i, month, month+6, a);
//						System.out.println("eve:"+getEveDay(i, month, month+6, a));
					}else {
						num+=getEveDay(i%12, month, (month+6)%12, b);
//						System.out.println("eve:"+getEveDay(i%12, month, (month+6)%12, b));
					}
				}
			}
			
		}else {                       //平年
			if(month<=6) {           //六个月都包含在当前年份
				for(int i=month;i<=month+6;i++) {
					num+=getEveDay(i, month, month+6, b);
//					System.out.println("eve:"+getEveDay(i, month, month+6, b));
				}
			}else {                 //六个月跨越两个年份,那么平年的第二年可能是平年也可能是闰年
				if((year+1)%4==0&&(year+1)%100!=0) {  //第二年为闰年
					for(int i=month;i<=month+6;i++) {
						if(i<=12) {
							num+=getEveDay(i, month, month+6, b);
//							System.out.println("eve:"+getEveDay(i, month, month+6, b));
						}else {
							num+=getEveDay(i, month, (month+6)%12, a);
//							System.out.println("eve:"+getEveDay(i, month, (month+6)%12, a));
						}
					}
				}else {             //第二年为平年
					for(int i=month;i<=month+6;i++) {
						if(month<=12) {
							num+=getEveDay(i, month, month+6, b);
//							System.out.println("eve:"+getEveDay(i, month, month+6, b));
						}else {
							num+=getEveDay(i%12, month, (month+6)%12, b);
//							System.out.println("eve:"+getEveDay(i%12, month, (month+6)%12, b));
						}
					}
				}
				
			}
		}
		return num;
	}
    
    private int getOnyDays(int year,int month,int day) {//一年
    	int num=0;
    	if(year%4==0&&year%100!=0) {//起始年份为闰年,第二年一定是平年
    		for(int i=month;i<=month+12;i++) {
    			if(i<=12) {
    				num+=getEveDayplus(i, month, a, 0);
    				System.out.println("eve:"+getEveDayplus(i, month, a, 0));
    			}else {
    				if(i==24) {
    					num+=day;
    					System.out.println("eve:"+day);
    				}else {
    					num+=getEveDayplus(i%12, month, b, 1);
    					System.out.println("eve:"+getEveDayplus(i%12, month, b, 1));
    				}
    			}
    		}
    	}else {            //起始年份为平年,第二年可能为闰年也可能为平年
    		if((year+1)%4==0&&(year+1)%100!=0) {//第二年为闰年
    			for(int i=month;i<=month+12;i++) {
    				if(i<=12) {
    					num+=getEveDayplus(i, month, b, 0);
    					System.out.println("eve:"+getEveDayplus(i, month, b, 0));
    				}else {
    					if(i==24) {
    						num+=day;
    						System.out.println("eve:"+day);
    					}else {
    						num+=getEveDayplus(i%12, month, a, 1);
    						System.out.println("eve:"+getEveDayplus(i%12, month, a, 1));
    					}
    					
    				}
    			}
    		}else {            //第二年还是平年
    			for(int i=month;i<=month+12;i++) {
    				if(i<=12) {
    					num+=getEveDayplus(i, month, b, 0);
    					System.out.println("eve:"+getEveDayplus(i, month, b, 0));
    				}else {
    					if(i==24) {
    						num+=day;
    						System.out.println("eve:"+day);
    					}else {
    						num+=getEveDayplus(i%12, month, b, 1);
    						System.out.println("eve:"+getEveDayplus(i%12, month, b, 1));
    					}
    					
    				}
    				
    			}
    		}
    	}
    	return num;
	}
    
    private int getEveDay(int month,int start,int end,int[] c) {  //非一年的产品
    	if(month==start)
    		return c[month]-day;
    	else {
    		if(month==end)
    			return day;
    		else 
    			return c[month];
    	}
    }
    
    private int getEveDayplus(int month,int start,int[] c,int flag) {
    	if(month==start) {
    		if(flag==0) 
    			return c[month]-day;
    		else 
    			return day;
    	}else {
    		return c[month];
    	}
    }
    
    private String getThDate(int year,int month,int day) {
    	int endyear,endmonth;
    	int endday=day;
    	if(month<=9) {
    		endyear=year;
    		endmonth=month+3;
    	}else {
    		endyear=year+1;
    		endmonth=(month+3)%12;
    	}
    	return endyear+"-"+endmonth+"-"+endday;
    }
    
    private String getSiDate(int year,int month,int day) {
    	int endyear,endmonth;
    	int endday=day;
    	if(month<=6) {
    		endyear=year;
    		endmonth=month+6;
    	}else {
    		endyear=year+1;
    		endmonth=(month+6)%12;
    	}
    	return endyear+"-"+endmonth+"-"+endday;
    }
    
    private String getOnyDate(int year,int month,int day) {
    	int endyear=year+1;
    	int endmonth=month;
    	int endday=day;
    	return endyear+"-"+endmonth+"-"+endday;
    }    

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值