Java实现自定义年历与月历:使用Calendar打印日历表
在Java开发中,有时需要在控制台或简单界面中以文本形式展示日历信息。本文将演示如何利用标准库中的 Calendar 和 GregorianCalendar 类,构建一个支持自定义年份、月份以及标记“今天”的日历打印工具。
核心原理与依赖环境
生成日历的核心在于确定两个要素:一是每个月包含多少天(考虑平闰年二月),二是该月第一天是星期几(用于前置空白填充)。Java 内置的 java.util 包提供了强大的日期处理工具,无需引入外部库即可实现此功能。
第1步:设置日期上下文与获取初始偏移
为了准确排版,首先需要定位到指定的年月,并计算出该月1号对应的星期值。Java的Calendar对象默认将星期日设为1,星期六设为7,这在计算空格填充时非常关键。
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class HongtenDate {
private int year;
// 记录当年1月1日是星期几的辅助索引
private int whatDayOnJanuaryOne;
// 构造函数:默认当前年份
public HongtenDate() {
Calendar cal = Calendar.getInstance();
this.year = cal.get(Calendar.YEAR);
setWhatDayOnJanuaryOne(getJanuaryOne(year));
}
// 构造函数:指定年份
public HongtenDate(int year) {
this.year = year;
setWhatDayOnJanuaryOne(getJanuaryOne(year));
}
}
第2步:计算每月天数与首尾对齐逻辑
不同月份的天数固定为31、30或28/29天。程序通过判断月份数字来分发不同的打印逻辑。在每一行输出日期前,需要填充若干个制表符(\t)以对齐星期标题。
/**
* 获取某年1月1日是星期几 (0=Sun, 1=Mon... 6=Sat)
*/
public int getJanuaryOne(int year) throws Exception {
int[] weekDays = { 0, 1, 2, 3, 4, 5, 6 };
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date dt = sdf.parse(year + "-01-01");
cal.setTime(dt);
// Calendar.DAY_OF_WEEK: 周日=1, 周六=7。我们需要转为0-6
int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
if (w < 0) w = 0;
return weekDays[w];
}
第3步:执行月度日历打印(含当前日标记)
这是最通用的方法。它接受月份参数,或者不传参直接打印当月。逻辑如下:
- 初始化
GregorianCalendar指向指定月的1号。 - 打印表头:
日 一 二 三 四 五 六。 - 根据1号的星期值,循环打印前导空格。
- 循环增加日期,直到月份发生变化。每打印一个日期,检查是否为周六,若是则换行。
- 如果日期小于10,补空格保持列宽对齐;若需标记当天,添加特殊符号。
public void printMonthOfYear(int mon) throws Exception {
if (mon < 1 || mon > 12) {
System.out.println("你输入的月份[" + mon + "]不对,请检查在进行....");
return;
}
GregorianCalendar now = new GregorianCalendar();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse(year + "-" + mon + "-01");
now.setTime(date);
int month = now.get(Calendar.MONTH); // 获取目标月份索引
now.set(Calendar.DAY_OF_MONTH, 1); // 确保从1号开始
int week = now.get(Calendar.DAY_OF_WEEK); // 获取1号的星期
System.out.println("日\t一\t二\t三\t四\t五\t六");
// 打印前置空白
for (int i = Calendar.SUNDAY; i < week; i++) {
System.out.print("\t");
}
// 打印日期主体
while (now.get(Calendar.MONTH) == month) {
int day = now.get(Calendar.DAY_OF_MONTH);
// 处理个位数日期对齐
if (day < 10) {
System.out.print(" " + day + "\t");
} else {
System.out.print("" + day + "\t");
}
// 周六换行
if (week == Calendar.SATURDAY) {
System.out.println();
}
// 进入下一天
now.add(Calendar.DAY_OF_MONTH, 1);
week = now.get(Calendar.DAY_OF_WEEK);
}
}
第4步:集成全年视图与平闰年处理
对于全年的打印,程序遍历1到12月。由于2月的特殊性(平年28天,闰年29天),代码中通常会有专门的 printFebuary 方法,并通过 year % 4 == 0 进行闰年判断。其余月份则调用统一的 print31 或 print30 方法复用逻辑。
以下是一个简单的测试入口,展示如何调用上述功能:
public static void main(String[] args) throws Exception {
// 示例1:打印当前月份的日历,并尝试标记“今天”(需在具体实现中加入日期比对逻辑)
HongtenDate date = new HongtenDate();
// date.printCurrentMonth();
// 示例2:打印2014年1月的日历
HongtenDate hd = new HongtenDate(2014);
// hd.printMonthOfYear(1);
}
通过组合上述模块,开发者可以轻松获得一个结构清晰、格式规范的文本日历。关键在于利用Calendar对象的自动化日期进位功能,避免手动编写复杂的月份天数映射表。
以上就是Java实现自定义年历与月历的详细流程,更多关于Java日期处理的文章资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













