1. 程式人生 > >Java開發筆記(四十一)日曆工具Calendar

Java開發筆記(四十一)日曆工具Calendar

前面的文章提到,Date是Java最早的日期工具,估計當時的設計師是個技術宅男,未經過充分調研就拍腦袋寫下了Date的原始碼,造成該工具存在先天不足,比如getYear方法返回的不是純正的公元紀年、getHours方法無法區分12小時制和24小時制等等,這很不利於Java語言的國際化。故而從JDK1.1開始,Java又提供了一個日曆工具Calendar,官方建議採用Calendar替代Date,並且Date的相關get方法都被標記為Deprecated(意思是已廢棄)。接下來就來看看這個全新的Calendar該當如何使用。
首先,建立日曆例項呼叫的是getInstance方法,而非new關鍵字,日曆例項的獲取程式碼如下所示:

		// 建立一個日曆例項
		Calendar calendar = Calendar.getInstance();

 

其次,呼叫日曆例項的get方法,獲得指定時間單位的具體數值,例如型別Calendar.YEAR對應的是公元年份,型別Calendar.MONTH對應的是月份序號等等,以年份為例,具體的獲取程式碼如下所示:

		// 獲取日曆例項中的年份
		int year = calendar.get(Calendar.YEAR);
		System.out.println("year="+year);

 

從以上程式碼可見,此時得到的年份數值無需額外加上1900,果然比Date省事多了。不過通過Calendar獲取其它時間單位仍有兩點需要注意:
1、Calendar的月份依然從0開始計數,也就是說,日曆工具獲取的一月份數值為0,十二月份的數值為11,於是獲取月份的程式碼需要記得加一:

		// 獲取日曆例項中的月份
		int month = calendar.get(Calendar.MONTH)+1;
		System.out.println("month="+month);

 

2、原來Date的星期幾從0開始計數,現在Calendar的星期幾改為從1開始計數,可謂一大進步,不料它的星期仍舊以星期日打頭、以星期六結尾。也就是說,日曆工具獲取的星期日數值為1,星期一數值為2,這樣一來只好由程式設計師手工調整,按照國人習慣把星期一對應的數值改為1、把星期日對應的數值改為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方法的呼叫程式碼示例如下:

		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號:

		// 帶兩個引數的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方法允許直接設定相對數值,就像下列程式碼示範的那樣:

		// 呼叫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開發筆記(序)章節目錄