/*把打印日历的整个工作分为两个部分,一个是打印题目包括除开日期外的所有东西,另外一个就是打印日期。
打印日期需要考虑某些功能的实现方法。一个是怎么找到一个月开始的第一天是星期几,一个是怎么确定xx年xx月有多少天。
最后为了美观需要调整空格输出的大小保证对齐。
*/
import java.util.Scanner;
public class PrintCalendar {
public static void main(String[] args) { //main主要用于控制输入
// TODO 自动生成的方法存根
Scanner input = new Scanner (System.in);
System.out.print("Enter full year (e.g. 2001) : ");
int year = input.nextInt();
System.out.print("Enter month in number between 1 to 12:");
int month = input.nextInt();
printMonth(year,month);
input.close();
}
public static void printMonth(int year,int month) {
printMonthTitle(year,month);
printMonthBody(year,month);
}
public static void printMonthTitle(int year,int month) { //打印title
System.out.println(" "+getMonthName(month)+ " "+year);
System.out.println("-------------------------------------");
System.out.println(" Sun Mon Tue Wed Thu Fri Sat ");
}
public static String getMonthName(int month) {
String monthName = " ";
switch(month) {
case 1 : monthName = "January" ;
break;
case 2 : monthName = "February" ;
break;
case 3 : monthName = "March" ;
break;
case 4 : monthName = "April" ;
break;
case 5 : monthName = "May" ;
break;
case 6 : monthName = "June" ;
break;
case 7 : monthName = "July" ;
break;
case 8 : monthName = "August" ;
break;
case 9 : monthName = "September" ;
break;
case 10 : monthName = "October" ;
break;
case 11 : monthName = "November" ;
break;
case 12 : monthName = "December" ;
break;
}
return monthName;
}
public static void printMonthBody(int year,int month) { //打印主体
int startDay = getStartDay (year,month);
int numberOfDaysInMonth = getNumberOfDaysInMonth(year,month);
int i = 0;
for(i = 0;i < startDay; i++) { //到本月的第一天之前都打印空格
System.out.print(" ");
}
for(i = 1 ; i <= numberOfDaysInMonth; i++) { //从第一天打印到本月最后一天,控制每行输出七个
System.out.printf("%5d",i);
if( (i + startDay) % 7 == 0 ) {
System.out.println();
}
}
System.out.println();
}
public static int getStartDay(int year, int month) { //计算每月的第一天
final int START_DAY_FOR_JAN_1_1800 = 3; //已知1800年的1月1日是星期三,用这个已知条件来计算以后的日子
int totalNumberOfDays = getTotalNumberOfDays(year,month);
return ((totalNumberOfDays + START_DAY_FOR_JAN_1_1800) % 7); //注意:计算的是1800。1.1到该年的该月的上一月的天数,然后对7取余数才是占用了下一个月的几个空,在下一个空就是该月份的第一天
}
public static int getTotalNumberOfDays(int year,int month) { //计算总的天数,先计算年,在计算月,计算年的时候分平年闰年,计算月份分大月小月和二月
int total = 0;
for(int i= 1800 ;i<year;i++) {
if(isLeapYear(i))
total=total+366;
else
total=total+365;
}
for(int i = 1; i < month ; i++) {
total = total + getNumberOfDaysInMonth(year,i);
}
return total;
}
public static int getNumberOfDaysInMonth(int year,int month) {
if(month == 1 || month == 3 || month == 5 || month == 7 || month == 8
|| month == 10 || month == 12)
return 31;
else if(month == 2)
return isLeapYear(year) ? 29 : 28;
else
return 30;
}
public static boolean isLeapYear (int year) {
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0 );
}
}
这个日历是从1800.1.1开始算的天数,不支持打印1800.1.1之前的日历