7-7 日期类设计

参考题目3和日期相关的程序,设计一个类DateUtil,该类有三个私有属性year、month、day(均为整型数),其中,year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 除了创建该类的构造方法、属性的getter及setter方法外,需要编写如下方法:

public boolean checkInputValidity();//检测输入的年、月、日是否合法
public boolean isLeapYear(int year);//判断year是否为闰年
public DateUtil getNextNDays(int n);//取得year-month-day的下n天日期
public DateUtil getPreviousNDays(int n);//取得year-month-day的前n天日期
public boolean compareDates(DateUtil date);//比较当前日期与date的大小(先后)
public boolean equalTwoDates(DateUtil date);//判断两个日期是否相等
public int getDaysofDates(DateUtil date);//求当前日期与date之间相差的天数
public String showDate();//以“year-month-day”格式返回日期值

应用程序共测试三个功能:

  1. 求下n天
  2. 求前n天
  3. 求两个日期相差的天数

注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改)

程序主方法如下:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int year = 0;
        int month = 0;
        int day = 0;

        int choice = input.nextInt();

        if (choice == 1) { // test getNextNDays method
            int m = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            m = input.nextInt();

            if (m < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:");
            System.out.println(date.getNextNDays(m).showDate());
        } else if (choice == 2) { // test getPreviousNDays method
            int n = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            n = input.nextInt();

            if (n < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            System.out.print(
                    date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:");
            System.out.println(date.getPreviousNDays(n).showDate());
        } else if (choice == 3) {    //test getDaysofDates method
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            int anotherYear = Integer.parseInt(input.next());
            int anotherMonth = Integer.parseInt(input.next());
            int anotherDay = Integer.parseInt(input.next());

            DateUtil fromDate = new DateUtil(year, month, day);
            DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);

            if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
                System.out.println("The days between " + fromDate.showDate() + 
                        " and " + toDate.showDate() + " are:"
                        + fromDate.getDaysofDates(toDate));
            } else {
                System.out.println("Wrong Format");
                System.exit(0);
            }
        }
        else{
            System.out.println("Wrong Format");
            System.exit(0);
        }        
    }
}

输入格式:

