參考:http://m.itdecent.cn/p/8b9d8f777bb3
https://www.cnblogs.com/comeboo/p/5378922.html
注意: fastjson-1.2.12 才開始支持java8 的LocalDateTime
//LocalDateTime --> String
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime time = LocalDateTime.now();
String localTime = df.format(time);
// String -->LocalDateTime
LocalDateTime ldt = LocalDateTime.parse("2018-01-12 17:07:05",df);
//Date --> LocalDateTime
Instant instant = date.toInstant();
ZoneId zone = ZoneId.systemDefault();
LocalDateTime ldt = LocalDateTime.ofInstant(instant, zone);
●Instant——它代表的是時間戳
●LocalDate——不包含具體時間的日期,比如2014-01-14。它可以用來存儲生日,周年紀(jì)念日,入職日期等。
●LocalTime——它代表的是不含日期的時間
●LocalDateTime——它包含了日期及時間,不過還是沒有偏移信息或者說時區(qū)。
●ZonedDateTime——這是一個包含時區(qū)的完整的日期時間,偏移量是以UTC/格林威治時間為基準(zhǔn)的。
java8是如何處理時間及日期的
1、在java8中如何獲取某個特定的日期
通過另一個方法,可以創(chuàng)建出任意一個日期,它接受年月日的參數(shù),然后返回一個等價的LocalDate實例。在這個方法里,需要的日期你填寫什么就是什么,不想之前的API中月份必須從0開始

2、在java8中檢查兩個日期是否相等
LocalDate重寫了equals方法來進(jìn)行日期的比較,如下所示:

3、在java8中如何檢查重復(fù)事件,比如生日
在java中還有一個與時間日期相關(guān)的任務(wù)就是檢查重復(fù)事件,比如每月的賬單日
如何在java中判斷是否是某個節(jié)日或者重復(fù)事件,使用MonthDay類。這個類由月日組合,不包含年信息,可以用來代表每年重復(fù)出現(xiàn)的一些日期或其他組合。他和新的日期庫中的其他類一樣也都是不可變且線程安全的,并且它還是一個值類(value class)。

通過列子可以看到MonthDay只存儲了月日,對比兩個日期的月日即可知道是否重復(fù)
4、如何增加時間里面的小時數(shù)
很多時候需要對時間進(jìn)行操作,比如加一個小時來計算之后的時間,java8提供了更方便的方法 如plusHours,這些方法返回的是一個新的LocalTime實例的引用,因為LocalTime是不可變的

5、如何獲取1周后的日期
這個與前一個獲取2小時后的時間的例子很相似,這里我們獲取的是1周后的日期。LocalDate是用來表示無時間的日期,他又一個plus()方法可以用來增加日,星期,月,ChronoUnit則用來表示時間單位,LocalDate也是不可變的,因此任何修改操作都會返回一個新的實例

可以看到一周后的日期是什么,也可以用這個方法來增加一個月,一年,一小時,一分等等
6、一年前后的日期
在上個例子中我們使用了LocalDate的plus()方法來給日期增加日周月,現(xiàn)在我們用minus()方法來找出一年前的那天

7、在java8中使用時鐘
java8自帶了Clock類,可以用來獲取某個時區(qū)下(所以對時區(qū)是敏感的)當(dāng)前的瞬時時間、日期。用來代替System.currentTimelnMillis()與TimeZone.getDefault()方法

8、在java中如何判斷某個日期在另一個日期的前面還是后面
如何判斷某個日期在另一個日期的前面還是后面或者相等,在java8中,LocalDate類中使用isBefore()、isAfter()、equals()方法來比較兩個日期。如果調(diào)用方法的那個日期比給定的日期要早的話,isBefore()方法會返回true。equals()方法在前面的例子中已經(jīng)說明了,這里就不舉例了

