Java 小技巧:打印日历表并显示事件

介绍一种在控制台打印本月日历表,显示时间和在今天日期后添加的方法。实现思路很简单,就是打印前先遍历一遍内容,确定最大列宽,然后每列按最大列宽计算空填充,从而实现对齐。

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>> events = new ArrayList<>();

        //每月事件列表
        for (int i = 0; i < 12; i++) {
            //本月事件列表
            List> 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>> 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 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 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, "");
    }
}

运行效果如下:

Java 小技巧:打印日历表并显示事件_第1张图片

 

你可能感兴趣的:(Java,java,开发语言)