java計算時間差, 日期差小結


轉自:https://blog.csdn.net/sy793314598/article/details/79544796

1、java 7中的日歷類Calendar

Calendar類使用其靜態的getInstance()方法獲取一個日歷實例,該實例為當前的時間;如果想改變時間,可以通過其setTime方法傳入一個Date對象,即可獲得Date對象所表示時間的Calendar對象

 1 /**
 2  *使用Calendar對象計算時間差,可以按照需求定制自己的計算邏輯
 3  * @param strDate
 4  * @throws ParseException
 5  */
 6 public static void calculateTimeDifferenceByCalendar(String strDate) throws ParseException {
 7     SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
 8     Date date = formatter.parse(strDate);
 9 
10     Calendar c1 = Calendar.getInstance();   //當前日期
11     Calendar c2 = Calendar.getInstance();
12     c2.setTime(date);   //設置為另一個時間
13 
14     int year = c1.get(Calendar.YEAR);
15     int oldYear = c2.get(Calendar.YEAR);
16 
17     //這里只是簡單的對兩個年份數字進行相減,而沒有考慮月份的情況
18     System.out.println("傳入的日期與今年的年份差為:" + (year - oldYear));
19 }

輸出為:

1 傳入的日期與今年的年份差為:12

2、java 8中的周期類Period

通過調用Period類的靜態方法between,傳入兩個待比較的LocalDate對象today與oldDate,得到的Period的對象p中就包含了today與oldDate兩個日期相差的年、月、日信息,可以通過p.getYears()等方法取出

 1 /**
 2  * 使用java 8的Period的對象計算兩個LocalDate對象的時間差,嚴格按照年、月、日計算,如:2018-03-12 與 2014-05-23 相差 3 年 9 個月 17 天
 3  * @param year
 4  * @param month
 5  * @param dayOfMonth
 6  */
 7 public static void calculateTimeDifferenceByPeriod(int year, Month month, int dayOfMonth) {
 8     LocalDate today = LocalDate.now();
 9     System.out.println("Today:" + today);
10     LocalDate oldDate = LocalDate.of(year, month, dayOfMonth);
11     System.out.println("OldDate:" + oldDate);
12 
13     Period p = Period.between(oldDate, today);
14     System.out.printf("目標日期距離今天的時間差:%d 年 %d 個月 %d 天\n", p.getYears(), p.getMonths(), p.getDays());
15 }

輸出為:

1 Today:2018-03-13
2 OldDate:2014-05-23
3 目標日期距離今天的時間差:3 年 9 個月 18 天

3、java 8中的Duration類

Duration與Period相對應,Period用於處理日期,而Duration計算時間差還可以處理具體的時間,也是通過調用其靜態的between方法,該方法的簽名是between(Temporal startInclusive, Temporal endExclusive),因此可以傳入兩個Instant的實例(Instant實現了Temporal接口),並可以以毫秒(toMillis)、秒(getSeconds)等多種形式表示得到的時間差

 1 public static void calculateTimeDifferenceByDuration() {
 2     Instant inst1 = Instant.now();  //當前的時間
 3     System.out.println("Inst1:" + inst1);
 4     Instant inst2 = inst1.plus(Duration.ofSeconds(10));     //當前時間+10秒后的時間
 5     System.out.println("Inst2:" + inst2);
 6     Instant inst3 = inst1.plus(Duration.ofDays(125));       //當前時間+125天后的時間
 7     System.out.println("inst3:" + inst3);
 8 
 9     System.out.println("以毫秒計的時間差:" + Duration.between(inst1, inst2).toMillis());
10 
11     System.out.println("以秒計的時間差:" + Duration.between(inst1, inst3).getSeconds());
12 }

輸出為:

1 Inst1:2018-03-13T09:06:00.691Z
2 Inst2:2018-03-13T09:06:10.691Z
3 inst3:2018-07-16T09:06:00.691Z
4 以毫秒計的時間差:10000
5 以秒計的時間差:10800000

4、java 8中的ChronoUnit類

