讀古今文學網 > 編寫高質量代碼:改善Java程序的151個建議 > 建議142:推薦使用Joda日期時間擴展包 >

建議142:推薦使用Joda日期時間擴展包

開發一個項目必然要和日期時間打交道,特別是一些全球性的項目,必須要考慮語言和時區問題,但是在JDK中,日期時間的操作比較麻煩,例如1000小時後是星期幾,倫敦時間是幾點等,這裡介紹一下通過Joda開源包來操作時間的方法,非常簡單方便。

(1)本地格式的日期時間

依據操作系統或指定的區域輸出日期或時間,例如:


//當前時間戳

DateTime dt=new DateTime();

//輸出英文星期

dt.dayOfWeek().getAsText(Locale.ENGLISH);

//本地日期格式

dt.toLocalDate();

//日期格式化

dt.toString(DateTimeFormat.forPattern("yyyy年M月d日"));


(2)日期計算

這是Joda最方便的地方,也是JDK最麻煩的地方,比如我們要計算100天後是星期幾,直接使用JDK提供的日期類會非常麻煩,使用Joda就簡單很多,例如:


//當前時間戳

DateTime dt=new DateTime();

//加100小時是星期幾

dt.plusHours(100).dayOfWeek();

//100天後的日期

dt.plusDays(100).toLocalDate();

//10年前的今天是星期幾

dt.minusYears(10).dayOfWeek().getAsText();

//離地球毀滅還有多少小時

Hours.hoursBetween(dt, new DateTime("2012-12-21")).getHours();


這裡需要注意的是,DateTime是一個不可變類型,與String非常類似,即使通過plusXXX、minusXX等方法進行操作,dt對像仍然不會變,只是新生成一個DateTime對像而已。但是,Joda也提供了一個可變類型的日期對像:MutableDateTime類,這樣,日期的加減操作就更加方便了,比如列出10年內的黑色星期五,實現代碼如下(此實現若用JDK的類來計算會異常複雜,讀者可以嘗試一下):


//當前可變時間

MutableDateTime mdt=new MutableDateTime();

//10年後的日期

DateTime destDateTime=dt.plusYears(10);

while(mdt.isBefore(destDateTime)){

//循環一次加1天

mdt.addDays(1);

//是13號,並且是星期五

if(mdt.getDayOfMonth()==13&&mdt.getDayOfWeek()==5){

//打印出10年內所有的黑色星期五

System.out.println("黑色星期五:"+mdt);

}

}


(3)時區時間

這個比較簡單實用,給定一個時區或地區代碼即可計算出該時區的時間,比如在一個全球系統中,數據庫中全部是按照標準時間來記錄的,但是在展示層要按照不同的用戶、不同的時區展現,這就涉及時區計算了,代碼如下:


//當前時間戳

DateTime dt=new DateTime();

//此時倫敦市的時間

dt.withZone(DateTimeZone.forID("Europe/London"));

//計算出標準時間

dt.withZone(DateTimeZone.UTC);


Joda還有一個優點,它可以與JDK的日期庫方便地進行轉換,可以從java.util.Date類型轉為Joda的DateTime類型,也可以從Joda的DateTime轉為java.util.Date,代碼如下:


DateTime dt=new DateTime();

//Joda的DateTime轉為JDK的Date

Date jdkDate=dt.toDate();

//JDK的Date轉為Joda的DateTime

dt=new DateTime(jdkDate);


經過這樣的轉換,Joda可以很好地與現有的日期類保持兼容,在需要複雜的日期計算時使用Joda,在需要與其他系統通信或寫到持久層中時則使用JDK的Date。Joda是一種令人驚奇的高效工具,無論是計算日期、打印日期,或是解析日期,Joda都是首選,當然日期工具類也可以選擇date4j,它也是一個不錯的開源工具,這裡就不再贅述了。