问题描述:
我们需要编写一个日历程序,这个程序将显示当前月份的日历,当前的日用一个*进行标志。想信大家都见过日历,因此,这个程序需要解决如何计算某月的天数以及一个给定日期相应的是星期几。
解决步骤:
下面看一下这个程序的关键步骤。首先,我们构造了一个日历对象,并用当前的日期和时间进行初始化。这需要用到Java中的LocalDate类。
LocalDate date = LocalDate.now();
请注意不要使用构造器来构造一个LocalDate对象。应当使用静态工厂方法(factory method)代表我们的构造器。上面的的 LocalDate.now() 便会构造一个新对象,表示构造这个对象时的日期。
然后,我们来获得当前的月和日。
int month = date.getMonthValue();
int today = date.getDayOfMonth();
接着,将date设置为这个月的第一天,并得到这一天为星期几。
date = date.minusDays(today - 1);//Set to start of month
DayOfWeek weekday = date.getDayOfWeek();
int value = weekday.getvalue();//1 = Monday,..., 7=Sunday
变量weekday设置为DayOfWeek类型的对象。我们调用这个对象的getvalue方法来获得到星期几的一个数值。这回得到一个整数,这里遵循国际惯例,即周末是一周的结尾。星期一返回1,星期二返回2......
注意,日历的第一行是缩进的,使得月份的第一天指向正确的星期几。下面的代码会打印表头和第一行的缩进。
System.out.println("Mon Tue Wed Thu Fri Sat Sun");
for(int i = 1; i < value; i++) {
System.out.print(" ");
}
现在我们来打印日历的主体。进入一个循环,其中date遍历一个月中的每一天。
每次迭代时,打印星期值。如果date是当前日期,这个日期则用一个*标记。接下来,把date推迟为下一天。如果到达新的一周的第一天,就换行打印:
while(date.getMonthValue() == month) {
System.out.printf("%3d", date.getDayOfMonth());
if(date.getDayOfMonth() == today){
System.out.print("*");
}
else {
System.out.print(" ");
}
date = date.plusDays(1);
if(date.getDayOfWeek().getValue() == 1)
System.out.println();
}
什么时候结束呢?我们不知道这个图月有几天,是31天、30天、29天还是28天。实际上,只要date还在当前月就应该继续循环。
程序清单如下:
import java.time.*;
public class CalenderTest{
public static void main(String[] args) {
LocalDate date = LocalDate.now();
int month = date.getMonthValue();
int today = date.getDayOfMonth();
date = date.minusDays(today - 1); //Set to start to month
DayOfWeek weekday = date.getDayOfWeek();
int value = weekday.getValue(); //1 = Monday, ... , 7 = Sun
System.out.println("Mon Tue Wed Thu Fri Sat Sun");
for(int i = 1; i < value; i++) {
System.out.print(" ");
}
while(date.getMonthValue() == month) {
System.out.printf("%3d", date.getDayOfMonth());
if(date.getDayOfMonth() == today){
System.out.print("*");
}
else {
System.out.print(" ");
}
date = date.plusDays(1);
if(date.getDayOfWeek().getValue() == 1)
System.out.println();
}
}
}
我们可以看到,使用LocalDate类可以轻松编写一个日历程序,能处理星期几以及各月天数不同等复杂问题。我们不需要知道这个类具体如何计算月和星期几。只需要使用这个类的接口,如plusDays和getDyaOfWeek等方法。这再一次体现里面向对象编程的优越性。
结果:
Mon Tue Wed Thu Fri Sat Sun
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15* 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30