ChronoUnit的between方法簽名為,between(Temporal temporal1Inclusive, Temporal temporal2Exclusive),需要注意的是,如果要以不同的單位展示時間差,between入參中的時間對象必須包含有對應的時間信息,否則會拋出java.time.temporal.UnsupportedTemporalTypeException: Unsupported unit XXX的異常

 1 /**
 2  * 使用java 8的ChronoUnit,ChronoUnit可以以多種單位(基本涵蓋了所有的,看源碼發現竟然還有“FOREVER”這種單位。。)表示兩個時間的時間差
 3  */
 4 public static void calculateTimeDifferenceByChronoUnit() {
 5     LocalDate startDate = LocalDate.of(2003, Month.MAY, 9);
 6     System.out.println("開始時間:" + startDate);
 7 
 8     LocalDate endDate = LocalDate.of(2015, Month.JANUARY, 26);
 9     System.out.println("結束時間:" + endDate);
10 
11     long daysDiff = ChronoUnit.DAYS.between(startDate, endDate);
12     System.out.println("兩個時間之間的天數差為:" + daysDiff);
13 //  long hoursDiff = ChronoUnit.HOURS.between(startDate, endDate);  //這句會拋出異常,因為LocalDate表示的時間中不包含時分秒等信息
14 }

輸出為:

開始時間:2003-05-09
結束時間:2015-01-26
兩個時間之間的天數差為:4280

5、傳統的SimpleDateFormat類

用SimpleDateFormat計算時間差的方法,網上找了一份,自己跑了一遍,可以使用,貼在下面

 1 /**
 2 * 用SimpleDateFormat計算時間差
 3 * @throws ParseException 
 4 */
 5 public static void calculateTimeDifferenceBySimpleDateFormat() throws ParseException {
 6     SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
 7     /*天數差*/
 8     Date fromDate1 = simpleFormat.parse("2018-03-01 12:00");  
 9     Date toDate1 = simpleFormat.parse("2018-03-12 12:00");  
10     long from1 = fromDate1.getTime();  
11     long to1 = toDate1.getTime();  
12     int days = (int) ((to1 - from1) / (1000 * 60 * 60 * 24));  
13     System.out.println("兩個時間之間的天數差為:" + days);
14 
15     /*小時差*/
16     Date fromDate2 = simpleFormat.parse("2018-03-01 12:00");  
17     Date toDate2 = simpleFormat.parse("2018-03-12 12:00");  
18     long from2 = fromDate2.getTime();  
19     long to2 = toDate2.getTime();  
20     int hours = (int) ((to2 - from2) / (1000 * 60 * 60));
21     System.out.println("兩個時間之間的小時差為:" + hours);
22 
23     /*分鍾差*/
24     Date fromDate3 = simpleFormat.parse("2018-03-01 12:00");  
25     Date toDate3 = simpleFormat.parse("2018-03-12 12:00");  
26     long from3 = fromDate3.getTime();  
27     long to3 = toDate3.getTime();  
28     int minutes = (int) ((to3 - from3) / (1000 * 60));  
29     System.out.println("兩個時間之間的分鍾差為:" + minutes);
30 }

輸出為:

1 兩個時間之間的天數差為:11
2 兩個時間之間的小時差為:264
3 兩個時間之間的分鍾差為:15840

總結

傳統的SimpleDateFormat和Java 7中的Calendar在使用的時候需要自己寫一個計算時間差的邏輯,比較麻煩,但是卻比較靈活,方便根據自己具體的需求來定制(比如,我想兩個日期的天數差15天就算滿一個月,不滿15天不算一個月,如2018-01-04到2018-02-20,算2個月的時間差);而Java 8中的幾個計算時間差的類更加方便、精確,可以以不同的單位表示得到的時間差,但要注意幾個類所包含的時間信息的區別:

1 System.out.println(LocalDate.now());        //只包含日期信息
2 System.out.println(LocalTime.now());        //只包含時間信息
3 System.out.println(LocalDateTime.now());        //包含日期、時間信息

輸出為:

1 2018-03-13
2 17:13:26.134
3 2018-03-13T17:13:26.135

以上總結的幾個方法只是個例子,具體使用的時候可能需要傳入一個或者兩個時間進行比較,可能會涉及到這些時間對象的相互轉換,Instant、Date、LocalDate等等。。。我就不列舉了。。。 
另外在使用SimpleDateFormat對String類型的日期進行parse的時候,如果傳入的日期為:2017-08-60,這種錯誤的日期,Java默認會按照日期的信息對其進行轉換,formatter.parse("2017-08-60");,得到的日期為2017-09-29,而如果不想進行這種轉換,而直接將其判定為輸入錯誤,則可以設置formatter.setLenient(false);,這時就會拋出java.text.ParseException異常了

1 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
2 formatter.setLenient(false);
3 try {
4     Date date = formatter.parse("2017-08-60");  //拋出轉換異常
5     System.out.println(date);
6 } catch (ParseException e) {
7     e.printStackTrace();
8 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM