Javaで実装された特定の年と月のカレンダーを表示します

1.構造図

ここに画像の説明を挿入

2.コード

package com.zhuo.base.com.zhuo.base;

import com.sun.org.apache.xerces.internal.impl.xs.SchemaNamespaceSupport;

import java.util.Scanner;

public class PrintCalendar {
    
    
    /*main方法*/
    public static void main(String[] args) {
    
    
        Scanner input = new Scanner(System.in);
        System.out.print("Enter full year (e.g., 2012): ");//提示用户输入年份
        int year = input.nextInt();
        System.out.print("Enter month as a number between 1 and 12: ");//提示用户输入月份
        int month = input.nextInt();
        printMonth(year, month);//打印一年中某个月的日历调用
    }
    /*打印一年中一个月的日历方法*/
    public static void printMonth(int year, int month) {
    
    
        printMonthTitle(year, month);//打印日历的标题方法调用
        printMonthBody(year, month);//打印日历正文方法调用
    }
    /*打印月份标题方法 */
    public static  void printMonthTitle(int year, int month) {
    
    
        System.out.println("           " + getMonthName(month) + " " + year);
        System.out.println(" ---------------------------");
        System.out.println(" Sun Mon Tue Wed Thu Fri Sat");
    }
    /*获取月份的英文名称方法 */
    public static String getMonthName(int month) {
    
    
        String monthName = "";
        switch (month) {
    
    
            case 1: monthName = "January"; break;
            case 2: monthName = "February"; break;
            case 3: monthName = "March"; break;
            case 4: monthName = "April"; break;
            case 5: monthName = "May"; break;
            case 6: monthName = "June"; break;
            case 7: monthName = "July"; break;
            case 8: monthName = "August"; break;
            case 9: monthName = "September"; break;
            case 10: monthName = "October"; break;
            case 11: monthName = "November"; break;
            case 12: monthName = "December";
        }
        return monthName;
    }
    /*打印月体方法*/
    public static void printMonthBody(int year, int month) {
    
    
        int startDay = getStartDay(year, month);//为每月的第一个天获取一周的开始日期方法调用
        int numOfDayInMonth = getNumberOfDaysInMonth(year, month);//获取当月天数方法调用
        /* 在每月第一天之前填充空间*/
        int i = 0;
        for (i = 0; i < startDay; i++)
            System.out.print("    ");
        for (i = 1; i <= numOfDayInMonth; i++) {
    
    
            System.out.printf("%4d", i);
            if ((i + startDay) % 7 == 0)
                System.out.println();
        }
        System.out.println();
    }
    /*获取每一年每个月开始日期*/
    public static int getStartDay(int year, int month) {
    
    
        final int START_DAY_FOR_JAN_1_1800 = 3;
        int totalNumberOfDays = getTotalNumberOfDays(year, month);//获取从1800年1月1日到每一年每个月一号总天数的方法调用
        return (totalNumberOfDays + START_DAY_FOR_JAN_1_1800) % 7;//返回每一年每一个月的开始日期
    }
    /*获取自1800年1月1日以来的总天数的方法 */
    public static int getTotalNumberOfDays(int year, int month) {
    
    
        int total = 0;
        /*得到从1800年1月1号到任何一年的总天数*/
        for (int i = 1800; i < year; i++)
            if (isLeapYear(i))
                total += 366;
            else
                total += 365;
        for (int i = 1; i < month; i++) {
    
    
            total += getNumberOfDaysInMonth(year, i);//添加从一月到日历月前一个月的天数
        }
        return total;
    }
    /*获取一个月的天数的方法*/
    public static int getNumberOfDaysInMonth(int year, int month) {
    
    
        if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12)
            return 31;
        else if (month == 4 || month == 6 || month == 9 || month == 11)
            return 30;
        else
            return isLeapYear(year) ? 29 : 28;
    }
    /*确定是否是闰年的方法*/
    public static boolean isLeapYear(int year) {
    
    
        return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
    }
}

3.結果の表示

Enter full year (e.g., 2012): 2021
Enter month as a number between 1 and 12: 2
           February 2021
 ---------------------------
 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

Process finished with exit code 0

4.トップダウン設計

まず、問題を2つのサブ問題に分割します。ユーザー入力の読み取りと月のカレンダーの印刷です。

  1. スキャナーを使用して、年と月の入力を読み取ります。
  2. 特定の月のカレンダーを印刷する問題は、カレンダーのタイトルとカレンダーの本体を印刷するという2つのサブ問題に分けることができます。
  • 月間カレンダーのタイトルは、年と月、点線、および7つの曜日の週名の3行で構成されます。月のフルネーム(例:1月)は、月を表す数字(例:1)で決定する必要があります。このステップはgetMonthNameによって実行されます
  • カレンダーの本体を印刷するには、月の最初の日が曜日(getStartDay)であり、月の日数(getNumberOfDaysInMonth)を知っている必要があります。例:2013年12月は31日です。 2013年12月1日は日曜日です。
  1. 月の最初の日を知るにはどうすればよいですか?それを取得する方法はいくつかあります。ここでは、次の方法を使用します。1800年1月1日が水曜日(START_DAY_F0R_JAN_l_1800 = 3)であることがわかっているとし、1800年1月1日から暦月の初日までの合計日数(totalNumberOfDays)を計算します。毎週7日あるため、暦月の最初の日の週は(totalNumberOfDays + START_DAY_FOR_JAN_1_1800)%7です。このようにして、getStartDayの問題をgetTotalNumberOfDaysにさらに絞り込むことができます。
  2. 合計日数を計算するには、その年がうるう年であるかどうかと、各月の日数を知る必要があります。したがって、getTotalNumberOfDaysは、isLeapYearとgetNumberOfDaysInMonthの2つのサブ問題にさらに絞り込むことができます。

5.実装の詳細

メソッドisLeapYear(int year)は、次のコードで実装できます。returnyear
%400 == 0 ||(year%4 == 0 && year%100!= 0);
次のファクトを使用してgetTotalNumberOfDaysInMonth(intyear)を実装します.intmonth)メソッド:
-月、3月、5月、7月、8月、10月、12月は31日です。4月、6月、9月、11月は30日あります。2月は通常28日ですが、うるう年には29日あります。したがって、通常、1年は365日であり、うるう年は366日です。
getTotalNumberOfDays(int year、int month)メソッドを実装します
。1800年1月1日から暦月の最初の日までの合計日数(totalNumberOfDays)を計算する必要があります1800年から暦年までの合計日数を検索し、次に暦年の暦月の前の合計日数を検索できます。これらの合計2日間の合計は
totalNumberOfDaysです。
カレンダーの本文を印刷するには、最初に初日の前にいくつかのスペースを入力してから、週ごとに1行を印刷します。

おすすめ

転載: blog.csdn.net/weixin_42768634/article/details/113643856