介绍一种在控制台打印本月日历表,显示时间和在今天日期后添加的方法。实现思路很简单,就是打印前先遍历一遍内容,确定最大列宽,然后每列按最大列宽计算空填充,从而实现对齐。
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
public class PrintCalendar {
public static void main(String[] args) {
//总事件列表
List<List<List<String>>> events = new ArrayList<>();
//每月事件列表
for (int i = 0; i < 12; i++) {
//本月事件列表
List<List<String>> monEvents = new ArrayList<>();
//每日事件列表
for (int j = 0; j < 31; j++) {
monEvents.add(new ArrayList<>());
}
events.add(monEvents);
}
//6月5号添加事件
events.get(5).get(5).add("hh");
printCalendar(6, events);
}
/**
* 打印日历
*
* @param month 月份
* @param events 本月事件列表
*/
public static void printCalendar(int month, List<List<List<String>>> events) {
LocalDate date = LocalDate.now().withDayOfMonth(1).withMonth(month);
DayOfWeek weekday = date.getDayOfWeek();
int firstDayOfWeek = weekday.getValue();
int daysInMonth = date.lengthOfMonth();
//查找最大列宽
int maxColWidth = 0;
ArrayList<String> columnContentList = new ArrayList<>();
LocalDate today = LocalDate.now();
boolean isCurrentMonth = today.getMonthValue() == month;
for (int j = 1; j <= daysInMonth; j++) {
//判断是否为当前日期
boolean isToday = today.getDayOfMonth() == j;
String todayStar = "";
if (isCurrentMonth && isToday) {
todayStar = "*";
}
List<String> dayEvents;
if (events.isEmpty()) {
dayEvents = new ArrayList<>();
} else {
dayEvents = events.get(month - 1).get(j - 1);
}
int colWidth;
String colContent;
if (!dayEvents.isEmpty()) {
String eventNames = String.join(",", dayEvents);
colContent = "%2d%s:%s".formatted(j, todayStar, eventNames);
colWidth = colContent.length();
} else {
colContent = "%2d%s".formatted(j, todayStar);
colWidth = colContent.length();
}
if (colWidth > maxColWidth) {
maxColWidth = colWidth;
}
columnContentList.add(colContent);
}
//左右空格填充
maxColWidth += " ".length() + maxColWidth % 2;
int rowWidth = maxColWidth * 7 + "|".length() * 8;
//打印月份
System.out.printf("%s\n", formatColumn(String.valueOf(month), rowWidth));
//打印星期
String[] header = new String[]{"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
for (int i = 0; i < rowWidth; i++) {
System.out.print("=");
}
System.out.print("\n");
for (String s : header) {
System.out.printf("|%s", formatColumn(s, maxColWidth));
}
System.out.println("|");
for (int i = 0; i < rowWidth; i++) {
System.out.print("=");
}
System.out.print("\n");
//打印开头的空格填充
for (int i = 1; i < firstDayOfWeek; i++) {
System.out.printf("|%s", formatColumn(" ", maxColWidth));
}
//打印日期
for (int j = 0; j < columnContentList.size(); j++) {
String columnContent = columnContentList.get(j);
System.out.printf("|%s", formatColumn(columnContent, maxColWidth));
if ((j + firstDayOfWeek) % 7 == 0) {
System.out.println("|");
}
}
System.out.println("|");
//打印底部横线
for (int i = 0; i < rowWidth; i++) {
System.out.print("=");
}
}
/**
* 列格式化,添加空格填充
*
* @param str 内容
* @param totalWidth 宽度
* @return String
*/
public static String formatColumn(String str, int totalWidth) {
int leftPad = (totalWidth - str.length()) / 2;
int rightPad = totalWidth - str.length() - leftPad;
return String.format("%" + leftPad + "s%s%" + rightPad + "s", "", str, "");
}
}
运行效果如下: