前面的文章提到,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開發筆記(序)章節目錄》