【问题标题】:I am receiving 'null' when entering specific dates in my output在输出中输入特定日期时,我收到“null”
【发布时间】:2019-05-24 14:04:39
【问题描述】:

我的代码可以完美编译和运行,但是当我的任何日期是星期六时,输出为“null”而不是“SATURDAY”。下面将举例说明这个问题。

我尝试更改我的“getDayOfWeek”方法中的 if 语句,但我似乎没有解决方案,我也尝试从经验丰富的编码人员那里获得帮助,但由于 java 不是他们的主要语言,他们似乎正在苦苦挣扎...

代码:

class MyDate {

    // properties of date object
    private int day, month, year;

    // constructor with arguments
    public MyDate(int day, int month, int year) {
        this.day = day;
        this.month = month;
        this.year = year;
    }

    public boolean isDateValid() {
        if (month > 12 || month < 1 || day < 1) { // if values exceed 12 or are negative: return false
            return false;
        } else if (year <= 1582 && month <= 10 && day <= 15) { //     starting date
            //   checking
            return false;
        } // for 31 day months: January, March, May, July, August, October, December
        else if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12) {

            if (day > 31) {
                return false;
            }

        } // for 30 day months: April, June, September, November
        else if (month == 4 || month == 6 || month == 9 || month == 11) { 

            if (day > 30) {
                return false;
            }

        } // February check
        else if (month == 2) {

            // leap year check for February
            // 29 days in a leap year
            // 28 days in a common year
            if (isLeapYear()) {
                if (day > 29) {
                    return false;
                }

            } else {
                if (day > 28) {
                    return false;
                }
            }
        }
        return true;
    }

    // checks if input year is leap year
    private boolean isLeapYear() {
        if (year % 4 != 0) {
            return false;
        } else if (year % 400 == 0) {
            return true;
        } else if (year % 100 == 0) {
            return false;
        } else {
            return true;
        }
    }

    // method returns the day of MyDate object
    public int getDay() {
        return day;
    }

    // parameter for day to set
    public void setDay(int day) {
        this.day = day;
    }

    // method returns the month of MyDate object
    public int getMonth() {
        return month;
    }

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

    // method returns the year of MyDate object
    public int getYear() {
        return year;
    }

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

    // method returns all variables: day/month/year of MyDate object 
    public String toString() {
        return day + "/" + month + "/" + year;
    }
}

public class MyCalendar {

    //enums for days of week
    public static enum Day {
        SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY,  SATURDAY;
    };

    //enums for month of year
    public static enum Month {
        JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER;
    };

    //enums for week number of month
    public static enum Week {
        FIRST, SECOND, THIRD, FOURTH, FIFTH;
    };

    //to store Date object
    private MyDate date;

    //constructor taking mydate object
    public MyCalendar(MyDate enteredDate) {
        this.date = enteredDate;
    }

    //main method 
    public static void main(String[] args) {

        boolean dateValid = false; //valid date false
        Scanner input = new Scanner(System.in); //scanner for input
        MyDate enteredDate = null;

        //till valid date found
        while (!dateValid) {
            System.out.print("Enter the date as day month year : ");
            //taking input and creating date output
            enteredDate = new MyDate(input.nextInt(), input.nextInt(), input.nextInt());
            //validating date input

            if (enteredDate.isDateValid()) { //if valid
                MyCalendar myCalendar = new MyCalendar(enteredDate); 
                //creating calendar table

                myCalendar.printDateInfo(); //printing date info
                myCalendar.printCalendar(); //printing calendar
                dateValid = true; //setting validate to true 
            } else {
                System.out.println(enteredDate + " is not a valid date, please re-input a valid date: ");
            }
        }

        input.close();
    }

    // returns number of days in current month
    private int getNumberOfDays() {
        int days = 31;
        int month = date.getMonth();
        if (month == 4 || month == 6 || month == 9 || month == 11)
            days = 30;
        return days;
    }

    //print calendar of input month
    public void printCalendar() {
        System.out.println("\n\nThe Calendar of "+Month.values()[date.getMonth()-1]+" "+date.getYear()+" is :");
        int numberOfMonthDays = getNumberOfDays();
        Day firstWeekdayOfMonth = getDayOfWeek(1, date.getMonth(), date.getYear());
        int weekdayIndex = 0;
        System.out.println("Su Mo Tu We Th Fr Sa");
        // The order of days depends on the input of date 
        // to display output of calendar

        for (int day = 0; Day.values()[day] != firstWeekdayOfMonth; day++) {
            System.out.print("   "); // this loop to print the first day in the
            // correct place
            weekdayIndex++;
        }
        for (int day = 1; day <= numberOfMonthDays; day++) {

            if (day < 10) 
                System.out.print(day + " ");
            else
                System.out.print(day);
            weekdayIndex++;
            if (weekdayIndex == 7) {
                weekdayIndex = 0;
                System.out.println();
            } else {
                System.out.print(" ");
            }
        }
        System.out.println();
    }

    //method to print about date information in literal form
    public void printDateInfo() {
        System.out.println(date + " is a " + getDayOfWeek(date.getDay(), date.getMonth(), date.getYear())
        + " located in the " + Week.values()[getWeekOfMonth() - 1] + " week of "
        + Month.values()[date.getMonth() - 1] + " " + date.getYear());
    }

