天天看點

Java時間處理第三方包:Joda-TimeJoda-Time體驗

Joda-Time provides a quality replacement for the Java date and time classes.

Joda-Time is the de facto standard date and time library for Java prior to Java SE 8. Users are now asked to migrate to java.time (JSR-310).

JDK在8之前的版本,對日期時間的處理相當麻煩,有些方法設計非常反人類。而Joda-Time使用起來不僅友善,而且可讀性強。雖然JDK 8引用了新的時間處理類,而且參與設計的人也正是Joda-Time的作者,但是由于各種原因,很多項目還是使用的JDK7,使用Joda-Time還是一個不錯的選擇。

Joda-Time體驗

對比之前JDK的處理方式,使用了Joda-Time之後,代碼整個神清氣爽了很多。接下來就用一些簡單的例子來對比一下JDk和Joda-Time的的使用。

依賴

隻需要引用一個包。

<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <version>2.3</version>
</dependency>
           

建立日期

JDK的日期是Date:

Date date = new Date();
           

Joda-Time的日期是DateTime:

DateTime dateTime = new DateTime();
           

DateTime在建立的時候還可以輕松的指定特定的日期和時間:

DateTime dateTime = new DateTime(2016, 10, 01, 00, 00);
           

日期格式化

JDK使用的是SimpleDateFormat來進行日期的格式化:

Date date = new Date();
        
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateStr = sdf.format(date);
           

乍看之下用起來也不麻煩,但是SimpleDateFormat是非線程安全的。也就是說,如果在并發環境下,必須對SimpleDateFormat對象做同步處理,比如用synchronized,比如用ThreadLocal;或者每次都new一個新的SimpleDateFormat對象,缺點顯而易見,就是浪費資源。

而Joda-Time中的DateTime本身就有格式化的方法,對象直接調用即可:

DateTime dateTime = new DateTime();
String dateTimeStr = dateTime.toString("yyyy-MM-dd HH:mm:ss");
           

當然,如果要用轉換器,Joda-Time也提供了DateTimeFormatter:

DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
String dateTimeStr = dtf.print(dateTime);
           

而且DateTimeFormatter是不可變的,是以是線程安全的。

SimpleDateFormat和DateTimeFormatter也都可以将字元串轉換成日期:

String dateStr = "2016-09-22";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
    Date date = sdf.parse(dateStr);
    } catch (ParseException e) {
        e.printStackTrace();
    }
        
DateTimeFormatter dtf = DateTimeFormat.forPattern("yyyy-MM-dd");
DateTime dateTime = dtf.parseDateTime(dateStr);
           

日期計算

個人在Joda-Time使用中,最喜歡的是它的日期計算。

比如要得到40天前的日期,在JDK中,計算日期相當複雜,必須借助月曆Calendar來完成:

Date today = new Date();
Calendar calendar = Calendar.getInstance();
calendar.setTime(today); // 設定月曆
calendar.add(Calendar.DAY_OF_MONTH, -40); // 将月曆往回翻40天
Date beforeDay = calendar.getTime(); // 月曆傳回日期
           

Joda-Time中,日期自帶日期計算功能,非常直覺:

DateTime today = new DateTime();
DateTime beforeDay = today.minusDays(40);
           

如果要計算兩個日期相差的天數,使用JDK是這樣實作的:

int diffDays = (int) ((today.getTime() - beforeDay.getTime()) / (24*60*60*1000));
           

Joda-Time提供了相關的方法來處理:

int diffDays = Days.daysBetween(yesterday, today).getDays();
           

除了天數,月數、年數計算起來都非常友善,比如月數:

int diffMonths = Months.monthsBetween(yesterday, today).getMonths();
           

相容JDK日期

Joda-Time另一個使用起來非常友善的地方就是與JDK日期類的互相轉換。因為很多現成的接口可能是用JDk的日期作為入參或者出參,如果Joda-Time不能相容,那很多友善就不複存在了。

// Date to DateTime
Date date = new Date();
DateTime dateTime = new DateTime(date);
        
// DateTime to Date
Date date2 = dateTime.toDate();
        
// Calendar to DateTime
Calendar calender = Calendar.getInstance();
DateTime dateTime2 =  new DateTime(calender);
        
// DateTime to Calendar
Calendar calendar2 = dateTime.toCalendar(Locale.CHINA);