前面的文章提到,Date是Java最先的日期工具,估计当时的设计师是个技术宅男,未通过充分调研就拍脑壳写下了Date的源码,形成该工具存在先天不足,好比getYear方法返回的不是纯正的公元纪年、getHours方法没法区分12小时制和24小时制等等,这很不利于Java语言的国际化。故而从JDK1.1开始,Java又提供了一个日历工具Calendar,官方建议采用Calendar替代Date,而且Date的相关get方法都被标记为Deprecated(意思是已废弃)。接下来就来看看这个全新的Calendar该当如何使用。
首先,建立日历实例调用的是getInstance方法,而非new关键字,日历实例的获取代码以下所示:html
// 建立一个日历实例 Calendar calendar = Calendar.getInstance();
其次,调用日历实例的get方法,得到指定时间单位的具体数值,例如类型Calendar.YEAR对应的是公元年份,类型Calendar.MONTH对应的是月份序号等等,以年份为例,具体的获取代码以下所示:java
// 获取日历实例中的年份 int year = calendar.get(Calendar.YEAR); System.out.println("year="+year);
从以上代码可见,此时获得的年份数值无需额外加上1900,果真比Date省事多了。不过经过Calendar获取其它时间单位仍有两点须要注意:
一、Calendar的月份依然从0开始计数,也就是说,日历工具获取的一月份数值为0,十二月份的数值为11,因而获取月份的代码须要记得加一:程序员
// 获取日历实例中的月份 int month = calendar.get(Calendar.MONTH)+1; System.out.println("month="+month);
二、原来Date的星期几从0开始计数,如今Calendar的星期几改成从1开始计数,可谓一大进步,不料它的星期仍旧以星期日打头、以星期六结尾。也就是说,日历工具获取的星期日数值为1,星期一数值为2,这样一来只好由程序员手工调整,按照国人习惯把星期一对应的数值改成一、把星期日对应的数值改成7等等。修改后的星期获取代码示例以下:工具
// 获取日历实例中的星期几 int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); dayOfWeek = dayOfWeek==1 ? 7 : dayOfWeek-1; System.out.println("dayOfWeek="+dayOfWeek);
其它的时间单位中规中矩,无需额外的处理,与Date相比,Calendar新增了类型Calendar.DAY_OF_YEAR(从年初开始数的日子),以及Calendar.MILLISECOND(秒钟后面的毫秒),另外把时钟区分为Calendar.HOUR(十二小时制的时钟数值)和Calendar.HOUR_OF_DAY(二十四小时制的时钟数值)两种类型。这些普通时间单位的获取代码以下所示:设计
// 获取日历实例中的日子 int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); System.out.println("dayOfMonth="+dayOfMonth); // 获取日历实例中从年初开始数的日子 int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR); System.out.println("dayOfYear="+dayOfYear); // 获取日历实例中的时钟(12小时制) int hour = calendar.get(Calendar.HOUR); System.out.println("hour="+hour); // 获取日历实例中的时钟(24小时制) int hourOfDay = calendar.get(Calendar.HOUR_OF_DAY); System.out.println("hourOfDay="+hourOfDay); // 获取日历实例中的分钟 int minute = calendar.get(Calendar.MINUTE); System.out.println("minute="+minute); // 获取日历实例中的秒钟 int second = calendar.get(Calendar.SECOND); System.out.println("second="+second); // 获取日历实例中的毫秒 int milliSecond = calendar.get(Calendar.MILLISECOND); System.out.println("milliSecond="+milliSecond);
再次,Calendar提供了set方法用于设置时间数值,而且重载了参数个数不一样的多种set方法,其中带三个参数的set方法支持同时设置年月日,带六个参数的set方法支持同时设置年月日、时分秒。这两种set方法的调用代码示例以下:htm
Calendar calendar = Calendar.getInstance(); // 调用带三个参数的set方法同时设置日历实例的年、月、日 calendar.set(2018, 11, 27); // 调用带六个参数的set方法同时设置日历实例的年、月、日、时、分、秒 calendar.set(2018, 11, 27, 12, 30, 40);
若是只想修改某个时间单位,则可调用带两个参数的set方法,第一个参数为单位类型包括Calendar.YEAR、Calendar.MONTH等等,第二个参数为具体的时间数值。好比如下的代码表示把某个日期改成当月1号:blog
// 带两个参数的set方法容许把某个时间单位改成指定数值 calendar.set(Calendar.DAY_OF_MONTH, 1); System.out.println("end set dayOfMonth="+calendar.get(Calendar.DAY_OF_MONTH));
注意到以上代码设置的日期是绝对值,有时候可能须要在当前日期上增增减减,也就是设置日期的相对值,此时能够联合使用get和set方法,先经过get方法得到当前的时间数值,对当前数值增减以后再传给set方法。下面的代码便演示了设置时间相对值的实现过程:开发
// 联合使用get和set方法,可对某个时间单位进行增减 int dayResult = calendar.get(Calendar.HOUR_OF_DAY) + 1; // 给当前日期加上一天 calendar.set(Calendar.HOUR_OF_DAY, dayResult); System.out.println("end set hourOfDay="+calendar.get(Calendar.HOUR_OF_DAY));
联合使用get和set方法当然实现了相对时间的修改,但是简简单单的功能还得两个步骤稍显繁琐,所以Calendar另外提供了add方法,利用add方法容许直接设置相对数值,就像下列代码示范的那样:get
// 调用add方法,直接在当前时间的基础上增长若干数值 calendar.add(Calendar.MINUTE, 10); // 给当前时间加上10分钟 System.out.println("end add minute="+calendar.get(Calendar.MINUTE));
日历工具Calendar就像它的前辈Date同样,仍然保留了与时间校验相关的几个方法,包括equals、before、after、compareTo方法等,而且它们的用法与Date类型的同名方法保持一致,这里再也不赘述,仍是直接看下面的时间比较代码好了:源码
// 比较两个日历时间的前后关系 private static void compareCalendar() { Calendar calendarOld = Calendar.getInstance(); Calendar calendarNew = Calendar.getInstance(); // 给calendarNew加上一秒 calendarNew.add(Calendar.SECOND, 1); // 比较两个时间是否相等 boolean equals = calendarOld.equals(calendarNew); System.out.println("equals="+equals); // 比较A时间是否在B时间以前 boolean before = calendarOld.before(calendarNew); System.out.println("before="+before); // 比较A时间是否在B时间以后 boolean after = calendarOld.after(calendarNew); System.out.println("after="+after); // 比较A时间与B时间的前后关系。返回-1表示A时间较早,返回0表示两个时间相等,返回1表示B时间较早 int compareResult = calendarOld.compareTo(calendarNew); System.out.println("compareResult="+compareResult); }
更多Java技术文章参见《Java开发笔记(序)章节目录》