**
7-5 日期问题面向对象设计(聚合二) (40 分)
**
参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:
解题报告
写完程序后,想要测试三个功能点的正确性,可以参考Java8中的LocalDateTime类中的相关方法(在提交代码中不允许使用): 例如:
LocalDateTime today = LocalDateTime.now();//定义对象
//LocalDateTime today= LocalDateTime.of(2000,2,12);//定义对象 System.out.println(today.plusDays(10));//当前日期后十天
System.out.println(today.plusDays(-10));//当前日期前十天
注意,在使用Period求两个日期之间相差天数时,Period只能求同月日期的相差天数,因此要采用如下方法:
System.out.println(LocalDate.now().toEpochDay() -
LocalDate.now().minusDays(5).toEpochDay());
具体使用方法可参考Jdk1.8 API文档
应用程序共测试三个功能:
求下n天
求前n天
求两个日期相差的天数
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)
输入格式:
有三种输入方式(以输入的第一个数字划分[1,3]):
1 year month day n //测试输入日期的下n天
2 year month day n //测试输入日期的前n天
3 year1 month1 day1 year2 month2 day2 //测试两个日期之间相差的天数
输出格式:
当输入有误时,输出格式如下: Wrong Format
当第一个数字为1且输入均有效,输出格式如下:
year1-month1-day1 next n days is:year2-month2-day2
当第一个数字为2且输入均有效,输出格式如下:
year1-month1-day1 previous n days is:year2-month2-day2
当第一个数字为3且输入均有效,输出格式如下:
The days between year1-month1-day1 and year2-month2-day2 are:值
输入样例1:
3 2014 2 14 2020 6 14
输出样例1:
The days between 2014-2-14 and 2020-6-14 are:2312
输入样例2:
2 1834 2 17 7821
输出样例2:
1834-2-17 previous 7821 days is:1812-9-19
输入样例3:
1 1999 3 28 6543
输出样例3:
1999-3-28 next 6543 days is:2017-2-24
输入样例4:
0 2000 5 12 30
输出样例4:
Wrong Format
import java.util.Scanner;
//Year类
class Year{
int value;
//默认构造方法
public Year(){
}
//带参构造方法
public Year(int value){
this.value=value;
}
//getter
public int getValue(){
return value;
}
//setter
public void setValue(int value){
this.value=value;
}
//判断year是否为闰年
public boolean isLeapYear(){
if((value%4==0&&value%100!=0)||value%400==0)
return true;
else
return false;
}
//效验数据合法性
public boolean validate(){
if(value<=2020&&value>=1820)
return true;
else
return false;
}
//年份加一
public void yearIncrement(){
value=value+1;
}
//年份减一
public void yearReduction(){
value=value-1;
}
}
//Month类
class Month{
int value;
//默认构造方法
public Month(){
}
//带参构造方法
public Month(int value){
this.value=value;
}
//getter
public int getValue(){
return value;
}
//setter
public void setValue(int value){
this.value=value;
}
//日期复位(1)
public void resetMin(){
value=1;
}
//月份设置为12
public void resetMax(){
value=12;
}
//效验数据合法性
public boolean validate(){
if(value>=1&&value<=12)
return true;
else
return false;
}
//月份加一
public void dayIncrement(){
value=value+1;
}
//月份减一
public void dayReduction(){
value=value-1;
}
}
//Day类
class Day{
int value;
//默认构造方法
public Day(){
}
//带参构造方法
public Day(int value){
this.value=value;
}
//getter
public int getValue(){
return value;
}
//setter
public void setValue(int value){
this.value=value;
}
//日期加一
public void dayIncrement() {
value=value+1;
}
//日期减一
public void dayReduction() {
value=value-1;
}
}
//DateUtil类
class DateUtil{
Year year;
Month month;
Day day;
int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
//默认构造方法
public DateUtil(){
}
//带参构造方法
public DateUtil(int y,int m,int d){
this.year = new Year(y);
this.month = new Month(m);
this.day = new Day(d);
}
//getter
public Year getYear(){
return year;
}
public Month getMonth(){
return month;
}
public Day getDay(){
return day;
}
//setter
public void setYear(Year year){
this.year = year;
}
public void setMonth(Month month){
this.month = month;
}
public void setDay(Day d){
this.day=d;
}
//设置日期最小值
public void setDayMin() {
this.day.value=1;
}
//设置日期最大值
public void setDatMax() {
if(this.year.isLeapYear())
a[2]=29;
this.day.value=a[this.month.value];
}
//效验数据合法性
public boolean checkInputValidity(){
if(this.year.isLeapYear())
a[2]=29;
if(this.year.validate()&&this.month.validate()&&this.day.value>=1&&this.day.value<=a[this.month.value])
return true;
else
return false;
}
//比较两个日期大小
public boolean compareDates(DateUtil date){
if(date.year.value<this.year.value)
return false;
else if(date.year.value==this.year.value&&date.month.value<this.month.value)
return false;
else if(date.year.value==this.year.value&&date.month.value==this.month.value&&date.day.value<this.day.value)
return false;
else
return true;
}
//判定两个日期是否相等
public boolean equalTwoDates(DateUtil date){
if(this.getDay().getValue()==date.getDay().getValue()&&this.getMonth().getValue()==date.getMonth().getValue()&&this.getYear().getValue()==date.getYear().getValue())
return true;
else
return false;
}
//日期值格式化
public String showDate(){
return this.getYear().getValue()+"-"+this.getMonth().getValue()+"-"+this.getDay().getValue();
}
//计算该年的剩余天数
public int syts(DateUtil d){
int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int b=0,i;
for(i=d.getMonth().getValue()+1;i<=12;i++){
b=b+a[i];
}
b=b+a[d.getMonth().getValue()]-d.getDay().getValue();
if(d.getYear().isLeapYear()&&d.getMonth().getValue()<=2)//闰年
b++;
return b;
}
//求下n天
public DateUtil getNextNDays(int n){
int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int y=0,m=0,d=0;
int i,j;
int b=syts(this);//该年剩余天数
if(b>n){//该年剩余天数大于n
y=this.getYear().getValue();
if(this.getYear().isLeapYear()){//如果是闰年
a[2]=29;
}
int e=a[this.getMonth().getValue()];//该月的天数
e=e-this.getDay().getValue();//本月剩余的天数
if(e>=n){//如果n天后在本月
m=this.getMonth().getValue();
d=n+this.getDay().getValue();
}
else{//如果n天后不在本月
n=n-e;
m=this.getMonth().getValue()+1;
i=m;
while(n-a[i]>0){//找到月
n=n-a[i];
m++;
i++;
}
d=n;//找到天
}
}
else{//该年剩余天数小于n
n=n-b;
y=this.getYear().getValue()+1;
int c=365;//平年天数
if(new Year(y).isLeapYear()){//闰年天数
c++;
}
while(n-c>0){//找到年
n=n-c;
y++;
c=365;
if(new Year(y).isLeapYear())
c++;
}
i=1;
while(n-a[i]>0&&i<=12){//找到月
n=n-a[i];
i++;
}
m=i;
d=n;//找到天
}
return new DateUtil(y,m,d);
}
//求前n天
public DateUtil getPreviousNDays(int n){
int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int y=0,m=0,d=0;
int i,b;
b=365-syts(this);//该日期所在年份已经过的天数
if(this.getYear().isLeapYear()){//如果是闰年
b++;
}
if (b>n){//如果前n天在该年
y=this.getYear().getValue();
int e=this.getDay().getValue();//本月已经过的天数
if(e>n){//如果前n天在本月
m=this.getMonth().getValue();
d=e-n;
}
else{//如果前n天不在本月
n=n-e;
m=this.getMonth().getValue()-1;
i=m;
while(n-a[i]>0){//找到月
n=n-a[i];
m--;
i--;
}
d=a[i]-n;//找到天
if(new Year(y).isLeapYear()&&m==2){
d++;
}
}
}
else{//如果前n天不在该年
n=n-b;
y=this.getYear().getValue()-1;
int f=365;
if(new Year(y).isLeapYear()){
f++;
}
while(n-f>0){//找到年
n=n-f;
y--;
f=365;
if(new Year(y).isLeapYear())
f++;
}
i=12;
while(n-a[i]>0&&i>=0){//找到月
n=n-a[i];
i--;
}
m=i;
d=a[i]-n;//找到天
if(new Year(f).isLeapYear()&&m==2){
d++;
}
}
return new DateUtil(y, m, d);
}
//求两个日期之间的天数
public int getDaysofDates(DateUtil date){
DateUtil b1=this;
DateUtil b2=date;
if(this.equalTwoDates(date)){//如果两天的日期相等
return 0;
}
else if(!this.compareDates(date)){//如果日期大小不对
b1=date;
b2=this;
}
int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int i,j,ts=0;
for(i=b1.getYear().getValue()+1;i<b2.getYear().getValue();i++){//两个日期的年数之和
ts=ts+365;
if(new Year(i).isLeapYear())
ts++;
}
if(b1.getYear().getValue()==b2.getYear().getValue()&&b1.getMonth().getValue()==b2.getMonth().getValue()){//年份相同,月份相同,日不同
ts=b2.getDay().getValue()-b1.getDay().getValue();
}
else if(b1.getYear().getValue()==b2.getYear().getValue()&&b1.getMonth().getValue()!=b2.getMonth().getValue()){//年份相同,月份不同
if(b1.getYear().isLeapYear())//是闰年
a[2]=29;
ts=ts+a[b1.getMonth().getValue()]-b1.getDay().getValue();//小日期该月剩余的天数
ts=ts+b2.getDay().getValue();//大日期的天数
for(j=b1.getMonth().getValue()+1;j<=b2.getMonth().getValue()-1;j++)//月份天数和
ts+=a[j];
}
else if(b1.getYear().getValue()!=b2.getYear().getValue()){//年份不同
ts=ts+a[b1.getMonth().getValue()]-b1.getDay().getValue();//小日期在该月剩余的天数
ts=ts+b2.getDay().getValue();//大日期在该月已经过的天数
for(j=b1.getMonth().getValue()+1;j<=12;j++)//小日期在该年剩余的天数
ts=ts+a[j];
for(j=b2.getMonth().getValue()-1;j>0;j--)//大日期在该年已经过的天数
ts=ts+a[j];
if(b1.getYear().isLeapYear()&&b1.getMonth().getValue()<=2)//如果小日期该年为闰年且该天在1月或2月
ts++;
if(b2.getYear().isLeapYear()&&b2.getMonth().getValue()>2)//如果大日期该年为闰年且该天在1月或2月后
ts++;
}
return ts;
}
}
//主类
public class Main {
public static void main(String[] args) {
Scanner x=new Scanner(System.in);
int year=0,month=0,day=0,a,b;
a=x.nextInt();//输入判断类型
year=x.nextInt();month= x.nextInt();day=x.nextInt();//输入年月日
DateUtil c=new DateUtil(year,month,day);
if(a==1){//求下n天
b=x.nextInt();//输入n
if(!c.checkInputValidity()||b<0){//如果数据不合法
System.out.println("Wrong Format");
}
else
System.out.println(year+"-"+month+"-"+day+" next "+b+" days is:"+c.getNextNDays(b).showDate());
}
else if(a==2){
b=x.nextInt();//输入n
if(!c.checkInputValidity()||b<0){//如果数据不合法
System.out.println("Wrong Format");
}
else
System.out.println(year+"-"+month+"-"+day+" previous "+b+" days is:"+c.getPreviousNDays(b).showDate());
}
else if(a==3){
int y1,m1,d1;
y1=x.nextInt();m1= x.nextInt();d1=x.nextInt();//输入第二个年月日
DateUtil d=new DateUtil(y1,m1,d1);
if(!c.checkInputValidity()||!d.checkInputValidity()){//如果数据不合法
System.out.println("Wrong Format");
}
else
System.out.println("The days between "+year+"-"+month+"-"+day+" and "+y1+"-"+m1+"-"+d1+" are:"+c.getDaysofDates(d));
}
else
System.out.println("Wrong Format");
}
}