1、傳統的日期時間類(Date和Calendar)java
1. Date類sql
這裏的Date是位於java.util包下的類,而不是java.sql包下的date類,Date對象即包含日期也包含時間,從JDK1.0就開始存在了,歷史至關悠久,所以,它的大部分構造器和方法已通過時了,不在推薦使用。安全
Date提供了6個構造器,其中4個已經Deprecated(不推薦使用了,若是繼續使用,編譯器會提出警告信息,並致使程序性能和安全性方面的問題),剩下2個構造器以下:微信
♦ Date():生成一個表明當前日期的Date對象。該構造器在底層調用System.currentTimeMillis()得到long長整數做爲日期參數。工具
♦ Date(long date):根據指定的long型整數生成一個Date對象。該構造器的參數表示建立的Date對象和GMT1970年1月1日00:00:00之間的時間差,以毫秒爲單位。性能
Date對象的大部分方法也已通過時了,僅剩下如下幾個方法:測試
♦ boolean after(Date when):測試該日期是否在指定的日期when以後。spa
♦ boolean before(Date when):測試該日期是否在指定的日期when以前。code
♦ long getTime():返回該時間對應的long 型整數,即從GMT 1970-01-01 00:00:00到該Date對象之間的時間差,以毫秒爲單位。對象
♦ void setTine(long time):設置該Date對象的時間。
Date類經常使用用法以下面程序示例:
public class DateTest { public static void main(String[] args) { Date d1 = new Date(); //獲取當前時間後的200毫秒的時間
Date d2 = new Date(System.currentTimeMillis() + 200); System.out.println(d2); System.out.println(d1.compareTo(d2)); System.out.println(d1.before(d2)); } }
運行代碼結果以下:
Fri Feb 22 21:32:14 CST 2019
-1
true
整體來講,Date類不推薦使用,若是須要獲取指定的時間或對時間進行加減運算,可以使用calendar工具類。
2. Calendar類
Calendar類自己是一個抽象類,它是全部日曆類的模板,但不能之間建立對象,但它提供了幾個靜態getInstance()方法來獲取Calendar對象。
Calendar和Date都是日期的工具類,它們之間能夠自由轉換,以下代碼所示:
Calendar cal = Calendar.getInstance(); //從Calendar對象中取出Date對象
Date date = cal.getTime(); //經過Date對象獲取對應的Calendar對象 //因爲Calendar沒有構造器接收Date對象 //因此必須先得到一個Calendar實例,而後調用其setTime()方法
Calendar cal2 = Calendar.getInstance(); cal2.setTime(date);
Calendar提供了大量的訪問、修改日期的方法,經常使用的以下:
♦ void add(int field,int amount):根據日曆的規則,爲給定的日曆字段添加或減去指定的時間量。
♦ int get(int field):返回指定日曆字段的值。
♦ int getActualMaximum(int field):返回指定的日曆字段可能擁有的最大值。例如月,最大值爲11。
♦ int getActualMinimum(int field):返回指定的日曆字段可能擁有的最小值。例如月,最小值爲0。
♦ void roll(int field,int amount):與add方法相似,區別在於加上amount後若是超過了該字段的最大範圍,也不會向上一個字段進位。
♦ void set(int field,int value):將給定的日曆字段設置爲給定值。
♦ void set(int year,int month,int date):設置Calendar對象的年、月、日3個字段的值。
♦ void set(int year,int month,int date,int hour,int minute,int second):設置Calendar對象的年、月、日、時、分、秒6個字段的值。
能夠看出上面不少方法都須要一個int類型的field參數,field時Calendar類的類變量,如Calendar.YEAR、Calendar.MONTH、Calendar.DATE等分別表明了年、月、日、時、分、秒等字段,須要注意的是Calendar.MONTH月份的起始值是0,範圍是0-11。下面程序示範了Calendar的常規用法:
public class CalendarTest { public static void main(String[] args) { Calendar cal = Calendar.getInstance(); //取出年
System.out.print("取出年:"); System.out.println(cal.get(Calendar.YEAR)); //取出月:當前月減1
System.out.print("取出月:"); System.out.println(cal.get(Calendar.MONTH)); //取出日
System.out.print("取出日:"); System.out.println(cal.get(Calendar.DATE)); //分別設置年、月、日、時、分、秒
System.out.print("設置時間:"); cal.set(2019, 02, 22, 22, 06, 34); System.out.println(cal.getTime()); //將Calendar的年前推1年
System.out.print("將Calendar的年前推1年:"); cal.add(Calendar.YEAR, -1); System.out.println(cal.getTime()); //將Calendar的月前推3個月
System.out.print("將Calendar的月前推3個月:"); cal.add(Calendar.MONTH, -3); System.out.println(cal.getTime()); } }
打印結果爲:
取出年:2019
取出月:1
取出日:22
設置時間:Fri Mar 22 22:06:34 CST 2019
將Calendar的年前推1年:Thu Mar 22 22:06:34 CST 2018
將Calendar的月前推3個月:Fri Dec 22 22:06:34 CST 2017
Calendar類須要注意的如下幾點:
♦ add與roll的區別
add(int field,int amount)方法主要用於改變Calendar的特定字段的值。若是要增長某個字段的值,則amount爲正數,若是要減小某個字段的值,則amount爲負數。此方法有以下兩條規則:
1)當被修改的字段超出它容許的範圍時,會發生進位,即上一級字段也會增大。例如:
Calendar cal = Calendar.getInstance();
cal.set(2008,7,23,0,0,0);//2008-8-23
cal.add(Calendar.MONTH,6);//2008-8-23 =>2009-2-23
2) 若是下一級字段也須要改變,則該字段會修正到變化最小的值。例如:
Calendar cal = Calendar.getInstance();
cal.set(2008,7,31,0,0,0);//2008-8-31
//由於進位後月份變爲2,而2月沒有31日,自動變成28
cal.add(Calendar.MONTH,6);//2008-8-31 =>2009-2-28
roll()的規則與add()規則處理不一樣:當被修改的字段超出它容許的範圍時,上一級字段也不會增大,即不會發生進位。例如:
Calendar cal = Calendar.getInstance();
cal.set(2008,7,23,0,0,0);//2008-8-23
cal.add(Calendar.MONTH,6);//2008-8-23 =>2008-2-23
roll()下一級字段的處理與add()相同,都會修正到該字段變化的最小值,例如:
Calendar cal = Calendar.getInstance();
cal.set(2008,7,31,0,0,0);//2008-8-31
//2月沒有31日,自動變成29,YEAR字段不會改變
cal.add(Calendar.MONTH,6);//2008-8-31 =>2008-2-29
♦ 設置Calendar的容錯性
先看以下代碼:
Calendar cal = Calendar.getInstance(); System.out.println("如今時間:"+cal.getTime()); cal.set(Calendar.MONTH, 13);//(1)
System.out.println("月份加上13後的時間"+cal.getTime()); //關閉容錯性
cal.setLenient(false); cal.set(Calendar.MONTH, 13);//(2)
System.out.println(cal.getTime());
打印結果爲:
如今時間:Sat Feb 23 22:06:13 CST 2019 月份加上13後的時間Sun Feb 23 22:06:13 CST 2020 Exception in thread "main" java.lang.IllegalArgumentException: MONTH at java.util.GregorianCalendar.computeTime(GregorianCalendar.java:2316) at java.util.Calendar.updateTime(Calendar.java:2468) at java.util.Calendar.getTimeInMillis(Calendar.java:1087) at java.util.Calendar.getTime(Calendar.java:1060) at com.bhyj.CalendarTest.main(CalendarTest.java:37)
從打印結果能夠看出:月份加上13後,代碼能正常執行,YEAR字段加1,MONTH字段爲1即2月,可是加上cal.setLenient(false);這行代碼後,代碼運行時異常,由於月份超出了最大月份。Calendar默認支持較好的容錯性,能夠關閉其容錯性,讓它進行嚴格的參數檢查。
♦ set()方法延遲修改
經過set()方法設置某一個字段的值得時候,該字段的值不會立馬修改,直到下次調用get()、getTime()等時纔會從新計算日曆的時間。延遲修改的優點是屢次調用set()方法不會觸發屢次沒必要要的計算。下面程序演示了set()方法延遲修改的效果:
Calendar cal = Calendar.getInstance(); cal.set(2003,7,31);//2003-8-31 //將月份設爲9,但9月31不存在 //若是當即修改,系統會把cal自動調整到10月1日
cal.set(Calendar.MONTH,8); //下面代碼輸出了10月1日
System.out.println(cal.getTime());//(1) //設置DATE字段爲5
cal.set(Calendar.DATE, 5);//(2)
System.out.println(cal.getTime());//(3)
打印結果爲:
Wed Oct 01 22:25:41 CST 2003
Sun Oct 05 22:25:41 CST 2003
若是將(1)處的代碼註釋掉,打印結果爲:
Fri Sep 05 22:28:06 CST 2003
你看明白了嗎?若是將(1)處的代碼註釋掉,由於set()方法具備延遲性,它內部只是先記錄下MONTH字段的值爲8,接着程序將DATE字段設置爲5,程序內部再次記錄DATE字段的值爲5——就是9月5日。
2、Java8新增的日期、時間包
爲了彌補傳統Java對日期、時間處理的不足,Java8提供了一套全新的日期時間庫。Java8專門新增了一個java.time包,該包下包含了以下經常使用類。
♦ Clock:該類用於獲取指定時區的當前日期、時間。該類能夠取代System類的currentTimeMillis()方法,該類提供了大量的方法獲取當前的日期和時間,以下圖:
程序代碼示例以下:
//獲取當前Clock
Clock clock = Clock.systemUTC(); //獲取clock對應的毫秒數 //等於System.currentTimeMillis()
System.out.println(clock.millis()); System.out.println(System.currentTimeMillis());
♦ Duration:該類表明持續時間
示例代碼以下:
Duration d = Duration.ofSeconds(600); System.out.println("600秒="+d.toMinutes()+"分"); System.out.println("600秒="+d.toHours()+"時"); System.out.println("600秒="+d.toDays()+"天");
♦ Instant:該類表明一個具體的時刻,能夠精確到納秒。該類主要提供瞭如下幾個方法:
1)now():獲取當前時刻。
2)now(Clock clock):獲取clock對應的時刻。
3)minusXxx():在當前時刻基礎上減去一段時間。
4)plusXxx():在當前時刻基礎上加上一段時間。
代碼示例以下:
//獲取當前時間
Instant instant = Instant.now(); System.out.println(instant); //instant增長600秒
Instant instant2 = instant.plusSeconds(600);
♦ LocalDate:該類表明不帶時區的日期,如:2019-02-24。該類主要提供瞭如下幾個方法:
1)now():獲取當前日期。
2)now(Clock clock):獲取clock對應的日期。
3)minusXxx():在當前年份基礎上減去幾年、幾月、幾周或幾日等。
4)plusXxx():在當前年份基礎上加上幾年、幾月、幾周或幾日等。
♦ LocalTime:該類表明不帶時區的時間,如:10:20:09。該類主要提供瞭如下幾個方法:
1)now():獲取當前時間。
2)now(Clock clock):獲取clock對應的時間。
3)minusXxx():在當前年份基礎上減去幾小時、幾分、幾秒等。
4)plusXxx():在當前年份基礎上加上幾小時、幾分、幾秒等。
♦ LocalDateTime:該類表明不帶時區的日期、時間,如:2019-02-24T10:20:09。該類主要提供瞭如下幾個方法:
1)now():獲取當前日期、時間。
2)now(Clock clock):獲取clock對應的日期、時間。
3)minusXxx():在當前年份基礎上減去幾年、幾月、幾周或幾日、幾小時、幾分、幾秒等。
4)plusXxx():在當前年份基礎上加上幾年、幾月、幾周或幾日、幾小時、幾分、幾秒等。
♦ MonthDay:該類僅表明月日,如:--09-20。該類主要提供瞭如下幾個方法:
1)now():獲取當前月日。
2)now(Clock clock):獲取clock對應的月日。
♦ Year:該類僅表明年,如:2019。該類主要提供瞭如下幾個方法:
1)now():獲取當前年份。
2)now(Clock clock):獲取clock對應的年份。
3)minusXxx():在當前年份基礎上減去幾年。
4)plusXxx():在當前年份基礎上加上幾年。
♦ YearMonth:該類僅表明年月,如:2019-02。該類主要提供瞭如下幾個方法:
1)now():獲取當前年月。
2)now(Clock clock):獲取clock對應的年月。
3)minusXxx():在當前年份基礎上減去幾年、幾月。
4)plusXxx():在當前年份基礎上加上幾年、幾月。
♦ ZonedDateTime:該類表明一個時區化的日期、時間。
♦ ZonedId:該類表明一個時區。
♦ DayOfWeek:該類是一個枚舉類,定義了週日到週六的枚舉值。
♦ Month:該類是一個枚舉類,定義了一月到十二月的枚舉值。
歡迎關注微信公衆號【Java典籍】,收看更多Java技術乾貨!
▼微信掃一掃下圖↓↓↓二維碼關注