9 、java 獲取當(dāng)前時間的本 周/月 開始結(jié)束日期
LocalDate today = LocalDate.now();
//本周周日(日歷上一般從上周周日到本周周六)
LocalDate firstDate=today.with(TemporalAdjusters.previous(java.time.DayOfWeek.SUNDAY));
//本周周日
LocalDate lastDate=today.with(TemporalAdjusters.next(java.time.DayOfWeek.MONDAY)).minusDays(1);
//本月一號
LocalDate firstday = LocalDate.of(today.getYear(),today.getMonth(),1);
LocalDate lastDay =firstday.plusMonths(1);//加一月;
//本月間隔天數(shù)
long intervalDaysThisMonth = lastDay.toEpochDay()-firstday.toEpochDay();
10 、獲取日期時間間隔
可以看到j(luò)ava8中比較日期非常簡單,不再需要使用Calendar這樣另外的類來完成類似的任務(wù)了
在進(jìn)行開發(fā)工作中,經(jīng)常會面對兩種操作。
1、把時間對象格式化成字符串后存儲下來
1、把格式化好的字符串解析成時間對象
Joda-Time為這兩個核心需求的解決方案就是DateTimeFormatter。
額外提一點,DateTimeFormatter在格式化和解析時是支持時區(qū)的。
二、核心對象:
2.1 DateTimeFormatter
日期格式化與解析
2.2 LocalDate
本地日期(沒有時間,沒有時區(qū))
2.3 LocalTime
本地時間(沒有日期,沒有時區(qū))
2.4 LocalDateTime
本地日期時間(沒有時區(qū))
2.5 DateTime
日期時間(支持時區(qū)轉(zhuǎn)換)
三、示例
1、當(dāng)前日期yyyy-MM-dd格式化
//當(dāng)前本地日期,沒有時區(qū)
LocalDate date = LocalDate.now();
//時間日期格式化,表達(dá)式與熟知的一樣
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd");
//2018-11-29
String dateStr = fmt.print(date);
2、當(dāng)前日期時間yyyy-MM--dd HH:mm:ss格式化
//當(dāng)前日期時間,沒有時區(qū)
LocalDateTime now = LocalDateTime.now();
//日期格式化,通用時間表達(dá)式
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
//2018-11-29 08:08:24
String nowStr = fmt.print(now);
3、解析日期時間并使用系統(tǒng)時區(qū)(example: 2019-10-28 10:23:12 )
String dateStr = "2019-10-28 10:23:12";
//根據(jù)時間表達(dá)式生成DateTimeFormatter對象
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
//2019-10-28T10:23:12.000+08:00
DateTime dateTime = fmt.parseDateTime(dateStr);
4、解析日期時間并設(shè)置時區(qū) (example:2019-10-28 10:23:12)
String dateStr = "2019-10-28 10:23:12";
//日期解析,通用時間表達(dá)式
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withZone(DateTimeZone.forOffsetHours(6));
//2019-10-28T10:23:12.000+06:00
DateTime dateTime = fmt.parseDateTime(dateStr);
java8中日期與時間API的幾個關(guān)鍵點
經(jīng)過上面的例子,我們已經(jīng)對java8的時間日期有了一定的了解,現(xiàn)在回顧一下
●它提供了javax.time.ZoneId用來處理時區(qū)。
●它提供了LocalDate與LocalTime類
●Java 8中新的時間與日期API中的所有類都是不可變且線程安全的,這與之前的Date與Calendar API中的恰好相反,那里面像java.util.Date以及SimpleDateFormat這些關(guān)鍵的類都不是線程安全的。
●新的時間與日期API中很重要的一點是它定義清楚了基本的時間與日期的概念,比方說,瞬時時間,持續(xù)時間,日期,時間,時區(qū)以及時間段。它們都是基于ISO日歷體系的。
每個Java開發(fā)人員都應(yīng)該至少了解這套新的API中的這五個類:
●Instant 它代表的是時間戳,比如2016-04-14T14:20:13.592Z,這可以從java.time.Clock類中獲取,像這樣: Instant current = Clock.system(ZoneId.of("Asia/Tokyo")).instant();
●LocalDate 它表示的是不帶時間的日期,比如2016-04-14。它可以用來存儲生日,周年紀(jì)念日,入職日期等。
●LocalTime - 它表示的是不帶日期的時間
●LocalDateTime - 它包含了時間與日期,不過沒有帶時區(qū)的偏移量
●ZonedDateTime - 這是一個帶時區(qū)的完整時間,它根據(jù)UTC/格林威治時間來進(jìn)行時區(qū)調(diào)整
●這個庫的主包是java.time,里面包含了代表日期,時間,瞬時以及持續(xù)時間的類。它有兩個子package,一個是java.time.foramt,這個是什么用途就很明顯了,還有一個是java.time.temporal,它能從更低層面對各個字段進(jìn)行訪問。
●時區(qū)指的是地球上共享同一標(biāo)準(zhǔn)時間的地區(qū)。每個時區(qū)都有一個唯一標(biāo)識符,同時還有一個地區(qū)/城市(Asia/Tokyo)的格式以及從格林威治時間開始的一個偏移時間。比如說,東京的偏移時間就是+09:00。
●OffsetDateTime類實際上包含了LocalDateTime與ZoneOffset。它用來表示一個包含格林威治時間偏移量(+/-小時:分,比如+06:00或者 -08:00)的完整的日期(年月日)及時間(時分秒,納秒)。
●DateTimeFormatter類用于在Java中進(jìn)行日期的格式化與解析。與SimpleDateFormat不同,它是不可變且線程安全的,如果需要的話,可以賦值給一個靜態(tài)變量。DateTimeFormatter類提供了許多預(yù)定義的格式器,你也可以自定義自己想要的格式。當(dāng)然了,根據(jù)約定,它還有一個parse()方法是用于將字符串轉(zhuǎn)換成日期的,如果轉(zhuǎn)換期間出現(xiàn)任何錯誤,它會拋出DateTimeParseException異常。類似的,DateFormatter類也有一個用于格式化日期的format()方法,它出錯的話則會拋出DateTimeException異常。
●再說一句,“MMM d yyyy”與“MMm dd yyyy”這兩個日期格式也略有不同,前者能識別出"Jan 2 2014"與"Jan 14 2014"這兩個串,而后者如果傳進(jìn)來的是"Jan 2 2014"則會報錯,因為它期望月份處傳進(jìn)來的是兩個字符。為了解決這個問題,在天為個位數(shù)的情況下,你得在前面補(bǔ)0,比如"Jan 2 2014"應(yīng)該改為"Jan 02 2014"。
12、在java8中處理不同的時區(qū)
java8中不僅將日期和時間進(jìn)行了分離,同時還有時區(qū)。比如ZonId代表的是某個特定時區(qū),ZonedDateTime代表帶時區(qū)的時間,等同于以前的GregorianCalendar類。使用該類,可以將本地時間轉(zhuǎn)換成另一個時區(qū)中的對應(yīng)時間。

