一、 日期類API導(dǎo)學(xué)
設(shè)計初衷:Java原本自帶的java.util.Date和java.util.Calendar類锦援,實際上兩種類有線程不安全的風(fēng)險(雖然學(xué)習(xí)的時候處于單線程環(huán)境并不會出現(xiàn)問題),但是之后到了企業(yè)中還是可能會增加學(xué)習(xí)成本剥悟,重新學(xué)習(xí)如何處理時間灵寺,所以推出了這個Java8的最新時間類庫的講解,希望降低學(xué)生的學(xué)習(xí)成本区岗,能夠更快的融入到企業(yè)開發(fā)實戰(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計算困難問題
為什么會出現(xiàn)新的日期類API
JAVA面世之初慈缔,標(biāo)準(zhǔn)庫就引入了兩種用于處理日期和時間的類叮称,它們是java.util.Datejava.util.Calendar。而前者堪稱類糟糕的設(shè)計典范藐鹤,瀏覽API可以發(fā)現(xiàn)瓤檐,從Java1.1開始,Date 類中的所有方法就已經(jīng)被棄用娱节,Java1.1推薦采用Calendar類處理日期和時間挠蛉,但是這個類同樣存在不少問題。
對于日期的計算困難問題
毫秒值與日期直接轉(zhuǎn)換比較繁瑣肄满,其次通過毫秒值來計算時間的差額步驟較多
三谴古、老版本API線程不安全問題
SimpleDateFormat類是線程不安全的,在多線程的情況下稠歉,全局共享一個SimpleDateFormat類中的Calendar對象有可能會出現(xiàn)異常掰担。
另外一個問題就是在java.util.Date和java.util.Calendar類之前,枚舉類型(ENUM)還沒有出現(xiàn)怒炸,所以在字段中使用整數(shù)常量導(dǎo)致整數(shù)常量都是可變的带饱,而不是線程安全的。 為了處理 實際開發(fā)中遇到的問題横媚,標(biāo)準(zhǔn)庫隨后引入了java.sql.Date作為java.util.Date的子類纠炮,但是還是沒能徹底解決問題。最終JavaSE 8中引入了java.time包灯蝴,這種全新的包從根本上解決了長久以來存在的諸多弊端恢口,java.time包基于Joda-Time庫構(gòu)建,是一種免費的開源解決方案穷躁,實際上在Java 8沒有出現(xiàn)之前耕肩,公司中已經(jīng)廣泛使用Joda-Time來解決Java中的日期與時間問題因妇,Joda-Time的設(shè)計團(tuán)隊也參與了java.time包的開發(fā)。
四猿诸、老版本API使用規(guī)范問題
五婚被、java.time包->常用類的概述和功能介紹
Instant類
Instant類對時間軸上的單一瞬時點建模,可以用于記錄應(yīng)用程序中的事件時間戳梳虽,之后學(xué)習(xí)的類型轉(zhuǎn)換中址芯,均可以使用Instant類作為中間類完成轉(zhuǎn)換。
Duration類
Duration類表示秒或納秒時間間隔窜觉,適合處理較短的時間谷炸,需要更高的精確性。
Period類
Period類表示一段時間的年禀挫、月旬陡、日。
LocalDate類
LocalDate是一個不可變的日期時間對象语婴,表示日期描孟,通常被視為年月日。
LocalTime類
LocalTime是一個不可變的日期時間對象砰左,代表一個時間匿醒,通常被看作是小時-秒,時間表示為納秒精度菜职。
LocalDateTime類
LocalDateTime類是一個不可變的日期時間對象青抛,代表日期時間,通常被視為年-月-日=時-分-秒酬核。
ZonedDateTime類
ZonedDateTime是具有時區(qū)的日期時間的不可變表示蜜另,此類存儲所有日期和時間字段,精度為納秒嫡意,時區(qū)為區(qū)域偏移量举瑰,用于處理模糊的本地日期時間。
now方法在日期/時間類的使用
Date-Time API中的所有類均生成不可變實例蔬螟,它們是線程安全的此迅,并且這些類不提供公共構(gòu)造函數(shù),也就是說沒辦法通過new的方式直接創(chuàng)建旧巾,需要采用工廠方法加以實例化耸序。
六、now方法在日期時間類中的應(yīng)用1
** now方法可以根據(jù)當(dāng)前日期或時間創(chuàng)建實例鲁猩。**
七坎怪、now方法在日期時間類中的應(yīng)用2
不僅僅是以上提供的及各類可以使用now方法,Java8的Time包種還提供了其它幾個類可以更精準(zhǔn)的獲取某些信息廓握。
Year類(表示年)
YearMonth類(表示年月)
MonthDay類(表示月日)
八搅窿、of方法在日期/時間類的應(yīng)用
指定任意時間節(jié)點
of方法可以根據(jù)給定的參數(shù)生成對應(yīng)的日期/時間對象嘁酿,基本上每個基本類都有of方法用于生成的對應(yīng)的對象,而且重載形式對邊男应,可以根據(jù)不同的參數(shù)生成對應(yīng)的數(shù)據(jù)闹司。
九、時區(qū)信息的獲茹迤(拓展)
在學(xué)習(xí)ZonedDateTime的時候游桩,發(fā)現(xiàn)這個對象里面封裝的不僅有時間日期,并且還有偏移量+時區(qū)耐朴,那么時區(qū)如何在Java中獲取呢众弓?通過提供的一個類ZonedId的getAvailableZoneIds方法可以獲取到一個Set集合,集合中封裝了600個時區(qū)隔箍。
十、添加時區(qū)信息與獲取其它時區(qū)時間
我們可以通過給 LocalDateTimem添加時區(qū)信息來查看到不同時區(qū)的時間脚乡,比如說 LocalDateTime中當(dāng)前封裝的是上海時間蜒滩,那么想知道此時此刻,紐約的時間是多少奶稠,就可以將紐約的時區(qū)Id添加進(jìn)去俯艰,就可以查看到了,方式如下:
封裝時間 LocalDateTime 并添加時區(qū)信息锌订。
更改時區(qū)信息查看對應(yīng)時間竹握。
十一、Month枚舉類的使用
java.time包中引用了Month的枚舉類辆飘,Month中包含標(biāo)準(zhǔn)日歷中的12個月份的常量(從JANUARY到DECEMEBER)也提供了一些方便的方法供我們使用啦辐。
推薦在初始化LocalDate和LocalDateTime對象的時候,月份的參數(shù)使用枚舉的方式傳入蜈项,這樣更簡單易懂而且不易出錯芹关,因為如果是老的思維,Calendar傳入0的話紧卒,那么會出現(xiàn)異常侥衬。
十二、章節(jié)練習(xí)(1)
十三跑芳、plus方法在LocalDate中的使用
想要修改某個日期/時間對象的現(xiàn)有實例時轴总,我們可以使用 plus和 minus方法來完成操作。
Java8中日期時間相關(guān)的API中的所有實例都是不可改變的博个,一旦創(chuàng)建LocalDate怀樟,LocalTime,LocalDateTime就無法修改他們(類似于String)坡倔,這對于線程安全時非常有利的漂佩。
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) 增加小時
十五养葵、plus的單獨使用方式1
本文中都是使用plusXXX的方法進(jìn)行演示,實際上也有對應(yīng)的減少方法瘩缆,以minus開頭的方法對應(yīng)的即為減少关拒,實際上也有對應(yīng)的減少方法,以minus開頭的方法對應(yīng)的即為減少庸娱,實際上minus方法調(diào)用的也是plus方法着绊,只不過傳入的參數(shù)是負(fù)數(shù)。
plus 和 minus 方法的應(yīng)用
剛才學(xué)習(xí)到的plusXXX相關(guān)的方法都是添加了數(shù)值到具體的某一項上熟尉,根據(jù)觀察還有兩個單獨的plus方法归露,接下來我們來學(xué)習(xí)這兩個單獨的plus方法。
plus(long amountToadd, TemporalUnit unit) LocalTime
plus(TemporalAmount amoutToadd) LocalTime
TemporalAmount 是一個接口斤儿,當(dāng)接口作為方法的參數(shù)的時候剧包,實際上傳入的是接口的實現(xiàn)類對象,根據(jù)查看這個接口的體系往果,可以看到這個接口有一個實現(xiàn)類疆液,名字叫做Period,在學(xué)習(xí)第一節(jié)的時候陕贮,說明了這個 嘞表示一段時間堕油。
如何使用Period來表示一段時間呢?這個類本身提供了of(int year, int month, int day)來表示肮之,例如:Period.of(1,2,3)返回的對象即為1年2個月3天這么一個時間段掉缺。
十六、plus的單獨使用方式2
plus(long amountToadd, TemporalUnit unit)
在實際開發(fā)過程中戈擒,可能還會更精準(zhǔn)的去操作日期或者說增加一些特殊的時間攀圈,比如說1個世紀(jì)、1個半天峦甩,1千年赘来,10年等,Java8提供了這些日期的表示方式而不需要去單獨進(jìn)行計算了凯傲。
TemporalUnit是一個接口犬辰,通過查看體系接口發(fā)現(xiàn),可以使用子類ChronoUnit來表示,ChronoUnit封裝了很多時間段供我們使用冰单。
十七幌缝、with方法的使用方式1
with方法在LocalDateTime類的應(yīng)用
如果不需要對日期進(jìn)行加減而是要直接修改日期的話,那么可以使用with方法诫欠,with方法提供了很多種修改時間的方式
LocalDateTime withNano(int i) 修改納秒
LocalDateTime withSecond(int i) 修改秒
LocalDateTime withMinute(int i) 修改分支
LocalDateTime withHour(int i) 修改小時
LocalDateTime withDayOfMonth(int i) 修改日
LocalDateTime withMonth(int i) 修改月
LocalDateTime withYear(int i) 修改年
十八涵卵、with方法的使用方式2
with(TemporalField field, long newValue)
temporalField是一個接口浴栽,通過查看體系結(jié)構(gòu),可以使用它的子類
ChronoField,ChronoField中封裝了一些日期時間中的組成成分轿偎,可以直接選擇之后傳入第二個參數(shù)進(jìn)行修改典鸡。
例如:with(ChronoField.DAY_OFMONTH,1);將日期中的月份中的天數(shù)改為1
例如:with(ChronoField.YEAR,2021);將日期中的年份改為2021。