1. 程式人生 > >Java開發筆記(四十二)日曆工具的常見應用

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方法轉換日期型別和日曆型別的程式碼例子:
// 把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方法,該方法可返回毫秒計量的時間總數,只要把兩個日曆例項的時間總數相減,再把二者的差額從毫秒單位換算成以天為單位,即可求得這兩個日曆時間之間的天數。據此編寫的計算方法程式碼如下所示:
// 計算兩個日曆例項間隔的天數
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)/(100060

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,則該方法的返回值就為當月的最後一天。於是獲取月末日子的程式碼僅需下列一行而已:

// 獲取當月的最後一天
int lastDay = calendar.getActualMaximum(Calendar.DATE);

這下月曆具備的所有要素都集齊了,包括當前年份、當前月份、當月1號、當月最後一天,再把中間的日子分星期依次排列,一個簡潔樸素的月曆便出爐了。下面是使用日曆工具計算並列印當前月曆的程式碼例子:
// 列印當前月份的月曆
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開發筆記(序)章節目錄