日期计算器:告知特定日期的星期几

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了日期计算器:告知特定日期的星期几相关的知识,希望对你有一定的参考价值。

我正在尝试用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日时才增加sumLeapDaysInLeapYears

以上是关于日期计算器:告知特定日期的星期几的主要内容,如果未能解决你的问题,请参考以下文章

在 datepicker 中选择特定日期时,如何自动填充特定的星期几?

php已知日期获取星期

当用户从日期选择器中选择日期时,如何在下拉列表中获取特定的星期几?

java实现两个日期内具有几个星期几的计算

c语言编程题:输入一个日期,计算出该日期是星期几?

c语言编程题:输入一个日期,计算出该日期是星期几?