日期计算器:告诉某个日期是一周中的哪一天



我正在尝试用Java编写一个程序(这是一个学校作业,告诉你某个日期是一周中的哪一天。(日期应写在 yyyy-mm-dd 格式上。我以为我已经想出了下面代码的解决方案,但后来我发现了一个错误。

当您运行代码并在对话框中键入 1999-12-31

时,程序会告诉您输入的日期 (1999-12-31( 是星期五。但是当您输入日期 2000-01-01(即 1999-12-31 之后的一天(时,程序会告诉您这一天是星期日!星期六怎么了?当您输入 2000-02-29 和 2000-03-01 时,也会发生类似的问题,它们都给出星期三作为答案!

我还没有注意到,仅当您输入介于 2000-01-01 和 2000-02-29 之间的日期时,才会出现此错误。如果有人能帮助我找到错误的原因并解决问题,我将不胜感激!

import static javax.swing.JOptionPane.*;
import static java.lang.Math.*;
public class DateCalc {
    // Here, between the DateCalc class declaration and the main method, several methods used in the program are
    // constructed.
    // The method isLeapYear tests whether the entered year is a leap year or not.
    private static boolean isALeapYear(int year)    {
        // If the year is a multiple of 4 and not a multiple of 100, or a multiple of 400, then it is a leap year.
        if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)  {
            return true;
        }
        else {
            return false;
        }
    }
    // A method that tests whether a given string is written as a valid date.
    private static boolean isAValidDate(int year, int month, int day)   {
        int maxValidYear = 9999;
        int minValidYear = 1754;
        if (year > maxValidYear || year < minValidYear) {
            return false;
        }
        if (month < 1 || month > 12)    {
            return false;
        }
        if (day < 1 || day > 31)    {
            return false;
        }
        // Handle the February Month
        if (month == 2) {
            if (isALeapYear(year)) {
                return (day <= 29); // This statement is true if the value of the day is less than or equal to 29 if the month is February within a leap year.
                // Otherwise the statement is false and the method will return the boolean value false.
            }
            else {
                return (day <= 28); // This statement is true if the value of the day is less than or equal to 28 if the month is February within a non-leap year.
                // Otherwise the statement is false and the method will return the boolean value false.
            }
        }
        // Month of April, June, September and November must have number of days less than or equal to 30.
        if (month == 4 || month == 6 || month == 9 || month == 11)  {
            return (day <= 30);
        }
        return true;
    }
    // A method that calculates the day number within the year.
    private static int dayNumberWithinYear(int year, int month, int day)    {
        // An array which stores the number of days in the different months (when the year is not a leap year).
        // (Index 0 is the number of days in January, index 1 is the number of days in February, etc.)
        int[] monthStructure = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
        // If the entered year is a leap year, then the monthStructure array will be initialized with an extra day in February, i.e the leap day.
        if (isALeapYear(year))  {
            monthStructure[1] = 29;
        }
        int sumDaysInPreviousMonths = 0;
        int daysInTheCurrentMonth = day;
        int dayNumber = 0;
        // Loops through all the months (index 0 is January, index 1 is February, etc.).
        for (int i = 0; i < month - 1; i++) {
            sumDaysInPreviousMonths += monthStructure[i];
        }
        dayNumber = sumDaysInPreviousMonths + daysInTheCurrentMonth;
        return dayNumber;
    }
    // A method that decides the day of the week of an entered date.
    private static void weekDay(int year, int month, int day)   {
        // The number of days that have passed since January 1, 1754, excluding the days of the entered year and
        // excluding the leap days.
        int sumDaysInOrdinaryYears = (year - 1754) * 365;
        int sumLeapDaysInLeapYears = 0;
        // Suppose the entered year is n. The for-loop goes through all the years from year n-1 to year 1754, and
        // checks if the current year in the loop is a leap year. The number of leap years between year 1754 and n-1
        // is equal to the number of days that will get added (beside from the days in ordinary years) to the total
        // days from January 1, 1754 to the entered date.
        for (; year > 1754; year -= 1)  {
            if (isALeapYear(year))  {
                sumLeapDaysInLeapYears += 1;
            }
        }
        // The sum of all days from year 1754 to year n-1 (if the entered year is n), is equal to the sum of days in
        // the ordinary years and the leap days in the years.
        int sumDaysInEveryYearExcludingTheEntered = sumDaysInOrdinaryYears + sumLeapDaysInLeapYears;
        int sumDaysInTotalYears = sumDaysInEveryYearExcludingTheEntered + dayNumberWithinYear(year, month, day);
        int weekDay = sumDaysInTotalYears % 7;
        if (weekDay == 0)   {
            showMessageDialog(null, "The date is a monday.");
        }
        else if (weekDay == 1)  {
            showMessageDialog(null, "The date is a tuesday.");
        }
        else if (weekDay == 2)  {
            showMessageDialog(null, "The date is a wednesday.");
        }
        else if (weekDay == 3)  {
            showMessageDialog(null, "The date is a thursday.");
        }
        else if (weekDay == 4)  {
            showMessageDialog(null, "The date is a friday.");
        }
        else if (weekDay == 5)  {
            showMessageDialog(null, "The date is a saturday.");
        }
        // If weekDay == 6
        else    {
            showMessageDialog(null, "The date is a sunday.");
        }
    }
    public static void main(String[] args)  {
        // This is step 3 in the laboratory instruction.
        while (true)    {
            String date = showInputDialog("Please, enter a date on the form yyyy-mm-dd");
            // If the user clicks 'Cancel' or clicks 'OK' when the dialog box is empty, the program will exit.
            if (date == null || date.length() == 0) {
                break;
            }
            int y = Integer.parseInt(date.substring(0,4));
            int m = Integer.parseInt(date.substring(5,7));
            int d = Integer.parseInt(date.substring(8));
            if (!isAValidDate(y, m, d)) {
                showMessageDialog(null, "Error! The entered date is invalid. " +
                        " Please enter a valid date on the form yyyy-mm-dd");
            }
            else {
                weekDay(y, m, d);
            }
        }
    }
}

与其要求我们调试您的整个代码,不如考虑LocalDate以获得所需的结果:

LocalDate ldt = LocalDate.parse("1999-12-31");
System.out.println(ldt.getDayOfWeek());
LocalDate ldt2 = LocalDate.parse("2000-01-01");
System.out.println(ldt2.getDayOfWeek());

输出:

星期五

星期六

问题在于找到闰年的数量。你的逻辑也在计算 2000 年。1999-12-31 和 2000-01-01 的闰年数应相同。仅当月份大于 2 月时,才需要考虑 2000 年。仅当输入日期大于 2 月 28 日时,才增加总和闰年

最新更新