前言
在我们完成这个日历设计前,需要了解Java中的预定义类LocalDate
的一些用法
语法
LocalDate.now() // 2022-07-01
会构造一个新对象,表示构造这个对象时的日期。
LocalDate.of(1999, 1, 1)
可以提供年、月和日来构造对应一个特定日期的对象:
当然,通常我们都希望将构造的对象保存在一个对象变量中:
LocalDate newYearsEve = LocalDate.of(1999, 1, 1);
当有了一个LocalDate
对象,可以用方法getYear
、getMonthValue
和getDayOfMonth
得到年、月和日:
int year = newYearsEve.getYear(); // 1999 int month = newYearsEve.getMonthValue(); // 1 int day = newYeaersEve.getDayOfMonth(); // 1
上面的方法看起来没什么意义,因为这正是构造对象时使用的那些值。不过,有时可能有一个计算得到的日期,然后你希望调用这些方法来了解它的更多信息。例如,plusDays
方法会得到一个新的LocalDate
,如果把应用这个方法的对象称为当前对象,这个新日期对象则是距当前对象指定天数的一个新日期:
LocalDate aThousandDaysLater = newYearsEve.plusDays(1000); year = aThousandDaysLater.getYear(); // 2002 month = aThousandDaysLater.getMonthValue(); // 09 day = aThousandDaysLater.getDayOfMonth(); // 26
aThousandDaysLater
是在原来的日期上加了1000天,这时使用上面的方法就有效了
日历实战
需求:使用LocalDate
类展示当前月的日历,格式如下:
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 31
当前日期使用*
号标记。可以看到,这个程序需要知道如何计算某月份的天数以及一个给定日期相应是星期几。
步骤分解
①先构造一个对象,并用当前的日期初始化
`LocalDate date = LocalDate.now();`
②获取当前的月份和日期
int month = date.getMonthValue(); int today = date.getDayOfMonth();
③将date设置为这个月的第一天,并得到这一天为星期几
date = date.minusDays(today - 1); // 设置为当月的第一天 DayOfWeek weekday = date.getDayOfWeek(); int value = weekday.getValue(); // 1 = Monday 7 = Sunday
变量weekday
设置为DayOfWeek
类型的对象。我们调用这个对象的getValue
方法来得到星期几的一个数值。我们会得到一个整数。星期一就返回1,星期二就返回2,依次类推,星期日就返回7.
④由于日历的第一行是缩进的,这样可使月份的第一天指向相应的星期几。下面代码会打印表头和第一行的缩进
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(); }
⑥什么时候结束呢?我们不知道这个月有几天,是28、29、30还是31。实际上,只要date还在当月就要继续迭代
完整代码
import java.time.DayOfWeek; import java.time.LocalDate; /** * @author JKC * @Description: * @date 2022/7/1 10:53 */ public class 制作日历 { public static void main(String[] args) { // 创建一个日期对象,并进行初始化 LocalDate date = LocalDate.now(); System.out.println(date); // 获取当前月份和日期 int month = date.getMonthValue(); int today = date.getDayOfMonth(); // 将date设置为这个月的第一天,并得到这一天为星期几 date = date.minusDays(today - 1); // 设置为DayOfWeek类型的对象。调用这个对象的getValue方法来得到星期几的一个数值 DayOfWeek weekday = date.getDayOfWeek(); int value = weekday.getValue(); // 1 = Monday 7 = Sunday 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(); } if (date.getDayOfWeek().getValue() != 1) System.out.println(); } }
结论
上面的示例程序的重点是展示如何使用一个类的接口完成相当复杂的任务,而无须了解实现细节
LocalDate API
static LocalDate now() 构造一个表示当前日期的对象 static LocalDate of(int year, int month, int day) 构造一个表示给定日期的对象 int getYear() int getMonthValue() int getDayOfMonth() 得到当前日期的年、月和日。 DayOfWeek getDayOfWeek 得到当前日期是星期几,作为DayOfWeek类的一个实例返回。调用getValue来得到1~7之间的一个数,表示这是星期几,1表示星期一,7表示星期日 LocalDate plusDays(int n) LocalDate minusDays(int n) 生成当前日期之后或之前n天的日期