轉自: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 }