日历计算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);}@Overridepublic int getYear() {return year;}@Overridepublic void setYear(int year) {this.year = year;}@Overridepublic int getMonth() {return month;}@Overridepublic void setMonth(int month) {this.month = month;}@Overridepublic int getDay() {return day;}@Overridepublic void setDay(int day) {this.day = day;}@Overridepublic 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;}@Overridepublic 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-3for(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;}    }


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部