注意:對應(yīng)時區(qū)的文本可以直接手動填寫,也可以調(diào)用定義好了的,手動填寫的時候注意不可填錯了,否則你會遇到下面的異常

13、如何表示固定的日期,比如信用卡過期時間
正如MonthDay表示的是某個重復(fù)出現(xiàn)的日子,YearMonth是另外一個組合,代表的是像信用卡還款日,定期存款到期日,options到期日這類的日期。你可以用這個類找出這個月有多少天,LengthOfMonth()這個方法返回的是這個YearMonth實例有多少天,這對于檢查2月是否潤2月很有用

14、如何在java8中檢查閏年
LocalDate類由一個isLeapYear()方法來返回當(dāng)前LocalDate對應(yīng)的那年是否是閏年

15、兩個日期之間包含多少天,多少月
計算兩個日期之間包含多少天、周、月、年。可以用java.time.Period類完成該功能。下面例子中將計算日期與將來的日期之間一共有幾個月

16、帶時區(qū)的日期與時間
在java8中,可以使用ZoneOffset來代表某個時區(qū),可以使用它的靜態(tài)方法ZoneOffset.of()方法來獲取對應(yīng)的時區(qū),只要獲得了這個偏移量,就可以用這個偏移量和LocalDateTime創(chuàng)建一個新的OffsetDateTime

可以看到現(xiàn)在時間日期和時區(qū)關(guān)聯(lián)上了,注意OffsetDateTime主要是用來給機(jī)器理解的,平時使用就用前面結(jié)束的ZoneDateTime類就可以了
17、在java8中獲取當(dāng)前時間戳
java8獲取時間戳特別簡單。Instant類由一個靜態(tài)的工廠方法now()可以返回當(dāng)前時間戳

可以看到,當(dāng)前時間戳是包含日期和時間的,與java.util.Date很類似,事實上Instant就是java8以前的Date,可以使用這個兩個類中的方法在這兩個類型之間進(jìn)行轉(zhuǎn)換,比如Date.from(Instant)就是用來把Instant轉(zhuǎn)換成java.util.date的,而Date。toInstant()就是將Date轉(zhuǎn)換成Instant的
18,如何在java8中使用預(yù)定義的格式器來對日期進(jìn)行解析/格式化
在java8之前,時間日期的格式化非常麻煩,經(jīng)常使用SimpleDateFormat來進(jìn)行格式化,但是SimpleDateFormat并不是線程安全的。在java8中,引入了一個全新的線程安全的日期與時間格式器。并且預(yù)定義好了格式。比如,本例中使用的BASICISODATE格式會將20160414格式化成2016-04-14

在DateTimeFormatter中還有很多定義好的格式,有興趣的可以自己去看一下
關(guān)于Java 8這個新的時間日期API就講到這了。這幾個簡短的示例 對于理解這套新的API中的一些新增類已經(jīng)足夠了。我們學(xué)習(xí)了如何創(chuàng)建與修改日期實例。我們還了解了純?nèi)掌?,日期加時間,日期加時區(qū)的區(qū)別,知道如何比較兩個日期,如何找到某天到指定日期比如說下一個生日,周年紀(jì)念日或者保險日還有多少天。我們還學(xué)習(xí)了如何在Java 8中用線程安全的方式對日期進(jìn)行解析及格式化,而無需再使用線程本地變量或者第三方庫這種取巧的方式。新的API能勝任任何與時間日期相關(guān)的任務(wù)。