本文實在是旨在對Java標準庫中日期處理之晦澀不堪現狀的怒斥。在你反駁之前,請確信你瞭解過Joda(譯註1)。我們問題的引發是因為所交付的客戶不接受(因為某種原因)在其項目中使用開源的資源。
我與我的同事們最近在開發管理類庫的一個簡單的Java應用程式。昨天,我開始編寫一個用來計算到期圖書的罰金的模組,完成該模組就要算出到期日與當前日期的間隔天數。其實也就是兩個日期做下減法,可是,Java標準庫卻把這件事情搞得很複雜。
這兩個日期是儲存在Date對象中的。為了能做減法我必須要這樣做:
- 把它們轉換為Calendar對象
- 清除時間為午夜零時
- 把它們轉換為基於epoch的毫秒數值
- 毫秒數值相減
- 除以86,000,000(一天轉換為毫秒數)
下面是我寫的代碼:
private int daysBetween(Date now, Date returnDate) {
Calendar cNow = Calendar.getInstance();
Calendar cReturnDate = Calendar.getInstance();
cNow.setTime(now);
cReturnDate.setTime(returnDate);
setTimeToMidnight(cNow);
setTimeToMidnight(cReturnDate);
long todayMs = cNow.getTimeInMillis();
long returnMs = cReturnDate.getTimeInMillis();
long intervalMs = todayMs - returnMs;
return millisecondsToDays(intervalMs);
}
private int millisecondsToDays(long intervalMs) {
return (int) (intervalMs / (1000 * 86400));
}
private void setTimeToMidnight(Calendar calendar) {
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
}
很可能還有更好的方法,但這是我在昨天下午經過多次迭代之後所能想到的。可以設想一下,Java標準庫可是動用了大量的智慧與精力打造而成的,像這種日期減法的準系統想必是經過設計的。
這個問題我較早就碰到過。只不過在此前我是用其他類庫來解決的,但在目前情形下,它不得已而變成了唯一的選擇。
看著Java標準庫的Date/Calendar,倒讓我回想起了我10年前學到的一課。當時,我正在努力開發一個C++的可重用類庫。記得那時Stroustrup一言以蔽之:“唯一的可重用類庫是那些現在已經被重用了的類庫。”換句話說,如果你決定用假象現實困難的辦法來開發類庫的話,那就註定要失敗。從另一個角度說,你只能通過參與多項真實的工程,並為它們提供有效組件的方式來確保架構的成功打造。
我其實不知道Data/Calendar類庫是如何建立的,但它暴露出了假象現實困難的馬腳。而且,至少我認為它還不夠好用。
(Tim的看法)
我的記得有過這樣的說法,軟體是有用的還是廢品差別取決於開發它的人是為自己而開發還是為別人,前者創造出的必是有價值的軟體,而後者的只能是廢品。現在看來依然是經典之談。當我看到Java或MFC的日期類型庫,也或是其它的什麼庫,然後再轉而看看perl、python、ruby或甚至是C++,我都能從中看出了這應驗之道。儘管好用的東西也會慢慢的落伍,但至少它們是有用的。
譯註1,Joda,某個知名的Java開源類庫,在時間日期的處理上相比Java標準庫更加強大且意用。對此感興趣的朋友,可以在sourceforge網站找到詳細資料。
(原文連結網址:的英文blog網址: ) http://butunclebob.com/ArticleS.UncleBob.JavaDates; Robert C. Martinhttp://www.butunclebob.com/ArticleS.UncleBob
作者簡介:Robert C. Martin是Object Mentor公司總裁,物件導向設計、模式、UML、敏捷方法學和極限編程領域內的資深顧問。他不僅是Jolt獲獎圖書《敏捷式軟體開發 (Agile Software Development):原則、模式與實踐》(中文版)(《敏捷式軟體開發 (Agile Software Development)》(英文影印版))的作者,還是暢銷書Designing Object-Oriented C++ Applications Using the Booch Method的作者。Martin是Pattern Languages of Program Design 3和More C++ Gems的主編,並與James Newkirk合著了XP in Practice。他是國際程式員大會上著名的發言人,並在C++ Report雜誌擔任過4年的編輯。