显示日历
编写程序,提示用户输入年份和代表该年的第一天是星期几的数字,然后在控制台上显示该年的日历表。
首先考虑两个方面:
1.打印的格式以及应该注意的细节(比如需何时换行等);
2.逻辑控制部分,程序的结构是什么样的。比如怎样去封装各个方法,它们各自应该要实现怎样的功能,怎样在主方法中调用它们、它们的接口/参数列表要设计成什么样的等等。
流程图大概是这样的:
流程图画得比较简单,但主方法的框架大概就是这样的了。由于个别方法的参数列表设计上的改变,代码实现的细节可能会有不同。
现在该考虑作为主体的循环骨架上,需要装上哪些“零件”才能解决需求了。
1.判断输入的年份是平年还是闰年:
public static boolean isLeap(int year) {
if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
return true;
else
return false;
}
2.确定该年份各个月的具体天数:这个方法返回的是一个储存了各个月的天数的数组,其中的每个元素作为日历主体打印的计数器。
public static int[] makeSureDays(int year) {
int[] leapDays = {
31,29,31,30,31,30,31,31,30,31,30,31
};
int[] nonLeapDays = {
31,28,31,30,31,30,31,31,30,31,30,31
};
if(isLeap(year))
return leapDays;
else
return nonLeapDays;
}
3.打印日历的表头部分:每个月日历的头部大同小异,把打印日历头作为一个模块独立出来,程序更加简洁。
public static void printMonthTitle(int month, int year) {
String monthName = getMonthName(month);
System.out.println(" " + monthName + " " + year);
System.out.println("-----------------------------");
System.out.println(" Sun Mon Tue Wed Thu Fri Sat");
}
4.在printMonthTitle里调用了一个名为getMonthName的方法。它的功能是将每个月份由整型常量转化为字符串常量(为了简便,主方法中月份是个整型变量),实现如下:
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";
}
return monthName;
}
5.打印日历的主体部分:这部分的结构复杂些,主要是定义了一个打印的追踪track。程序通过它控制何时换行(每7天一换),并且返回表示下个月的第一天是星期几的整型值。
public static int printMonthBody(int whatDay, int month, int year) {
//whatDay is the first day of the month
int track = 0;
for(int j = 0; j < (whatDay % 7); j++) {
System.out.print(" ");
track++;
}
int[] days = makeSureDays(year);
for(int i = 1; i <= days[month - 1]; i++) {
System.out.printf("%4d", i);
track++;
if(track % 7 == 0) {
System.out.printf("\n");
}
}
System.out.printf("\n");
return (track % 7);
}
至此所有的“零件”设计完毕,主方法的结构如下:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入年份:");
int year = input.nextInt();
System.out.print("请输入这年的第一天是星期几(数字表示):");
int startDay = input.nextInt();
printMonthTitle(1, year);
int whatDay = printMonthBody(startDay, 1, year);
for(int month = 2; month <= 12; month++) {
printMonthTitle(month, year);
whatDay = printMonthBody(whatDay, month, year);
}
}
运行结果(局部):
完整代码:
import java.util.Scanner;
public class PrintCalendar {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("请输入年份:");
int year = input.nextInt();
System.out.print("请输入这年的第一天是星期几(数字表示):");
int startDay = input.nextInt();
printMonthTitle(1, year);
int whatDay = printMonthBody(startDay, 1, year);
for(int month = 2; month <= 12; month++) {
printMonthTitle(month, year);
whatDay = printMonthBody(whatDay, month, year);
}
}
public static boolean isLeap(int year) {
if((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))
return true;
else
return false;
}
public static int[] makeSureDays(int year) {
int[] leapDays = {
31,29,31,30,31,30,31,31,30,31,30,31
};
int[] nonLeapDays = {
31,28,31,30,31,30,31,31,30,31,30,31
};
if(isLeap(year))
return leapDays;
else
return nonLeapDays;
}
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";
}
return monthName;
}
public static void printMonthTitle(int month, int year) {
String monthName = getMonthName(month);
System.out.println(" " + monthName + " " + year);
System.out.println("-----------------------------");
System.out.println(" Sun Mon Tue Wed Thu Fri Sat");
}
public static int printMonthBody(int whatDay, int month, int year) {
//whatDay is the first day of the month
int track = 0;
for(int j = 0; j < (whatDay % 7); j++) {
System.out.print(" ");
track++;
}
int[] days = makeSureDays(year);
//days[month - 1]
for(int i = 1; i <= days[month - 1]; i++) {
System.out.printf("%4d", i);
track++;
if(track % 7 == 0) {
System.out.printf("\n");
}
}
System.out.printf("\n");
return (track % 7);
}
}