java - 日期计算器 : Tell what day of the week a certain date is

标签 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);
            }
        }
    }
}

最佳答案

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

输出:

FRIDAY

SATURDAY

关于java - 日期计算器 : Tell what day of the week a certain date is,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54633446/

相关文章:

java - 使用多个位置地理围栏

sql - SQL计算一个人的年龄

java - 以 2014-01-01T00 :00:00. 588Z 等日期字符串结尾的 Z 是什么

android - 使用 DatePickerDialog 时获取星期几

postgresql - 两个工作日(周一至周五)之间的统计数据

java - 包含集合的 Web 应用程序域对象是否应该具有 "add"和 "remove"项目方法?

java - 根据文件头数据确定文件扩展名的设计

java - 连接到 Axon 服务器时更改节点的实例名称

mysql - 不同季节的酒店房价

java - 检查当前日期和时间是否在不包括周末的日期范围内