聲明:此筆記為根據(jù)黑馬程序員的“2020新版JDK8日期API解析”手打創(chuàng)作
源碼提?。?/p>
鏈接:https://pan.baidu.com/s/1aIJFugm-yGnjS2UAD-IY0w
提取碼:oopm
?不妨點(diǎn)個(gè)贊哦!
附加內(nèi)容? ? ? ??
jdk11中查看的java.util.Date類中可用方法
???????????????????????????一、 日期類API導(dǎo)學(xué)
設(shè)計(jì)初衷:Java原本自帶的java.util.Date和java.util.Calendar類,實(shí)際上兩種類有線程不安全的風(fēng)險(xiǎn)(雖然學(xué)習(xí)的時(shí)候處于單線程環(huán)境并不會出現(xiàn)問題),但是之后到了企業(yè)中還是可能會增加學(xué)習(xí)成本,重新學(xué)習(xí)如何處理時(shí)間,所以推出了這個(gè)Java8的最新時(shí)間類庫的講解,希望降低學(xué)生的學(xué)習(xí)成本,能夠更快的融入到企業(yè)開發(fā)實(shí)戰(zhàn)中去。
課程目標(biāo)
*? ? 掌握J(rèn)ava8中提供的java.time包中的常用日期與相關(guān)方法
*? ? 可以從java.util包下的日期類相關(guān)類過度到j(luò)ava.time包下的日期類
*? ? 掌握J(rèn)ava8中的日期與字符串之間的相互轉(zhuǎn)換
學(xué)習(xí)此課程需要的基礎(chǔ)知識
*? ? java.util.Date與java.util.Calendar類的相關(guān)基礎(chǔ)知識
*? ? 線程相關(guān)的基礎(chǔ)知識
開發(fā)環(huán)境
*? ? IDEA + JDK1.8
適合人群
*? ? Java初學(xué)者
*? ? 再企業(yè)中有從老版本的日期類轉(zhuǎn)換到新版本的日期類需求的人員
? ? ? ? ? ? ? ? ? ? ? ? ? ? 二、 老版本API計(jì)算困難問題
為什么會出現(xiàn)新的日期類API
JAVA面世之初,標(biāo)準(zhǔn)庫就引入了兩種用于處理日期和時(shí)間的類,它們是java.util.Datejava.util.Calendar。而前者堪稱類糟糕的設(shè)計(jì)典范,瀏覽API可以發(fā)現(xiàn),從Java1.1開始,Date 類中的所有方法就已經(jīng)被棄用,Java1.1推薦采用Calendar類處理日期和時(shí)間,但是這個(gè)類同樣存在不少問題。
對于日期的計(jì)算困難問題
毫秒值與日期直接轉(zhuǎn)換比較繁瑣,其次通過毫秒值來計(jì)算時(shí)間的差額步驟較多
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?三、老版本API線程不安全問題
SimpleDateFormat類是線程不安全的,在多線程的情況下,全局共享一個(gè)SimpleDateFormat類中的Calendar對象有可能會出現(xiàn)異常。
另外一個(gè)問題就是在java.util.Date和java.util.Calendar類之前,枚舉類型(ENUM)還沒有出現(xiàn),所以在字段中使用整數(shù)常量導(dǎo)致整數(shù)常量都是可變的,而不是線程安全的。? ? ? ? ? ? ? ? ? ? ? 為了處理 實(shí)際開發(fā)中遇到的問題,標(biāo)準(zhǔn)庫隨后引入了java.sql.Date作為java.util.Date的子類,但是還是沒能徹底解決問題。最終JavaSE 8中引入了java.time包,這種全新的包從根本上解決了長久以來存在的諸多弊端,java.time包基于Joda-Time庫構(gòu)建,是一種免費(fèi)的開源解決方案,實(shí)際上在Java 8沒有出現(xiàn)之前,公司中已經(jīng)廣泛使用Joda-Time來解決Java中的日期與時(shí)間問題,Joda-Time的設(shè)計(jì)團(tuán)隊(duì)也參與了java.time包的開發(fā)。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 四、老版本API使用規(guī)范問題
? ? ? ? ? ? ? ? ? ? ? ? 五、java.time包->常用類的概述和功能介紹
Instant類
? ? Instant類對時(shí)間軸上的單一瞬時(shí)點(diǎn)建模,可以用于記錄應(yīng)用程序中的事件時(shí)間戳,之后學(xué)習(xí)的類型轉(zhuǎn)換中,均可以使用Instant類作為中間類完成轉(zhuǎn)換。
Duration類
? ? Duration類表示秒或納秒時(shí)間間隔,適合處理較短的時(shí)間,需要更高的精確性。
Period類
? ? Period類表示一段時(shí)間的年、月、日。
LocalDate類
? ? LocalDate是一個(gè)不可變的日期時(shí)間對象,表示日期,通常被視為年月日。
LocalTime類
? ? LocalTime是一個(gè)不可變的日期時(shí)間對象,代表一個(gè)時(shí)間,通常被看作是小時(shí)-秒,時(shí)間表示為納秒精度。
LocalDateTime類
? ? LocalDateTime類是一個(gè)不可變的日期時(shí)間對象,代表日期時(shí)間,通常被視為年-月-日=時(shí)-分-秒。
ZonedDateTime類
? ? ZonedDateTime是具有時(shí)區(qū)的日期時(shí)間的不可變表示,此類存儲所有日期和時(shí)間字段,精度為納秒,時(shí)區(qū)為區(qū)域偏移量,用于處理模糊的本地日期時(shí)間。
now方法在日期/時(shí)間類的使用
Date-Time API中的所有類均生成不可變實(shí)例,它們是線程安全的,并且這些類不提供公共構(gòu)造函數(shù),也就是說沒辦法通過new的方式直接創(chuàng)建,需要采用工廠方法加以實(shí)例化。? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? ? ? ? ? ? 六、now方法在日期時(shí)間類中的應(yīng)用1
?now方法可以根據(jù)當(dāng)前日期或時(shí)間創(chuàng)建實(shí)例。
? ? ? ? ? ? ? ? ? ? ? ? ?七、now方法在日期時(shí)間類中的應(yīng)用2
不僅僅是以上提供的及各類可以使用now方法,Java8的Time包種還提供了其它幾個(gè)類可以更精準(zhǔn)的獲取某些信息。
Year類(表示年)
YearMonth類(表示年月)
MonthDay類(表示月日)
? ? ? ? ? ? ? ? ? ? ? ? 八、of方法在日期/時(shí)間類的應(yīng)用
指定任意時(shí)間節(jié)點(diǎn)
of方法可以根據(jù)給定的參數(shù)生成對應(yīng)的日期/時(shí)間對象,基本上每個(gè)基本類都有of方法用于生成的對應(yīng)的對象,而且重載形式對邊,可以根據(jù)不同的參數(shù)生成對應(yīng)的數(shù)據(jù)。
? ? ? ? ? ? ? ? ? ? ? ? ?九、時(shí)區(qū)信息的獲取(拓展)
在學(xué)習(xí)ZonedDateTime的時(shí)候,發(fā)現(xiàn)這個(gè)對象里面封裝的不僅有時(shí)間日期,并且還有偏移量+時(shí)區(qū),那么時(shí)區(qū)如何在Java中獲取呢?通過提供的一個(gè)類ZonedId的getAvailableZoneIds方法可以獲取到一個(gè)Set集合,集合中封裝了600個(gè)時(shí)區(qū)。
? ? ? ? ? ? ? ? ? ? ? ? 十、添加時(shí)區(qū)信息與獲取其它時(shí)區(qū)時(shí)間
我們可以通過給 LocalDateTimem添加時(shí)區(qū)信息來查看到不同時(shí)區(qū)的時(shí)間,比如說 LocalDateTime中當(dāng)前封裝的是上海時(shí)間,那么想知道此時(shí)此刻,紐約的時(shí)間是多少,就可以將紐約的時(shí)區(qū)Id添加進(jìn)去,就可以查看到了,方式如下:
*? ? 封裝時(shí)間 LocalDateTime 并添加時(shí)區(qū)信息。
*? ? 更改時(shí)區(qū)信息查看對應(yīng)時(shí)間。
? ? ? ? ? ? ? ? ? ? ? ? ? 十一、Month枚舉類的使用
java.time包中引用了Month的枚舉類,Month中包含標(biāo)準(zhǔn)日歷中的12個(gè)月份的常量(從JANUARY到DECEMEBER)也提供了一些方便的方法供我們使用。
推薦在初始化LocalDate和LocalDateTime對象的時(shí)候,月份的參數(shù)使用枚舉的方式傳入,這樣更簡單易懂而且不易出錯(cuò),因?yàn)槿绻抢系乃季S,Calendar傳入0的話,那么會出現(xiàn)異常。
? ? ? ? ? ? ? ? ? ? ? ? ? ? 十二、章節(jié)練習(xí)(1)
? ? ? ? ? ? ? ? ? ? ? ? ? ?十三、plus方法在LocalDate中的使用
想要修改某個(gè)日期/時(shí)間對象的現(xiàn)有實(shí)例時(shí),我們可以使用 plus和 minus方法來完成操作。
Java8中日期時(shí)間相關(guān)的API中的所有實(shí)例都是不可改變的,一旦創(chuàng)建LocalDate,LocalTime,LocalDateTime就無法修改他們(類似于String),這對于線程安全時(shí)非常有利的。
plus方法在LocalDate與LocalTime中的使用
*? ? LocalDate中定義了多種對日期進(jìn)行增減操作的方法。
? ? LocalDate plusDay(long days) 增加天數(shù)
? ? LocalDate plusWeeks(long weeks) 增加周數(shù)
? ? LocallDate plusMonths(long months) 增加月數(shù)????
? ? LocalDate plusYears(long years) 增加年數(shù)
minus方法與以上類似。
? ? ? ? ? ? ? ? ? ? ? ? ?十四、plus方法在LocalTime中的使用
LocalTime中定義了多種對事件進(jìn)行增減操作的方法
LocalTime plusNanos(long nanos) 增加納秒
LocalTime plusSeconds(long seconds) 增加秒
LocalTime plusMinutes(long minutes) 增加分鐘
LocalTime plusHours(long hours) 增加小時(shí)
? ? ? ? ? ? ? ? ? ? ? ? ? ?十五、plus的單獨(dú)使用方式1
本文中都是使用plusXXX的方法進(jìn)行演示,實(shí)際上也有對應(yīng)的減少方法,以minus開頭的方法對應(yīng)的即為減少,實(shí)際上也有對應(yīng)的減少方法,以minus開頭的方法對應(yīng)的即為減少,實(shí)際上minus方法調(diào)用的也是plus方法,只不過傳入的參數(shù)是負(fù)數(shù)。
plus 和 minus 方法的應(yīng)用
剛才學(xué)習(xí)到的plusXXX相關(guān)的方法都是添加了數(shù)值到具體的某一項(xiàng)上,根據(jù)觀察還有兩個(gè)單獨(dú)的plus方法,接下來我們來學(xué)習(xí)這兩個(gè)單獨(dú)的plus方法。
plus(long amountToadd, TemporalUnit unit)? LocalTime
plus(TemporalAmount amoutToadd)? ? ? ?LocalTime
TemporalAmount 是一個(gè)接口,當(dāng)接口作為方法的參數(shù)的時(shí)候,實(shí)際上傳入的是接口的實(shí)現(xiàn)類對象,根據(jù)查看這個(gè)接口的體系,可以看到這個(gè)接口有一個(gè)實(shí)現(xiàn)類,名字叫做Period,在學(xué)習(xí)第一節(jié)的時(shí)候,說明了這個(gè) 嘞表示一段時(shí)間。
如何使用Period來表示一段時(shí)間呢?這個(gè)類本身提供了of(int year, int month, int day)來表示,例如:Period.of(1,2,3)返回的對象即為1年2個(gè)月3天這么一個(gè)時(shí)間段。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ?十六、plus的單獨(dú)使用方式2
plus(long amountToadd, TemporalUnit unit)
在實(shí)際開發(fā)過程中,可能還會更精準(zhǔn)的去操作日期或者說增加一些特殊的時(shí)間,比如說1個(gè)世紀(jì)、1個(gè)半天,1千年,10年等,Java8提供了這些日期的表示方式而不需要去單獨(dú)進(jìn)行計(jì)算了。
TemporalUnit是一個(gè)接口,通過查看體系接口發(fā)現(xiàn),可以使用子類ChronoUnit來表示,ChronoUnit封裝了很多時(shí)間段供我們使用。
? ? ? ? ? ? ? ? ? ? ? ? ? ? 十七、with方法的使用方式1
with方法在LocalDateTime類的應(yīng)用
如果不需要對日期進(jìn)行加減而是要直接修改日期的話,那么可以使用with方法,with方法提供了很多種修改時(shí)間的方式
LocalDateTime withNano(int i) 修改納秒
LocalDateTime withSecond(int i) 修改秒
LocalDateTime withMinute(int i) 修改分支
LocalDateTime withHour(int i) 修改小時(shí)
LocalDateTime withDayOfMonth(int i) 修改日
LocalDateTime withMonth(int i) 修改月
LocalDateTime withYear(int i) 修改年
? ? ? ? ? ? ? ? ? ? ? ? ? 十八、with方法的使用方式2
with(TemporalField field, long newValue)
temporalField是一個(gè)接口,通過查看體系結(jié)構(gòu),可以使用它的子類
ChronoField,ChronoField中封裝了一些日期時(shí)間中的組成成分,可以直接選擇之后傳入第二個(gè)參數(shù)進(jìn)行修改。
例如:with(ChronoField.DAY_OFMONTH,1);將日期中的月份中的天數(shù)改為1
例如:with(ChronoField.YEAR,2021);將日期中的年份改為2021。