    /*
     * gets day of the week, returns enum type Day
     *
     * Zellar's congruence to calculate the day of week
     * for any given date after October 15 1582
     * (h) = (q+(13*(m+1)/5)+K+(K/4)+(J/4)+5J)%7 ,q- day of month,
     * m- month, k = year of century (year%100), J = (year/100)
     */
    public Day getDayOfWeek(int day, int month, int year) {
        int q = day;
        int m = month;

        if (m < 3) {
            m = 12 + date.getMonth();
            year = year - 1;
        }
        int K = year % 100;
        int J = year / 100;
        //calculating h value
        int h = (q + (13 * (m + 1) / 5) + K + (K / 4) + (J / 4) + 5 * J) % 7;
        Day output = null;
        if (h < Day.values().length && h > 0) {
            output = Day.values()[h - 1]; //getting respective  enum value
        }
        return output; //returning enum value
    }

    // get week number of current date
    public int getWeekOfMonth() {
        int days = date.getDay();
        int weeks = days / 7;
        days = days % 7;
        if (days > 0)
            weeks++;
        return weeks;
    }

}

预期结果:

java MyCalendar 29/02/2019
29/02/2019 in not a valid date, please re-input a valid date:         25/05/2019
25/05/2019 is a Saturday and located in the fourth week of May 2019
The calendar of May 2019 is:
SUN MON TUE WED THU FRI SAT
            1   2   3   4  
5   6   7   8   9   10  11
12  13  14  15  16  17  18
19  20  21  22  23  24  25
26  27  28  29  30  31

实际结果:

25/05/2019 is a null located in the FOURTH week of MAY 2019

The calendar of May 2019 is:
SUN MON TUE WED THU FRI SAT
            1   2   3   4  
5   6   7   8   9   10  11
12  13  14  15  16  17  18
19  20  21  22  23  24  25
26  27  28  29  30  31

另一个日期(不是星期六)的结果:

24/05/2019 is a FRIDAY located in the FOURTH week of MAY 2019

The calendar of May 2019 is:
SUN MON TUE WED THU FRI SAT
            1   2   3   4  
5   6   7   8   9   10  11
12  13  14  15  16  17  18
19  20  21  22  23  24  25
26  27  28  29  30  31

具体问题: 输出在星期六的所有日期都打印 null,而其他非星期六的日期将获得所需的正确输出。

【问题讨论】:

  • 您是否尝试过使用调试器逐行运行您的代码以找出该 null 的确切来源?
  • 您是否涵盖了 getDay() 返回的值是对应于星期几的 int 的事实:0 代表星期日,1 代表星期一,2 代表星期二...?
  • 你工作太辛苦了。 Java 为此提供了类,例如MonthDayOfWeek 的枚举,以及表示实体的类,例如YearMonth。无需自己动手。有关完整工作示例中的代码,请参阅 my Answer 上的类似问题。
  • 在您的示例中,语句int h = (q + (13 * (m + 1) / 5) + K + (K / 4) + (J / 4) + 5 * J) % 7;h 设置为0。这是有意的吗?在任何情况下,它都会导致output 未被设置,这就是打印null 的原因。

标签: java date null


【解决方案1】:
if (h < Day.values().length && h > 0) {

应该改为

if (h < (Day.values().length + 1) && h > 0) {

【讨论】:

  • 关键是您在下面的代码中使用 (h-1) 和 0
  • 哦.. 抱歉,请在我的代码中删除 +1 附近的额外“**”。我只想强调
  • 不幸的是,它仍然输出为“null”而不是“SATURDAY”。谢谢大家的帮助!
  • 有没有其他可能的方法来解决这个问题?
  • 一次调试,就很清楚了。你的程序不正确。
【解决方案2】:
  • 如果这是用于生产代码,the comment by Basil Bourque 是正确的:您不应开发自己的 MyDate 类,而应依赖内置的 LocalDate 类。
  • 另一方面,如果按照我的假设,这是一个编程练习,那很好,而且(我看得出)你没有理由不努力完成它。

你计算星期几的公式是:

    //calculating h value
    int h = (q + (13 * (m + 1) / 5) + K + (K / 4) + (J / 4) + 5 * J) % 7;

(顺便说一句,请找到更好的变量名,并尊重Java命名约定:变量名不能是大写字母。)我不明白公式,但假设它是正确的,它会计算天0 = 星期六,1 = 星期日,最多 6 = 星期五。要使用此号码查找您的 Day 枚举,请使用

        output = Day.values()[(h + 6) % 7]; //getting respective  enum value

由于h 将始终为非负数且小于 7,因此您不需要封闭的 if 语句。只需无条件分配给output。通过这些更改,我得到了

Enter the date as day month year : 25 5 2019
25/5/2019 is a SATURDAY located in the FOURTH week of MAY 2019


The Calendar of MAY 2019 is :
Su Mo Tu We Th Fr Sa
         1  2  3  4 
5  6  7  8  9  10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

【讨论】:

  • 感谢您的帮助,给出的公式是计算星期几的“Zellar同余”,我需要在我的代码中实现该公式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-03-27
  • 1970-01-01
  • 1970-01-01
  • 2018-03-17
  • 1970-01-01
  • 2022-06-16
  • 1970-01-01
相关资源
最近更新 更多