Java开发笔记(四十二)日历工具的常见应用
前面介绍了日历工具Calendar的基本用法,乍看起来Calendar与Date两个半斤八两,似乎没有多大区别,那又何苦庸人自扰鼓捣一个新玩意呢?显然这样小瞧了Calendar,其实它的作用大着呢,接下来不妨深入探讨一下Calendar的几种实际应用,主要包括:Calendar和Date类型互相转换、计算两个日历时间的天数、打印当前月份的月历等,分别说明如下。
1、Calendar和Date类型互相转换
虽说Date早就应该被Calendar取代,但毕竟是前辈,而且Java也一直没有抛弃它,特别有一点:Date拥有搭配的日期格式化工具SimpleDateFormat,可以很方便地输出指定格式的日期时间字符串,敢问Calendar有此绝活么?既然Calendar无法覆盖Date的所有功能,那就必须支持互相转换Calendar和Date类型,从而让日期实例去执行日历实例所不能完成的任务。因为类型转换的要求是Calendar提出来的,所以这个转换动作理应由它实现,这里用到了Calendar的getTime方法和setTime方法,其中getTime方法的返回值就是Date类型的实例,而setTime方法可将Date实例填入Calendar实例。下面是通过getTime和setTime方法转换日期类型和日历类型的代码例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | // 把Calendar类型的数据转换为Date类型 private static void convertCalendarToDate() { // 创建一个日历实例 Calendar calendar = Calendar.getInstance(); // 调用日历实例的getTime方法,获得日期信息 Date date = calendar.getTime(); System.out.println( "convertCalendarToDate date=" + date.toString() + ", calendar=" + calendar.toString()); } // 把Date类型的数据转换为Calendar类型 private static void convertDateToCalendar() { // 创建一个日历实例 Calendar calendar = Calendar.getInstance(); // 创建一个日期实例 Date date = new Date(); // 调用日历实例的setTime方法,设置日期信息 calendar.setTime(date); System.out.println( "convertDateToCalendar date=" + date.toString() + ", calendar=" + calendar.toString()); } |
2、计算两个日历时间的天数
根据两个给定的时间,计算二者间隔的天数,这个业务场景也很常见。例如为了安全起见,网站每隔若干天就要求用户重新登录;又如信用卡还款,银行需要在还款日之前多少天提醒用户等等。这时用到了Calendar的getTimeInMillis方法,该方法可返回毫秒计量的时间总数,只要把两个日历实例的时间总数相减,再把二者的差额从毫秒单位换算成以天为单位,即可求得这两个日历时间之间的天数。据此编写的计算方法代码如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | // 计算两个日历实例间隔的天数 private static void countDays() { Calendar calendarA = Calendar.getInstance(); // 设置第一个日历实例的年月日 calendarA.set( 2018 , 3 , 15 ); Calendar calendarB = Calendar.getInstance(); // 设置第二个日历实例的年月日 calendarB.set( 2018 , 9 , 15 ); // 获得第一个日历实例包含的时间总数(单位毫秒) long timeOfA = calendarA.getTimeInMillis(); // 获得第二个日历实例包含的时间总数(单位毫秒) long timeOfB = calendarB.getTimeInMillis(); // 先计算二者的差额,再把毫秒计量的差额转换为天数 long dayCount = (timeOfB-timeOfA)/( 1000 * 60 * 60 * 24 ); System.out.println( "dayCount=" +dayCount); } |
3、打印当前月份的月历
对于期待周末的学生和上班族来说,一份安排妥当的月历是必不可少的,现在利用Calendar功能便能制作一个简单的月历。月历的每行均为一个星期,行首是星期一,行尾是星期日,然后分行打印当月从1号到月末的所有日子。其中的年、月、星期都是明确的,唯有月末的日子是变化着的,比如1、3、5、7、8、10、12这七个月的月末是31号,4、6、9、11这四个月的月末是30号,2月每逢闰年有29天、其它年份则有28天。倘若为了确定当月的最后一天,就得自己编码判断这些繁复的细节,可谓是绞尽脑汁、伤筋动骨。所幸Calendar早已提供了getActualMaximum方法,该方法用于获得指定时间单位的最大合法值,如果指定的时间单位是Calendar.DATE,则该方法的返回值就为当月的最后一天。于是获取月末日子的代码仅需下列一行而已:
1 2 | // 获取当月的最后一天 int lastDay = calendar.getActualMaximum(Calendar.DATE); |
这下月历具备的所有要素都集齐了,包括当前年份、当前月份、当月1号、当月最后一天,再把中间的日子分星期依次排列,一个简洁朴素的月历便出炉了。下面是使用日历工具计算并打印当前月历的代码例子:
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 | // 打印当前月份的月历 private static void printMonthCalendar() { // 创建一个日历实例 Calendar calendar = Calendar.getInstance(); // 设置日期为当月1号 calendar.set(Calendar.DATE, 1 ); // 获得该日期对应的星期几 int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); dayOfWeek = dayOfWeek== 1 ? 7 : dayOfWeek- 1 ; // 获取当月的最后一天 int lastDay = calendar.getActualMaximum(Calendar.DATE); // 拼接月历开头的年月 String yearAndMonth = String.format( "\n %d年%d月" , calendar.get(calendar.YEAR), calendar.get(calendar.MONTH)+ 1 ); System.out.println(yearAndMonth); System.out.println( " 星期一 星期二 星期三 星期四 星期五 星期六 星期日" ); // 先补齐1号前面的空白 for ( int i= 1 ; i<dayOfWeek; i++) { System.out.print( " " ); } // 循环打印从一号到本月最后一天的日子 for ( int i= 1 ; i<=lastDay; i++) { String today = String.format( "%7d" , i); System.out.print(today); // 如果当天是星期日,末尾就另起一行 if ((dayOfWeek+i- 1 )% 7 == 0 ) { System.out.println(); } } } |
运行上述的月历代码,观察到的打印结果如下图所示。
更多Java技术文章参见《Java开发笔记(序)章节目录》
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 聊一聊 操作系统蓝屏 c0000102 的故障分析
· SQL Server 内存占用高分析
· .NET Core GC计划阶段(plan_phase)底层原理浅谈
· .NET开发智能桌面机器人:用.NET IoT库编写驱动控制两个屏幕
· 用纯.NET开发并制作一个智能桌面机器人:从.NET IoT入门开始
· 我干了两个月的大项目,开源了!
· 推荐一款非常好用的在线 SSH 管理工具
· 聊一聊 操作系统蓝屏 c0000102 的故障分析
· 千万级的大表,如何做性能调优?
· .NET周刊【1月第1期 2025-01-05】