编写日历
打印一个月份的日历的难点在于得找准这个月的第一天所对应的星期数。要想解决这个问题有一个好方法就是找出一年一月一号对应的是星期一,这样所求月份的第一天星期数=(这一年至所输年份间的总天数+所输年份的1月至所输月份间的总天数+1)%7。那我找的这一年呢就是1900年,别问我为什么能找到,问就是老师教的。
import java.util.Scanner;
public class Calendar {
public static void main(String[] args) {
//输入年份以及月份
//计算1900年至所输年份间的总天数
//判断平年闰年
Scanner scanner=new Scanner(System.in);
System.out.println("输入一个年份:");
int year=scanner.nextInt();
int yearTotalDays = 0;
for(int i=1900;i<year;i++) {
if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0) {
yearTotalDays += 366;
} else {
yearTotalDays += 365;
}
}
//计算所输年份的一月至所输月份间的总天数
System.out.println("输入一个月份:");
int month=scanner.nextInt();
int monthTotalDays=0;
int days=0;
for(int m=1;m<=month;m++){
//这里的m要取等号并不是计算的时候要用到,而是下面打印所输月份时避免再次考虑该月份有多少天
//判断每个月的天数(大月、小月、二月(还要判断是平年还是闰年))
switch(m){
case 2:
//判断所输的年份是否是闰年
if(year%4 == 0 && year%100 != 0 || year%400 == 0){
days = 29;
}else{
days = 28;
}
break;
//小月
case 4:
case 6:
case 9:
case 11:
days=30;
break;
//大月
default:
days=31;
}
//累加每个月的总天数
if(m<month){
monthTotalDays+=days;
}
}
//计算所输月份第一天的星期数
int week=(yearTotalDays+monthTotalDays+1)%7;
//因为星期天的值是0,为了控制一号打印的位置,需将星期日设为7
if(week==0){
week=7;
}
System.out.println("一\t二\t三\t四\t五\t六\t七");
//控制打印的间距
for(int b=1;b<week;b++){
System.out.print("\t");
}
//打印当月的每一天
for(int d=1;d<=days;d++) {
System.out.print(d+"\t");
//判断每一天是否是星期天
if ((yearTotalDays + monthTotalDays + d) % 7 == 0) {
//换行
System.out.println();
}
}
}
}
总结自己犯的错误:
1.我犯的第一个错误呢就是在计算跨年的天数的时候,if的条件本应该是判断1900年至所输年份之间年份的平年还是闰年,我却判断成了所输年份是平年还是闰年。
2.第二个问题是计算所输年份的一月至所输月份之间的总天数,其实这里也还好,就是二月的时候要判断一下所输年份是平年还是闰年,然后把从1月到所输月份之间的天数加起来,麻烦的是在打印所输月份的日历时还需要次再判断该月的天数,老师给出了优化方法,就是在计算所输年份的一月至所输月份之间的总天数时将所输入的月份也包含进去,但是计算天数的时候只计算一月至所输月份之间的总天数,在switch语句中用声明的变量days存储最后一个月的天数,这个天数也就所输入的天数。
3.第三个难题是格式问题,找准了1号所对应的星期数,那么怎么将他们对齐呢?首先将第一排的星期数打印好,每个星期数之间用\t隔开;再用一个循环语句,在1号所对应的星期数前面输入\t,例如该月份的1号对应星期三,那么当i<3,也即在i=1和i=2时需要输入\t。