用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);
}
}
}
最终的效果:
JAN FEB MAR APR
Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun
1 2 3 1 2 3 4 5 6 7 1 2 3 4 5 6 7 1 2 3 4
4 5 6 7 8 9 10 8 9 10 11 12 13 14 8 9 10 11 12 13 14 5 6 7 8 9 10 11
11 12 13 14 15 16* 17 15 16 17 18 19 20 21 15 16 17 18 19 20 21 12 13 14 15 16 17 18
18 19 20 21 22 23 24 22 23 24 25 26 27 28 22 23 24 25 26 27 28 19 20 21 22 23 24 25
25 26 27 28 29 30 31 29 30 31 26 27 28 29 30
MAY JUN JUL AUG
Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun
1 2 1 2 3 4 5 6 1 2 3 4 1
3 4 5 6 7 8 9 7 8 9 10 11 12 13 5 6 7 8 9 10 11 2 3 4 5 6 7 8
10 11 12 13 14 15 16 14 15 16 17 18 19 20 12 13 14 15 16 17 18 9 10 11 12 13 14 15
17 18 19 20 21 22 23 21 22 23 24 25 26 27 19 20 21 22 23 24 25 16 17 18 19 20 21 22
24 25 26 27 28 29 30 28 29 30 26 27 28 29 30 31 23 24 25 26 27 28 29
31 30 31
SEP OCT NOV DEC
Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun Mon Tue Wed Thu Fri Sat Sun
1 2 3 4 5 1 2 3 1 2 3 4 5 6 7 1 2 3 4 5
6 7 8 9 10 11 12 4 5 6 7 8 9 10 8 9 10 11 12 13 14 6 7 8 9 10 11 12
13 14 15 16 17 18 19 11 12 13 14 15 16 17 15 16 17 18 19 20 21 13 14 15 16 17 18 19
20 21 22 23 24 25 26 18 19 20 21 22 23 24 22 23 24 25 26 27 28 20 21 22 23 24 25 26
27 28 29 30 25 26 27 28 29 30 31 29 30 27 28 29 30 31