打印万年历,你会吗?

打印万年历,你会吗?啊,不会!那就跟我一起使用Java在控制台上打印一个简单的万年历吧!

这个万年历怎么样,漂亮吧!

你该不会天真的认为这是从控制台上打印出来吧?要是你真这么想,我可被你的天真打败了!

要用Java实现这个万年历不是不可能,你还得会Java的swing图形用户界面开发。

我们还是来看看Java在控制台上打印的万年历长啥样?

第一反应是不是好丑呀?别看它长得丑,这可是货真价实的万年历。

软件开发其实就好比一个人,最重要的是内涵(功能),而不是外表(界面)(其实外表也很重要)。这个万年历就很有内涵。不信,我们就一起来看一看如何实现万年历吧。

初学编程的同学在写代码时,习惯还没想好就开始写代码,写的过程中有问题又反复修改。如果是语文考试作文,恐怕你的作文最终已经改得面目全非,惨不忍睹。所以,这是一个非常不好的编程习惯。

好的编程习惯是解决问题前一定要先分析问题,把大问题逐步分成小问题,理清逻辑,自下而上,逐步实现。

其实,一句话就是先想好再动手。


问题分析
  1. 首先1970年是Unix系统诞生的时间,1970年就成为Unix的元年,1970年1月1号是星期四,现在大多的手机的日历功能只能显示到1970年1月1日这一天。不信,现在赶紧掏出手机看一看。那最大可以显示哪一年呢?我的手机显示的是2037年,你的呢?

  2. 要想打印某年某月的日历,逐步分成小问题如下:

    1> 计算出本月的总天数 (注意:考虑闰年问题

    2> 计算出本月的1号是星期几(其他号数对应的星期几就可以以此类推

  3. 打印万年历格式

    1>打印标题格式

    2>打印内容格式

代码实现

问题分析得差不多了,心里应该大致知道要实现哪些小功能,接着就一步步编写代码。

Java的JDK帮助文档中,有一个专门日历类-Calender。这个类封装了很多方法用于计算日历,我们正好使用它来完成万年历的开发。

下面写一个Calender简单小例子:

1
2
3
4
5
6
7
8
public static void main(String[] args) {
Calendar nowc = Calendar.getInstance();
System.out.println(nowc.get(Calendar.YEAR)); // 当前年份
System.out.println(nowc.get(Calendar.MONTH));// 当前月份(从0开始)
System.out.println(nowc.get(Calendar.DAY_OF_MONTH)); // 当前日期
System.out.println(nowc.get(Calendar.DAY_OF_WEEK));
//当前星期几(从1表示星期日开始)
}

输出结果如下(2017年6月9日 星期五):

2017

5

9

6

Calendar类在实现万年历中的具体使用,我们通过代码进行说明,方法的使用有不清楚的地方可以自行查看JDK帮助文档。

  • 判断是否闰年方法
1
2
3
4
5
6
7
// 判断闰年(年份能被400整除或能被4整除同时不能被100整除)
public static boolean isLeap(int year) {
if ((year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0))){
return true;
}
return false;
}
  • 计算本月天数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 计算本月天数
public static int getDays(int year,int month) {
int days = 0;
if (month == 1 || month == 3 || month == 5 || month == 7 ||
month == 8 || month == 10 || month == 12) {
days = 31;
} else if (month == 4 || month == 6 || month == 9 || month == 11) {
days = 30;
} else {
if (isLeap(year)) { //判断是否闰年
days = 28;
} else {
days = 29;
}
}
return days;
}
  • 计算本月第一天星期几
1
2
3
4
5
6
7
8
9
// 计算本月一号星期数
public static int getfirstWeek(int year,int month) {
Calendar calendar = Calendar.getInstance();
calendar.set(year, month-1,1); //设置日期为本月一号
int week = calendar.get(Calendar.DAY_OF_WEEK)-1;
return week;
}
  • 打印标题
1
2
3
4
5
6
7
8
9
10
11
// 打印标题
public static void printTitle(int year, int month) {
System.out.printf("%32s\n", year + " 年 " + month + " 月 ");
System.out.println("----------------------------------------------");
String[] weeks = { "星期日", "星期一", "星期二", "星期三",
"星期四", "星期五", "星期六" };
for (int index = 0; index < weeks.length; ++index) {
System.out.printf("%-15s", weeks[index]);
}
System.out.println();
}
  • 打印内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 打印内容
public static void printBody(int year,int month) {
int week = getfirstWeek(year, month);
for (int index = 0; index < week; ++index) {
String blank = " ";// 空字符串占位
System.out.printf("%-8s", blank);
}
int days = getDays(year, month);
for (int index = week+1,day = 1;
index < days + week+1;
++index,day++) {
if (index % 7 == 0) {
System.out.printf("%-8d\n",day); //换行
} else {
System.out.printf("%-8d",day);
}
}
}
  • 打印万年历
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//打印万年历
public static void main(String[] args) {
// 控制台输入年份和月份
Scanner input = new Scanner(System.in);
System.out.println("请输入年份:");
int year = input.nextInt();
System.out.println("请输入月份:");
int month = input.nextInt();
// 打印标题
printTitle(year, month);
// 打印内容
printBody(year, month);
}

总结

你现在觉得打印这个简单的万年历其实并不简单,很有内涵了吧?涉及很多编程的细节和小问题的处理。是不是感觉一下子脑袋又不够用了?

还等什么,现在就跟着上面的代码,自己再敲一遍。边敲那思考,直到自己搞明白为此。