如何修改Java日历程序,实现输入年份打印全年12个月日历?
全年日历打印修改方案
核心修改思路
原代码已经具备单个月份日历的生成能力,要实现全年打印,只需要循环遍历1-12月,为每个月份创建实例并调用打印方法,同时修复原代码中标题居中的bug,优化格式逻辑。
具体修改步骤
- 修复月份标题居中逻辑
原代码靠一堆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);
- 修改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("---------------------"); } }
- 验证闰年处理
原代码的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
相关产品推荐
相关产品推荐

