显示给定年月的日历,用java实现

一.结构图

在这里插入图片描述

二.代码

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

三.结果显示

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

四.自顶向下的设计

先把问题拆分成两个子问题:读取用户输人和打印该月的日历。

  1. 使用Scanner来读取年和月份的输人。
  2. 打印给定月份的日历问题可以分解成两个子问题:打印日历的标题和日历的主体
  • 月历的标题由三行组成:年月、虚线、每周七天的星期名称。需要通过表示月份的数字(例如:1)来确定该月的全称(例如:January)。这个步骤是由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。

五.实现细节

方法isLeapYear(int year)可以使用下列代码实现:
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
使用下面的事实实现getTotalNumberOfDaysInMonth(intyear.intmonth)方法:
—月、三月、五月、七月、八月、十月和十二月都有31天。四月、六月、九月和十一月都有30天。二月通常有28天,但是在闰年有29天。因此,一年通常有365天,闰年有366天。
实现getTotalNumberOfDays(int year,int month)方 法:
需 要 计 算1800年1月1日和日历月份的第一天之间的总天数(totalNumberOfDays)。可以求出1800年到该日历年的总天数,然后求出该日历年中在日历月份之前的总天数。这两个总天数相加就是
totalNumberOfDays。
要打印日历体,首先在第一天之前填充一些空格,然后为每个星期打印一条线。

猜你喜欢

转载自blog.csdn.net/weixin_42768634/article/details/113643856
今日推荐