首先,想要输出一个月的日历,就需要知道日历的规律,从1900年1月1号是星期1,那么本月日历一号前面有几个空的呢(拿百度日历来讲,第一行依次星期一到星期日)?因为一星期是七天,所以(从1900年到本月1号之前天数的总和)再处以七得到的余数就等于每个月1号前面的空格数.
如下图,这是2022.04的日历表
先理清一下思路,我们把第一行的星期数输出,那是手拿把攥的事情;
第二行1号前面需要隔几天呢,我们第一段已经讲了,就是1900年到前一月的天数对7求余的余数.
那接下来我们主要就需要求1900年到前一个月的天数了,我们直接求不好求,可以分为年月两部分,那就设1900年到今年初的总天数为allYearDays,今年年初到本月月初,也就是到前一个月的总天数(假如本月是4月,那就是1,2,3月的总天数)为allMonthDays,设今年年份是nowYear(自己输入),本月月份是nowMonth(自己输入),本月天数是monthDays(待定,需判断)
年分为闰年和平年,所以需要判断一下,可以被4整除但不能被100整除的是闰年;还有一种是可以被400整除也是闰年.这两个条件有一个成立就是闰年,天数就是366天,否则就是平年365,
可是适用for循环和条件判断来求年allYearDays的天数:
for(int i=1900;i<newYear;i++) { if((i%4==0&&i%100!=0)||i%==400) { allYearDays+=366; } else { allYearDays+=365; } }
这样从1900年到前一年的总天数就算完了
但是判断闰年平年使用if判断有点繁琐,我们也可以适用三目运算符,如下
for(int i=1900;i<newYear;i++) { allYearDays+=(i%4==0&&i%100!0)||i%400 ? 366:365; }
同理求今年初到本月前一月的天数allMonthDays,也是两种方法:
for(int i=1;i<nowMonth;i++) { if(i=1||i=3||i=5||i=7||i=8||i=10||i=12) { allMonthDays+=31; } else if(i=2) { if((nowYear%4==0||nowYear%100!=0)||nowYear%400==0) { allMonthDays+=29; } else { allMonthDays+=28 } } else { allMonthDays+=30; } }
第二种算也是利用三目运算符
for(int i=1;i<nowMonth;i++) { if(i==1||i=3||i=5||i=7||i=8||i=10||i=12) { allMonthDays+=31; } else if(i=2) { allMonthDays+=(nowYear%4==0||nowYear%100!=0)||nowYear%400==0 ? 29:28; } else { allMonthDays+=30; } }
成功的开端是胜利的一半,上面我们算出了从1900年到今年前一年的总天数allYearDays和今年初到本月前一月的总天数allMonthDays,那就可以算余数了,设余数为remainder,
remainder=(allYearDays+allMonDays)%7;
接下来准备工作做好了,该输出第一行的星期了
System.out.println("星期一\t星期二\t星期三\t星期四\t星期五\t星期六\t星期日\n");
接下来输出这个月的天数,那输出之前我们需要判断一下这个月有几天,利用if语句,同样是两种方法:
if(nowMonth==1||nowMonth==3||nowMonth==5|| nowMonth==7||nowMonth==8||nowMonth== 10||nowMonth==12) { monthDays=31; } else if(nowMonth==2) { if((nowYear%4==0||nowYear%100!=0)||nowYear%400==0) { monthDays=29; } else { monthDays=28 } } else { monthDays=30; }
第二种:
if(nowMonth==1||nowMonth==3||nowMonth==5|| nowMonth==7||nowMonth==8||nowMonth==10||nowMonth==12) { monthDays=31; } else if(nowMonth==2) { monthDays=(nowYear%4==0||nowYear%100!=0)||nowYear%400==0 ? 29:28; } else { monthDays=30; }
接下来就是输出了,第一行已经输出了,所以先输出第二行的空格,
for(int i=1;i<=remainder;i++) { System.out.println("\t"); }
然后输出本月的日期,注意每一行到七个数就需要换行,就是空格数加上号数是七的倍数就得换行
空格数就是我们上面求的余数remainder
for(int i=1;i<=monthDays;i++) { if((i+remainder)%7==0) { System.out.println(" 打两个空格 "+i+"\t\n"); } else { System.out.print(" 打两个空格"+i+"\t"); } }
接下来就完成了,需要注意的是,小编条件有限,只能手动修改nowYear和nowMonth
import java.util.Scanner;
public class Test{
public static void main(String [] args){
System.out.println("请依次输入,你要打印的年份和月份:");
Scanner in=new Scanner(System.in);
int a=in.nextInt();
int b=in.nextInt();
/**定义需要的日期,从而实现本月的日历打印**/
int allYearDays=0;//从1900年到今年前一年的总天数
int allMonthDays=0;//从今年开始到本月前一月的总天数
int remainder=0;//从1900年到本月前一月的总天数除以7的余数
int nowYear=a;//今年的年份
int nowMonth=b;//本月的月份
int monthDays=0;//这个月的天数,需要通过判断
/**接下来首先算日历月份1号前面有几个空格,通过1900年到本
月前一月的天数总和除以7得到的余数得到,因为1900年1月一号是星期一**/
/**先算1900年到本年前一年的总天数**/
for(int i=1900;i<nowYear;i++){
allYearDays+=(i%4==0&&i%100!=0)||i%400==0 ? 366:365; //先判断是平年还是闰年,然后再加起来,利用三目运算符
}
/**然后算出今年初到本月前一月的总天数**/
for(int i=1;i<nowMonth;i++){
if(i==1||i==3||i==5||i==7||i==8||i==10||i==12){
allMonthDays+=31;
}else if(i==2){
allMonthDays+=(nowYear%4==0&&nowYear%100!=0)||nowYear%400==0 ? 29:28;//判断平年还是闰年的二月
}else {
allMonthDays+=30;
}
}
/**现在总天数算完了,该算每个月前面的空格数了,就等于总天数除以7的余数**/
remainder=(allYearDays+allMonthDays)%7;
/**接下来先输出每个月份上面的星期数,注意每个汉字是一个字符,一个制表符占四个字符位置需要对应**/
System.out.println("星期一\t星期二\t星期三\t星期四\t星期五\t星期六\t星期日\n");
/**下面就开始输入一号前面的空格了**/
for(int i=1;i<=remainder;i++){
System.out.print("\t");
}
/**接下来开始输入日期,每七个换一个行.但是还需要判断一下本月有几天**/
if(nowMonth==1||nowMonth==3||nowMonth==5||nowMonth==7||nowMonth==8||nowMonth==10||nowMonth==12){
monthDays=31;
}else if(nowMonth==2){
monthDays=(nowYear%4==0&&nowYear%100!=0)||nowYear%400==0 ? 29:28;
}else {
monthDays=30;
}
/**下面不卖关子了,开始输出月份的号,同时需要判断到一行七个数,需要ヾ(@^▽^@)ノ换行,需要注意可以添加一些空格使号和星期对齐*/
for(int i=1;i<=monthDays;i++){
if((i+remainder)%7==0){ //如果加上空格是七的倍数,那输出完这个字符就换行了
System.out.println(" "+i+"\t\n");
}else{
System.out.print(" "+i+"\t"); //否则就直接输出
}
}
}
}