有三种输入方式(以输入的第一个数字划分[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

代码展示

化零为整的思想,但是这样在计算中多出的加减会有溢出(int)的情况导致答案错误,所以先转long算完再转回来

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int year = 0;
        int month = 0;
        int day = 0;

        int choice = input.nextInt();

        if (choice == 1) { // test getNextNDays method
            int m = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            //test
            //System.out.println(date.showDate());

            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            m = input.nextInt();

            if (m < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + m + " days is:");
            System.out.println(date.getNextNDays(m).showDate());
        } else if (choice == 2) { // test getPreviousNDays method
            int n = 0;
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            DateUtil date = new DateUtil(year, month, day);

            if (!date.checkInputValidity()) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            n = input.nextInt();

            if (n < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            System.out.print(
                    date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " previous " + n + " days is:");
            System.out.println(date.getPreviousNDays(n).showDate());
        } else if (choice == 3) {    //test getDaysofDates method
            year = Integer.parseInt(input.next());
            month = Integer.parseInt(input.next());
            day = Integer.parseInt(input.next());

            int anotherYear = Integer.parseInt(input.next());
            int anotherMonth = Integer.parseInt(input.next());
            int anotherDay = Integer.parseInt(input.next());

            DateUtil fromDate = new DateUtil(year, month, day);
            DateUtil toDate = new DateUtil(anotherYear, anotherMonth, anotherDay);

            //test
            //System.out.println(fromDate.showDate());
            //System.out.println(toDate.showDate());

            if (fromDate.checkInputValidity() && toDate.checkInputValidity()) {
                System.out.println("The days between " + fromDate.showDate() +
                        " and " + toDate.showDate() + " are:"
                        + fromDate.getDaysofDates(toDate));
            } else {
                System.out.println("Wrong Format");
                System.exit(0);
            }
        } else {
            System.out.println("Wrong Format");
            System.exit(0);
        }
    }
}

class DateUtil {
    private int year;
    private int month;
    private int day;

    //检测输入的年、月、日是否合法
    public boolean checkInputValidity() {
        if (this.year >= 1820 && this.year <= 2020) {
            int flag = 0;
            if (isLeapYear(this.year)) flag = 1;
            if (this.month >= 1 && this.month <= 12) {
                if (this.day >= 1 && this.day <= standard[flag][this.month]) {
                    return true;
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    //判断year是否为闰年
    public boolean isLeapYear(int year) {

        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
            return true;
        else return false;
        
    }

    int[][] standard = {{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
            {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};

    //                   0   1   2   3   4   5   6   7   8   9  10  11  12
    //取得year-month-day的下n天日期
    public DateUtil getNextNDays(int m) {
        DateUtil d = new DateUtil(this.year, this.month, this.day);
        //格式化成每月第一天
        long n = (long) m;
        n += (d.getDay() - 1);
        d.setDay(1);
        int flag = 0;
        if (isLeapYear(d.getYear())) {
            flag = 1;
        }
        while (n >= standard[flag][d.getMonth()]) {
            n -= standard[flag][d.getMonth()];
            if (d.getMonth() == 12) {
                d.setYear(d.getYear() + 1);
                d.setMonth(1);
                //年份发生变化时,需要再次进行判断
                if (isLeapYear(d.getYear())) {
                    flag = 1;
                } else {
                    flag = 0;
                }
            } else {
                d.setMonth(d.getMonth() + 1);
            }
        }

        d.setDay((int)(n + 1));

        return d;
    }

    //取得year-month-day的前n天日期
    public DateUtil getPreviousNDays(int n) {
        DateUtil d = new DateUtil(this.year, this.month, this.day);

        if (n < d.getDay())
            return new DateUtil(this.year, this.month, this.day - n);

        //格式化成每月第一天
        n -= d.getDay() - 1;
        d.setDay(1);

        int flag = 0;
        if (isLeapYear(d.getYear())) {
            flag = 1;
        }

        while (n >= standard[flag][d.getMonth() - 1]) {
            n -= standard[flag][d.getMonth() - 1];
            if (d.getMonth() == 1) {
                if (n >= 31) {
                    d.setYear(d.getYear() - 1);
                    d.setMonth(12);
                    n -= 31;
                    //年份发生变化时,需要再次进行判断
                    if (isLeapYear(d.getYear())) {
                        flag = 1;
                    } else {
                        flag = 0;
                    }
                } else {
                    //这里跳出,说明一定是前一年十二月的某日
                    //或者本年1月1号(n==0)
                    break;
                }
            } else {
                d.setMonth(d.getMonth() - 1);
            }
        }

        if (n != 0) {
            if (d.getMonth() == 1) {
                d.setYear(d.getYear() - 1);
                d.setMonth(12);
                d.setDay(31 - n + 1);
            } else {
                //这两句位置不能对调
                d.setDay(standard[flag][d.getMonth() - 1] - n + 1);
                d.setMonth(d.getMonth() - 1);
            }
        } else {
            return d;
        }

        return d;
    }

    //比较当前日期与date的大小(先后)
    public boolean compareDates(DateUtil date) {
        //调用者大返回true
        if (this.year > date.year) {
            return true;
        } else if (this.year == date.year) {
            if (this.month > date.month) {
                return true;
            } else if (this.month == date.month) {
                if (this.day >= date.day) return true;
                else return false;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    //判断两个日期是否相等
    public boolean equalTwoDates(DateUtil date) {
        if (this.year == date.year && this.month == date.month && this.day == date.day)
            return true;
        else return false;
    }

    //求当前日期与date之间相差的天数
    public int getDaysofDates(DateUtil date) {
        if (this.equalTwoDates(date)) return 0;
        DateUtil d1, d2;

        //test
        //System.out.println("进函数了");

        //d1是小的那个
        if (this.compareDates(date)) {
            d1 = new DateUtil(date.year, date.month, date.day);
            d2 = new DateUtil(this.year, this.month, this.day);
        } else {
            d1 = new DateUtil(this.year, this.month, this.day);
            d2 = new DateUtil(date.year, date.month, date.day);
        }
        /*
        System.out.println("如果我出现了说明赋值没问题");
        System.out.println(d1.showDate());
        System.out.println(d2.showDate());
        System.out.println();
        */
        //化零为整
        int gap = 0;
        //对齐日,回退到每月1号
        gap -= d1.getDay() - 1;
        d1.setDay(1);
        gap += d2.getDay() - 1;
        d2.setDay(1);

        /*System.out.println("对齐日之后,gap = " + gap);
        System.out.println("d1 = " + d1.showDate());
        System.out.println("d2 = " + d2.showDate());
        */
        //对齐月,回退到每年1月
        int flag1 = 0;
        if (isLeapYear(d1.getYear())) flag1 = 1;
        for (int i = 1; i < d1.getMonth(); i++) {
            gap -= standard[flag1][i];
        }
        d1.setMonth(1);

        int flag2 = 0;
        if (isLeapYear(d2.getYear())) flag2 = 1;
        for (int i = 1; i < d2.getMonth(); i++) {
            gap += standard[flag2][i];
        }
        d2.setMonth(1);
        /*
        System.out.println("对齐月之后,gap = " + gap);
        System.out.println("d1 = " + d1.showDate());
        System.out.println("d2 = " + d2.showDate());
        */
        //逐步跨年
        while (d1.getYear() < d2.getYear()) {
            if (isLeapYear(d1.getYear()))
                gap += 366;
            else gap += 365;
            //最开始忘了修改这个↓,导致陷入死循环
            d1.setYear(d1.getYear() + 1);
        }
        return gap;
    }

    //以“year-month-day”格式返回日期值
    public String showDate() {
        return this.year + "-" + this.month + "-" + this.day;
    }

    public DateUtil() {
    }

    public DateUtil(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public int getYear() {
        return year;
    }

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

    public int getMonth() {
        return month;
    }

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

    public int getDay() {
        return day;
    }

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

  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值