我正在 java 中编写日历程序,但除了 2015 年 10 月之外,月份不匹配,我需要帮助

I'm writing a calendar program in java, but besides oct 2015 the months dont match, i need help please

基本上,一切正常。但是应该正确的主要内容,即日期,是错误的,到目前为止,2015 年 10 月它是正确的,但由于某种原因我无法检测到,与我的日历相比,我到目前为止尝试的其他月份是不正确的电脑。 这是我的程序,也许你有一些有效的输入可以帮助我解决这些问题。

    public static boolean isLeapYear(int year) {
        int month = 0;
        int s = getDaysIn(month, year);
        return year % 4 == 0 && (year % 100 != 0) || (year % 400 == 0);
    }

    public static int getDaysIn(int month, int year) {
        switch (month) {
            case 1:
                return 31;
            case 2:
                if (isLeapYear(month)) {
                    return 29;
                } else {
                    return 28;
                }
            case 3:
                return 31;
            case 4:
                return 30;
            case 5:
                return 31;
            case 6:
                return 30;
            case 7:
                return 31;
            case 8:
                return 31;
            case 9:
                return 30;
            case 10:
                return 31;
            case 11:
                return 30;
            case 12:
                return 31;
            default:
                return -1;
        }
    }

    public static String getMonthName(int month) {
        switch (month) {
            case 1:
                return "January";
            case 2:
                return "February";
            case 3:
                return "March";
            case 4:
                return "April";
            case 5:
                return "May";
            case 6:
                return "June";
            case 7:
                return "July";
            case 8:
                return "August";
            case 9:
                return "September";
            case 10:
                return "October";
            case 11:
                return "November";
            case 12:
                return "December";
            default:
                return "Invalid month.";
            }
        }

    public static int getStartDay(int month, int year) {
        int days = 0;

        for (int i = 1900; i < year; i++) {
            days = days + 365;
            if (isLeapYear(i)) {
                days = days + 1;
            }
        }
        for (int i = 1; i < month; i++) {
            days = days + getDaysIn(month, year);
        }
        int startday = (days + 1) % 7 + 2;
        return startday;
    }

    public static void displayCalendar(int month, int year) {
        String monthName = getMonthName(month);
        int startDay = getStartDay(month, year);
        int monthDays = getDaysIn(month, year);

        System.out.println("   Sun   Mon   Tue   Wed   Thu   Fri       Sat");
        int weekDay = startDay - 1;
        for (int i = 1; i < startDay; i = i + 1) {
            System.out.print("      ");
        }
        for (int x = 1; x <= monthDays; x++) {
            weekDay = weekDay + 1;
            if (weekDay > 7) {
                System.out.println();
                weekDay = 1;
            }
            System.out.format("   %3d", x);
        }
        if (weekDay > 7) {
            System.out.println();
        }
    }

您的 getStartDay 实际上是您的错误所在:

    for (int i = 1; i < month; i++) {
        days = days + getDaysIn(month, year);
    }
    int startday = (days + 1) % 7 + 2;
    return startday;

应替换为:

    for (int i = 1; i < month; i++) {
        days = days + getDaysIn(i, year);
    }
    int startday = (days % 7) + 2;
    return startday;

如您所见,您的循环存在一个小问题。

您应该在 getDaysIn 调用中使用增量器 i 来计算从年初到您要显示的月份的天数。


第二个错误在这里:

    int startday = (days + 1) % 7 + 2;

这个表达式背后的逻辑对我来说仍然是个谜。

让我们用一个具体的例子来打破这个 :

假设我们要显示 FEB 1900。很容易做到,因为我们从 1900 年一月 开始,所以我们可以很容易地计算天数(一月有 31 天,所以 days = 31)

第一个表达式会得到什么结果return?

= (31 + 1) % 7 + 2
= 32 % 7 + 2    
= 4 + 2    
= 6

因为在您的逻辑中 1 日是星期日,6 日是星期五。

我们来看看吧:

不是预期的结果吧?

我发现此方法还有一个问题。

让我们想象一下days = 33(这永远不会发生,但我们在这里需要这个例子)。

= (33 + 1) % 7 + 2
= 34 % 7 + 2
= 6 + 2
= 8

一周的第 8 天是几号?


正确答案的解释如下:

(days % 7) + 2

days % 7 为我们提供下个月的最后一天的值,当周从 MONDAY 开始时。

我们将此值加 2 :

  • 1 获得所需月份的开始日期。

  • 1 因为我们的日历从星期日开始,我们必须在日历视图中滑动日期。


这是完整的代码(我也做了一些修改以使其更紧凑):

    public class Calendar{

    public static void main(String[] args) {
        // INSERT YOUR TESTS HERE
    }

    public static boolean isLeapYear(int year) {
        return year % 4 == 0 && (year % 100 != 0) || (year % 400 == 0);
    }

    public static int getDaysIn(int month, int year) {
        switch (month) {
            case 1 : case 3 : case 5 : case 7 : case 8 : case 10 : case 12 :
                return 31; 
            case 4 : case 6 : case 9 : case 11 :
                return 30; 
            case 2:
                return isLeapYear(year) ? 29 : 28; 
            default:
                return -1;
        }
    }

    public static String getMonthName(int month) {
        String[] months = {"January", "February", "March", "April", "May", "June", 
                "July", "August", "September", "October", "November", "December"};

        return month <= 12 && month > 0 ? months[month - 1] : "Invalid month";
    }

    public static int getStartDay(int month, int year) {
        int days = 0;

        for (int i = 1900; i < year; i++) {
            days += 365;
            if (isLeapYear(i)) {
                days = days + 1;
            }
        }

        for (int i = 1; i < month; i++) {
            days = days + getDaysIn(i, year);
        }
        int startday = (days % 7) + 2;
        return startday;
    }

    public static void displayCalendar(int month, int year) {
        String monthName = getMonthName(month);
        int startDay = getStartDay(month, year);
        int monthDays = getDaysIn(month, year);

        System.out.println("   Sun   Mon   Tue   Wed   Thu   Fri   Sat");
        int weekDay = startDay - 1;
        for (int i = 1; i < startDay; i = i + 1) {
            System.out.print("      ");
        }
        for (int x = 1; x <= monthDays; x++) {
            weekDay = weekDay + 1;
            if (weekDay > 7) {
                System.out.println();
                weekDay = 1;
            }
            System.out.format("   %3d", x);
        }
        if (weekDay > 7) {
            System.out.println();
        }
    }

}

编辑

如果没有显示,您应该尝试在您的 main 方法中写一些东西。

public static void main(String[] args) {
    for (int i = 0 ; i < 5 ; i++){
        System.out.println(getMonthName(i+1) + " " + (2010 + i));
        displayCalendar(i+1, 2010 + i);
        System.out.println();
    }
}

给出以下输出:

    January 2010
   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
February 2011
   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
March 2012
   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
April 2013
   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
May 2014
   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