Java打印万年历 两种实现方法

先看实现效果:
在这里插入图片描述
其实最难的就是如何确定这个月份的第一天是星期几(即最开始打印的空白)。

那么如何确定当前月份的第一天是星期几呢?
首先,我们需要知道,1900年的1月1号是星期一。

然后就好办了,比如我们要打印2020年5月的日历,先算出1900-01-01到2020-05-01的前一天一共有几天,然后让它模7,得出的余数是几,刚好就是星期几。

普通实现

如果是普通实现,不使用提供好的日期类,就需要自己判断是否是闰年,如果是闰年则366天,2月29天。

import java.util.Scanner;

public class PermCalendar {
    public static void main(String[] args) {
        //接收输入
        Scanner input = new Scanner(System.in);
        System.out.println("输入年月:(形如2020-02)");
        String str = input.nextLine();
        String[] splitArr = str.split("-");
        int year = Integer.parseInt(splitArr[0]);
        int month = Integer.parseInt(splitArr[1]);

        int yearDays = getYearDays(year);
        int monthDays = getMonthDays(year,month);
        //给定月份的第一天是星期几(yearDays和monthDays都是为了获取 startWeek)
        int startWeek = (yearDays+monthDays+1)%7;
        //输出日历
        printMonth(year,month,startWeek);

    }
    //例如 :给定一个2020年,返回1900年到2019年 的总天数
    public static int getYearDays(int year){
        int sum = 0;
        for(int i = 1900;i<year;i++){
            //判断是否是闰年
            /**
             * 普通闰年:公历年份是4的倍数的,且不是100的倍数,为普通闰年。(如2004年就是闰年);
             * 世纪闰年:公历年份是整百数的,必须是400的倍数才是世纪闰年(如1900年不是世纪闰年,2000年是世纪闰年)
             */
            boolean isLeapYear = (i % 400 ==0) || (i %4 == 0 && i % 100!=0);
            sum+=isLeapYear ? 366 :355;

        }
        return sum;
    }
    //获取一年中给定月份的前一个月距离这一年的第一天过去了多少天
    public static int getMonthDays(int year,int month){
        int sum = 0;
        for(int i = 1;i<month;i++){
            sum+=getDays(year,i);
        }
        return sum;
    }
    //给定一个年份,给定一个月份,返回这个月有多少天
    public static int getDays(int year,int month){
        boolean isLeapYear = (year % 400 ==0) || (year %4 == 0 && year % 100!=0);
        switch (month){
            case 2:
                return isLeapYear?29:28;
            case 4:
            case 6:
            case 9:
            case 11:
                return 30;
            default:
                return 31;
        }
    }
    public static void printMonth(int year,int month,int startWeek){
        //先打印表头
        System.out.println("星期日\t星期一\t星期二\t星期三\t星期四\t星期五\t星期六");
        //打印空白
        int count = 0;//计数器,判断什么时候该换行
        for(int i = 0;i<startWeek;i++){
            System.out.print("\t\t");
            count++;
        }
        //打印日期
        int days = getDays(year,month);
        for (int i = 1;i<=days;i++){
            System.out.print(i+"\t\t");
            count++;
            if(count %7 == 0){
                System.out.println();
            }
        }
    }
}

使用LocalDate实现

import java.time.LocalDate;
import java.util.Scanner;

public class NewCalendar {
    public static void main(String[] args) {
        //接收输入
        Scanner input = new Scanner(System.in);
        System.out.println("输入年月:(形如2020-02)");
        String str = input.nextLine();
        String[] splitArr = str.split("-");
        int year = Integer.parseInt(splitArr[0]);
        int month = Integer.parseInt(splitArr[1]);

        LocalDate date = LocalDate.of(year,month,1);
        printMonth(date);
    }
    public static void printMonth(LocalDate date){
        //星期表头
        String [] weeks = {"日","一","二","三","四","五","六"};
        //itar   自动生成循环
        for (int i = 0; i < weeks.length; i++) {
            //printf格式化输出
            System.out.printf("%s"+ (i!=6? "\t" : "\n"),weeks[i]);
        }
        //打印空格
        int startWeek = date.getDayOfWeek().getValue();//对应的星期数
        for (int i = 0; i < startWeek; i++) {
            System.out.print("\t");
        }
        //打印日期
        int month = date.getMonthValue();
        //使用循环,不断增加一天,知道月份增加到了下个月
        while (date.getMonthValue() == month){
            System.out.printf("%d" + (date.getDayOfWeek().getValue() != 6? "\t" : "\n"),date.getDayOfMonth());
            date = date.plusDays(1);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_43598138/article/details/105972045