You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Java日历程序,实现输入年份打印全年12个月日历?

全年日历打印修改方案

核心修改思路

原代码已经具备单个月份日历的生成能力,要实现全年打印,只需要循环遍历1-12月,为每个月份创建实例并调用打印方法,同时修复原代码中标题居中的bug,优化格式逻辑。

具体修改步骤

  1. 修复月份标题居中逻辑
    原代码靠一堆if-else判断月份加空格,不仅容易漏写(比如1月、10月的输出被注释掉了),还不够灵活。可以通过计算标题长度,动态生成左边空格,实现通用的居中效果:
// 替换原printCalendar中的标题判断代码
String title = MONTHS[month] + " " + year;
// 日历每行总宽度匹配星期行的长度(21字符)
int totalWidth = 21;
int leftSpaces = (totalWidth - title.length()) / 2;
// 打印左边空格 + 标题
System.out.printf("%" + leftSpaces + "s%s%n", "", title);
  1. 修改main方法,实现全年遍历
    删掉原来获取月份输入的代码,只获取年份,然后循环1到12,依次创建每个月份的Month实例并打印日历,建议在月份之间加分隔线提升可读性:
public static void main(String[] args) {
    Scanner s = new Scanner(System.in);
    System.out.println("Enter year: ");
    int year = s.nextInt();
    s.close(); // 关闭Scanner避免资源泄漏

    for (int month = 1; month <= 12; month++) {
        Month m = new Month(month, year);
        m.printCalendar();
        // 月份之间加分隔线
        System.out.println("---------------------");
    }
}
  1. 验证闰年处理
    原代码的isLeapYear逻辑是正确的,getNumDays也能正确返回闰年2月的29天,无需修改。

修改后的完整代码

import java.util.Scanner;

public class Month {
    private static final String[] MONTHS = {
            "", "January", "February", "March", "April", "May", "June", "July",
            "August", "September", "October", "November", "December"
    };

    private static final int[] NUMDAYS = {
            0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
    };

    private int month;
    private int year;

    public Month(int month, int year) {
        this.month = month;
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public int getYear() {
        return year;
    }

    private boolean isLeapYear() {
        if (year % 400 == 0) {
            return true;
        }
        if (year % 100 == 0) {
            return false;
        }
        return year % 4 == 0;
    }

    private int getNumDays() {
        if (month == 2) {
            return isLeapYear() ? 29 : 28;
        } else {
            return NUMDAYS[month];
        }
    }

    private int getStartDOW() {
        int m, y;
        if (month < 3) {
            m = month + 12;
            y = year - 1;
        } else {
            m = month;
            y = year;
        }
        return (13 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7;
    }

    public void printCalendar() {
        // 动态计算标题居中的空格
        String title = MONTHS[month] + " " + year;
        int totalWidth = 21;
        int leftSpaces = (totalWidth - title.length()) / 2;
        System.out.printf("%" + leftSpaces + "s%s%n", "", title);

        System.out.println(" S  M  T  W  T  F  S");
        int dow = getStartDOW();
        for (int i = 0; i < dow; i++) {
            System.out.print("   ");
        }
        int numdays = getNumDays();
        for (int i = 1; i <= numdays; i++) {
            System.out.printf("%2d ", i);
            if (dow == 6) {
                System.out.println();
                dow = 0;
            } else {
                dow++;
            }
        }
        System.out.println();
    }

    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        System.out.println("Enter year: ");
        int year = s.nextInt();
        s.close();

        for (int month = 1; month <= 12; month++) {
            Month m = new Month(month, year);
            m.printCalendar();
            System.out.println("---------------------");
        }
    }
}

关键说明

  • 标题居中优化:用printf格式化语法动态计算空格,不管月份名称长度如何,都能自动居中,避免了原代码的硬编码错误。
  • 全年遍历逻辑:通过for循环创建12个月份实例,逐个打印,逻辑清晰直接。
  • 资源处理:添加Scanner.close(),养成良好的资源回收习惯。

内容的提问来源于stack exchange,提问作者NEWCODE

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 22:30:55