轉自:https://blog.csdn.net/sy793314598/article/details/79544796
一、java 7中的日曆類Calendar
Calendar類使用其靜態的getInstance()方法獲取一個日曆實例,該實例爲當前的時間;若是想改變時間,能夠經過其setTime方法傳入一個Date對象,便可得到Date對象所表示時間的Calendar對象java
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 }
輸出爲:url
1 傳入的日期與今年的年份差爲:12
二、java 8中的週期類Period
經過調用Period類的靜態方法between,傳入兩個待比較的LocalDate對象today與oldDate,獲得的Period的對象p中就包含了today與oldDate兩個日期相差的年、月、日信息,能夠經過p.getYears()等方法取出spa
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 }
輸出爲:.net
1 Today:2018-03-13 2 OldDate:2014-05-23 3 目標日期距離今天的時間差:3 年 9 個月 18 天
三、java 8中的Duration類
Duration與Period相對應,Period用於處理日期,而Duration計算時間差還能夠處理具體的時間,也是經過調用其靜態的between方法,該方法的簽名是between(Temporal startInclusive, Temporal endExclusive),所以能夠傳入兩個Instant的實例(Instant實現了Temporal接口),並能夠以毫秒(toMillis)、秒(getSeconds)等多種形式表示獲得的時間差code
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 }
輸出爲:orm
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
四、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 }
輸出爲:blog
開始時間:2003-05-09 結束時間:2015-01-26 兩個時間之間的天數差爲:4280
五、傳統的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 }
輸出爲:get
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 }