先看实现效果:
其实最难的就是如何确定这个月份的第一天是星期几(即最开始打印的空白)。
那么如何确定当前月份的第一天是星期几呢?
首先,我们需要知道,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);
}
}
}