日期计算器:告诉您某个日期是星期几

时间:2019-02-11 15:06:27

标签: java date dayofweek leap-year

我正在尝试用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);
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

与其要求我们调试您的整个代码,不如考虑使用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());

输出:

  

星期五

     

星期六

答案 1 :(得分:2)

问题在于查找of年数。您的逻辑也算2000年。 1999-12-31和2000-01-01的of年数应该相同。仅当月份大于二月时,才需要考虑2000年。仅当输入日期大于2月28日时,才增加sumLeapDaysInLeapYears