简易日历制作
记录一下Java实现的一个日历小程序,效果图如下:
实现以上的效果,我们需要用到两个类:SimpleDateFormat和Calendar。
首先看看这两个类的用法:
类 SimpleDateFormat
SimpleDateFormat
是一个以与语言环境有关的方式来格式化和解析日期的具体类。它允许进行格式化(日期(Date) -> 文本(String))、解析(文本(String) -> 日期(Date))和规范化。
具体要用到的方法
SimpleDateFormat(String pattern) 用给定的模式和默认语言环境的日期格式符号构造
SimpleDateFormat
。Date parse(String source) 从给定字符串的开始解析文本以生成日期。
这里我们使用SimpleDateFormat生成一个格式为“yyyy-MM”的实例,并通过parse方法将我们输入的字符串转换成日期(Date)对象。具体实现如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM"); //生成格式化实例 System.out.print("请输入要查询的月份(yyyy-MM):"); String str = scanner.next(); //获取输入字符串 Date date = null; //要获取的Date对象变量 try { date = sdf.parse(str); //将字符串转成日期对象,这里会抛出格式转换异常,需要用try..catch进行处理 } catch (Exception e) { System.out.println("时间格式不正确"); }
类 Calendar
Calendar
类是一个抽象类,它为特定瞬间与一组诸如 YEAR(年)
、MONTH(月)
、Date(日)
等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。
日历类使我们更好的对时间进行操作,使我们可以轻易获取到具体的某个时间字段,并能对时间字段进行增、减、设置等操作。
日历类是一个抽象类,所以我们不能对其进行实例化,但该类提供了一个静态方法getInstance,所以我们可以通过该方法来获取一个Calendar的对象实例。
我们的目的是做一个日历,而日历最重要的是获取当月第一天是星期几以及获取该月的最大天数,Calendar都为我们提供了具体的方法来实现。
要用到的方法
Calendar getInstance() 使用默认时区和语言环境获得一个日历。
void setTime(Date date) 使用给定的
Date
设置此 Calendar 的时间。int get(int field) 返回给定日历字段的值。
int getActualMaximum(int field) 根据当前Calendar设置的时间来获取指定字段的最大值。
我们需要用getInstance方法来获取Calendar实例,并通过上面SimpleDateFormat中字符串转成的Date对象来给我们的Calendar设置时间,最后通过get方法来获取当月第一天是星期几,并通过getActualMaximum方法来获得当月天数。
注意的几点:
- Calendar获取的MONTH是从0开始,最大为11
- Calendar获取的DAY_OF_WEEK为从1开始,最大为7,且1代表的是星期天,2~7代表是星期一到星期六
具体实现如下:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
Calendar calendar = Calendar.getInstance(); //获取Calendar对象 calendar.setTime(date); //给Calendar对象设置时间 int year = calendar.get(calendar.YEAR); //获取所设置的年份 int month = calendar.get(calendar.MONTH); //获取所设置的月 System.out.println("===================="+year+"年"+(month+1)+"月======================");
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
c.set(c.DATE, 1); int []dayOfWeek = {7,1,2,3,4,5,6}; int weekDay = c.get(c.DAY_OF_WEEK); int firstWeekDay = dayOfWeek[weekDay-1];
接下来我们要开始打印日期了,由于我们的日期是从1开始显示,一直到当月的最大一天,但我们显示的位置要和星期相对应,所以在这里我把日期(day)开始设置为“-firstWeekDay+1”,来填充前面所需要的空白。
我们还会涉及一个换行的问题,正常逻辑是每7天换行一次,而我们的日期是从“-firstWeekDay+1”开始的,所以我们在计算换行时需要再将其加上。具体实现见代码吧。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
int day = -firstWeekDay+1; //第一天 for (;day<=c.getActualMaximum(c.DATE); day++) { if(day<=0) { System.out.print("\t"); //day从1开始显示 } else { System.out.print(day+"\t"); } if((day+firstWeekDay-1)%7 == 0){ //每计7天换行一次 System.out.println(); } }
这样,我们的日历就完成啦。不过这里还有别的一些问题,比如我们在捕获格式转换异常时,如果程序继续往下执行,则可能会发生空指针异常,不过再添加一个异常捕获就好了。