Java8之前的時間庫中存在一些設計不好的地方,導致用起來非常地不方便,又容易出錯。比如,要實現在指定的日期的基礎上面增加指定的時間的操作,你需要些大量的樣板程式碼;而它的月份從0開始,稍有不慎就會掉入坑中。所以,通常我們使用第三方庫Joda Time來進行時間相關的操作。
1、使用JodaTime
JodaTime在Github上面的主頁:JodaTime
使用JodaTime的時候的兩種配置方式:
在Maven中:
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.9.9</version>
</dependency>
複製程式碼
在Gradle中:
compile `joda-time:joda-time:2.9.9`
複製程式碼
2、獲取DateTime例項
當使用JodaTime的時候,首先你要獲取一個DateTime例項,然後用它的其他方法串聯起來實現強大的功能。想要獲取一個DateTime例項,你有很多種方式。下面列出常見的幾種方式:
方式1:使用系統時間構造DateTime例項
DateTime dateTime = new DateTime();
複製程式碼
方式2:使用具體的時間構造DateTime例項,該方法有許多過載版本
DateTime dateTime1 = new DateTime(
2000, // year
1, // month
1, // day
0, // hour (midnight is zero)
0, // minute
0, // second
0 // milliseconds
);
複製程式碼
方式3:使用Calendar構造DateTime例項
DateTime dateTime2 = new DateTime(Calendar.getInstance());
複製程式碼
方式4:使用其他DateTime例項構造DateTime例項
DateTime dateTime3 = new DateTime(dateTime);
複製程式碼
方式5:使用字串構造DateTime例項
DateTime dateTime4 = new DateTime("2006-01-26T13:30:00-06:00");
DateTime dateTime5 = new DateTime("2006-01-26");
複製程式碼
3、使用DateTime的方法
DateTime中有許多的方法,這裡我們將常用的方法分成兩類。一類是在方法中返回DateTime的那種,一類是在方法中返回Property型別的那種。顯然,後面的那種繼續串聯操作的話,就需要呼叫Property的例項方法了。
這裡,我們先給出DateTime中的第一類方法。
// 指定的時間單位上面增加指定的值
DateTime dateTime0 = dateTime.plusDays(1);
System.out.println(dateTime0);
// 指定的時間單位上面減少指定的值
DateTime dateTime6 = dateTime.minusDays(1);
System.out.println(dateTime6);
// 除了增減日期還可以直接指定它的指定時間單位上面的值
DateTime dateTime7 = dateTime.withYear(2020);
System.out.println(dateTime7);
// 按照指定的格式輸出日期
System.out.println(dateTime.toString("E MM/dd/yyyy HH:mm:ss.SSS"));
複製程式碼
在上面的程式碼中,我們只給出了其中的一部分方法的例項。實際上,在DateTime內部有許多的方法,只是它們的原理基本類似。
上面的一些方法,如果涉及的時間發生了變化(具體是指時間對應的毫秒數發生了變化),就會呼叫DateTime例項的withMillis()方法。在該方法中,如果發現傳入的毫秒數與當前的毫秒數不一樣就會新建一個DateTime例項,並將其返回。所以,上面的plusDays(1)和minusDays(1)返回的DateTime實際上已經是另一個例項了。
4、使用Property的
可以通過DateTime例項的millisOfDay() dayOfYear() minuteOfDay()等一些列方法可以獲取到該DateTime的一個Property例項,然後可以通過呼叫Property的方法再獲取一個DateTime例項。也就是說,實際上呼叫DateTime的方法獲取Property例項是為了對指定的時間位置的資訊進行修改。比如,對“日”進行修改,對“年”進行修改等等。修改了之後還是要獲取一個DateTime例項,然後再繼續進行後續的操作。
實際上每次呼叫DateTime的方法獲取Property例項的時候,都會將當前的DateTime作為引數傳入。然後當呼叫了指定的方法之後又會呼叫DateTime例項的withMillis()方法判斷時間是否發生變化,如果發生了變化就建立一個新例項並返回。
下面是它的一些示例:
// 這裡先用dayOfMonth獲取一個Property例項,然後呼叫它的withMaximumValue方法
// 它的含義是指定日期的其他日期不變,月份變成最大的之後返回一個DateTime,即如果傳入的是2018年5月1日,將返回2018年5月31日,
// 年,月,秒等位置不變,日變成該月最大的。
DateTime dateTime0 = dateTime.dayOfMonth().withMaximumValue();
DateTime dateTime1 = dateTime.dayOfMonth().withMinimumValue();
複製程式碼
5、其他的靜態方法
除了上面的一些類之外,JodaTime還有許多的靜態方法供我們使用。比如:
System.out.println(Days.daysBetween(dateTime1, dateTime).getDays());
System.out.println(Months.monthsBetween(dateTime1, dateTime).getMonths());
System.out.println(Years.yearsBetween(dateTime1, dateTime).getYears());
複製程式碼
當然,這裡我們只列出了對兩個DateTime例項的“日” “月”和“年”單位的操作,還有許多類似的類可以用來對“毫秒”“秒”等操作。
結語
這裡只是通過JodaTime的一些常用的方法的例項來說明其設計的基本原理,重點在於理清其中的邏輯,明白每個被串聯的操作究竟做了什麼。
相關程式碼:Java-advanced