用Java打印日历。循环判断非常多,不忍直视。
最终实现的格式:
- 月份名称用英文,取前3个字母,居中展示
- 星期表头,从周一开始到周日结束,取英文前3个字母
- 当月当天的号数后面加“*”号标记
public static void main(String[] args) {
// 获取当前时间,年月日。获取月和日用来特殊标记今天,即在今天的日期后面加*号
LocalDate date = LocalDate.now();
int year = date.getYear();
int month = date.getMonthValue();
int today = date.getDayOfMonth();
// 初始化日期为当年的1月1日
date = LocalDate.of(year, 1, 1);
while (year == date.getYear()) {
// 打印月份信息,并居中展示
System.out.print(" ");
System.out.printf("%15.3s", date.getMonth());
System.out.printf("%-12s", " ");
System.out.print(" ");
// 一行打印四个月,到4的整数倍时,开始打印具体的月份信息
if (date.getMonthValue() % 4 == 0) {
// 打印具体的月份日历
// 由于前面月份加1打印了月份信息,所以要减3个月,重新回到第一个月开始打印
date = date.minusMonths(3);
// 打印月份后面的换行
System.out.println();
// 打印星期表头,并且在星期表头打印完之后换行
for (int i = 0; i < 4; i++) {
if (i < 3) {
System.out.print(" Mon Tue Wed Thu Fri Sat Sun ");
} else {
System.out.print(" Mon Tue Wed Thu Fri Sat Sun ");
}
}
System.out.println();
// 打印日期,将日期初始化为当月1号
LocalDate date1 = LocalDate.of(year, date.getMonthValue(), 1);
// 用i记录每一行打印4周,用k记录每个月份里的周数
for (int i = 0, k = 0; ; ) {
// 当前打印月份的1号
int month1 = date1.getMonthValue();
LocalDate date2 = LocalDate.of(year, month1, 1);
DayOfWeek weekday = date2.getDayOfWeek();
int value = weekday.getValue();
// k == 0表示当月的第一周
if (k == 0) {
// 当月第1天前面的占位
for (int j = 1; j < value; j++) {
System.out.print(" ");
}
// 打印当月第1号
System.out.printf("%3d", date2.getDayOfMonth());
if (date2.getMonthValue() == month && date2.getDayOfMonth() == today) {
System.out.print("*");
} else {
System.out.print(" ");
}
// 打印当月第一周剩下的星期,直到周日
while (date2.getDayOfWeek().getValue() < 7) {
date2 = date2.plusDays(1);
System.out.printf("%3d", date2.getDayOfMonth());
if (date2.getMonthValue() == month && date2.getDayOfMonth() == today) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
} else {
// k记录一个月横跨的周数,大于6说明该月份所有日期打印完毕
if (k > 6) {
break;
}
// 开始打印每月除第1周之外的日期,它们的第一天一定是周一,首先找到上周最后一天是几号
while (date2.getDayOfWeek().getValue() < 7) {
date2 = date2.plusDays(1);
}
date2 = date2.plusWeeks(k - 1);
// 上月最后1天加1,如果加完月份还在当前月份,那么先打印这周的第一天
date2 = date2.plusDays(1);
if (date2.getMonthValue() == month1) {
System.out.printf("%3d", date2.getDayOfMonth());
if (date2.getMonthValue() == month && date2.getDayOfMonth() == today) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
// 然后打印这周剩下的日子
while (date2.getDayOfWeek().getValue() < 7 && date2.getMonthValue() == month1) {
date2 = date2.plusDays(1);
if (date2.getMonthValue() == month1) {
System.out.printf("%3d", date2.getDayOfMonth());
if (date2.getMonthValue() == month && date2.getDayOfMonth() == today) {
System.out.print("*");
} else {
System.out.print(" ");
}
}
}
// 当日子加了以后已经不在同一个月份,那么打印该月最后一天到周日的空格
if (date2.getMonthValue() != month1) {
weekday = date2.getDayOfWeek();
value = weekday.getValue();
for (int j = 0; j <= 7 - value; j++) {
System.out.print(" ");
}
}
}
// 一周打印完毕之后,月份加1,打印下个月的星期
date1 = date1.plusMonths(1);
i++;
// 打印完4周,i清零,周数加1,打印行尾的空格、换行,并且月份要回到第1个月
if (i == 4) {
i = 0;
k++;
System.out.println(" ");
date1 = date1.minusMonths(4);
} else {
// 不到4周,只在每周末尾打印空格
System.out.print(" ");
}
}
// 至此,4个月打印完成,由于最开始时减了3,所以这里加4,打印下4个月的日期
date = date.plusMonths(4);
} else {
// 不到4的整数倍时,月份加1,打印月份头信息
date = date.plusMonths(1);
}
}
}
最终的效果: