參考:http://www.reibang.com/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——它代表的是時(shí)間戳
●LocalDate——不包含具體時(shí)間的日期奄妨,比如2014-01-14再登。它可以用來存儲(chǔ)生日,周年紀(jì)念日端铛,入職日期等棚贾。
●LocalTime——它代表的是不含日期的時(shí)間
●LocalDateTime——它包含了日期及時(shí)間逞力,不過還是沒有偏移信息或者說時(shí)區(qū)锅论。
●ZonedDateTime——這是一個(gè)包含時(shí)區(qū)的完整的日期時(shí)間,偏移量是以UTC/格林威治時(shí)間為基準(zhǔn)的令宿。
java8是如何處理時(shí)間及日期的
1叼耙、在java8中如何獲取某個(gè)特定的日期
通過另一個(gè)方法,可以創(chuàng)建出任意一個(gè)日期粒没,它接受年月日的參數(shù)旬蟋,然后返回一個(gè)等價(jià)的LocalDate實(shí)例。在這個(gè)方法里革娄,需要的日期你填寫什么就是什么,不想之前的API中月份必須從0開始
2冕碟、在java8中檢查兩個(gè)日期是否相等
LocalDate重寫了equals方法來進(jìn)行日期的比較拦惋,如下所示:
3、在java8中如何檢查重復(fù)事件安寺,比如生日
在java中還有一個(gè)與時(shí)間日期相關(guān)的任務(wù)就是檢查重復(fù)事件厕妖,比如每月的賬單日
如何在java中判斷是否是某個(gè)節(jié)日或者重復(fù)事件,使用MonthDay類挑庶。這個(gè)類由月日組合言秸,不包含年信息,可以用來代表每年重復(fù)出現(xiàn)的一些日期或其他組合迎捺。他和新的日期庫(kù)中的其他類一樣也都是不可變且線程安全的举畸,并且它還是一個(gè)值類(value class)。
通過列子可以看到MonthDay只存儲(chǔ)了月日凳枝,對(duì)比兩個(gè)日期的月日即可知道是否重復(fù)
4抄沮、如何增加時(shí)間里面的小時(shí)數(shù)
很多時(shí)候需要對(duì)時(shí)間進(jìn)行操作,比如加一個(gè)小時(shí)來計(jì)算之后的時(shí)間岖瑰,java8提供了更方便的方法 如plusHours叛买,這些方法返回的是一個(gè)新的LocalTime實(shí)例的引用,因?yàn)長(zhǎng)ocalTime是不可變的
5蹋订、如何獲取1周后的日期
這個(gè)與前一個(gè)獲取2小時(shí)后的時(shí)間的例子很相似率挣,這里我們獲取的是1周后的日期。LocalDate是用來表示無時(shí)間的日期露戒,他又一個(gè)plus()方法可以用來增加日椒功,星期捶箱,月,ChronoUnit則用來表示時(shí)間單位蛾茉,LocalDate也是不可變的讼呢,因此任何修改操作都會(huì)返回一個(gè)新的實(shí)例
可以看到一周后的日期是什么,也可以用這個(gè)方法來增加一個(gè)月谦炬,一年悦屏,一小時(shí),一分等等
6键思、一年前后的日期
在上個(gè)例子中我們使用了LocalDate的plus()方法來給日期增加日周月础爬,現(xiàn)在我們用minus()方法來找出一年前的那天
7、在java8中使用時(shí)鐘
java8自帶了Clock類吼鳞,可以用來獲取某個(gè)時(shí)區(qū)下(所以對(duì)時(shí)區(qū)是敏感的)當(dāng)前的瞬時(shí)時(shí)間看蚜、日期。用來代替System.currentTimelnMillis()與TimeZone.getDefault()方法
8赔桌、在java中如何判斷某個(gè)日期在另一個(gè)日期的前面還是后面
如何判斷某個(gè)日期在另一個(gè)日期的前面還是后面或者相等供炎,在java8中,LocalDate類中使用isBefore()疾党、isAfter()音诫、equals()方法來比較兩個(gè)日期。如果調(diào)用方法的那個(gè)日期比給定的日期要早的話雪位,isBefore()方法會(huì)返回true竭钝。equals()方法在前面的例子中已經(jīng)說明了,這里就不舉例了
9 雹洗、java 獲取當(dāng)前時(shí)間的本 周/月 開始結(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);
//本月一號(hào)
LocalDate firstday = LocalDate.of(today.getYear(),today.getMonth(),1)时肿;
LocalDate lastDay =firstday.plusMonths(1)庇茫;//加一月;
//本月間隔天數(shù)
long intervalDaysThisMonth = lastDay.toEpochDay()-firstday.toEpochDay()螃成;
10 港令、獲取日期時(shí)間間隔
可以看到j(luò)ava8中比較日期非常簡(jiǎn)單,不再需要使用Calendar這樣另外的類來完成類似的任務(wù)了
在進(jìn)行開發(fā)工作中锈颗,經(jīng)常會(huì)面對(duì)兩種操作顷霹。
1、把時(shí)間對(duì)象格式化成字符串后存儲(chǔ)下來
1击吱、把格式化好的字符串解析成時(shí)間對(duì)象
Joda-Time為這兩個(gè)核心需求的解決方案就是DateTimeFormatter淋淀。
額外提一點(diǎn),DateTimeFormatter在格式化和解析時(shí)是支持時(shí)區(qū)的覆醇。
二朵纷、核心對(duì)象:
2.1 DateTimeFormatter
日期格式化與解析
2.2 LocalDate
本地日期(沒有時(shí)間炭臭,沒有時(shí)區(qū))
2.3 LocalTime
本地時(shí)間(沒有日期,沒有時(shí)區(qū))
2.4 LocalDateTime
本地日期時(shí)間(沒有時(shí)區(qū))
2.5 DateTime
日期時(shí)間(支持時(shí)區(qū)轉(zhuǎn)換)
三袍辞、示例
1鞋仍、當(dāng)前日期yyyy-MM-dd格式化
//當(dāng)前本地日期,沒有時(shí)區(qū)
LocalDate date = LocalDate.now();
//時(shí)間日期格式化,表達(dá)式與熟知的一樣
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd");
//2018-11-29
String dateStr = fmt.print(date);
2搅吁、當(dāng)前日期時(shí)間yyyy-MM--dd HH:mm:ss格式化
//當(dāng)前日期時(shí)間威创,沒有時(shí)區(qū)
LocalDateTime now = LocalDateTime.now();
//日期格式化,通用時(shí)間表達(dá)式
DateTimeFormatter fmt = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
//2018-11-29 08:08:24
String nowStr = fmt.print(now);
3谎懦、解析日期時(shí)間并使用系統(tǒng)時(shí)區(qū)(example: 2019-10-28 10:23:12 )
String dateStr = "2019-10-28 10:23:12";
//根據(jù)時(shí)間表達(dá)式生成DateTimeFormatter對(duì)象
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í)間并設(shè)置時(shí)區(qū) (example:2019-10-28 10:23:12)
String dateStr = "2019-10-28 10:23:12";
//日期解析,通用時(shí)間表達(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中日期與時(shí)間API的幾個(gè)關(guān)鍵點(diǎn)
經(jīng)過上面的例子界拦,我們已經(jīng)對(duì)java8的時(shí)間日期有了一定的了解吸申,現(xiàn)在回顧一下
●它提供了javax.time.ZoneId用來處理時(shí)區(qū)。
●它提供了LocalDate與LocalTime類
●Java 8中新的時(shí)間與日期API中的所有類都是不可變且線程安全的享甸,這與之前的Date與Calendar API中的恰好相反截碴,那里面像java.util.Date以及SimpleDateFormat這些關(guān)鍵的類都不是線程安全的。
●新的時(shí)間與日期API中很重要的一點(diǎn)是它定義清楚了基本的時(shí)間與日期的概念蛉威,比方說隐岛,瞬時(shí)時(shí)間,持續(xù)時(shí)間瓷翻,日期,時(shí)間割坠,時(shí)區(qū)以及時(shí)間段齐帚。它們都是基于ISO日歷體系的。
每個(gè)Java開發(fā)人員都應(yīng)該至少了解這套新的API中的這五個(gè)類:
●Instant 它代表的是時(shí)間戳彼哼,比如2016-04-14T14:20:13.592Z对妄,這可以從java.time.Clock類中獲取,像這樣: Instant current = Clock.system(ZoneId.of("Asia/Tokyo")).instant();
●LocalDate 它表示的是不帶時(shí)間的日期敢朱,比如2016-04-14剪菱。它可以用來存儲(chǔ)生日,周年紀(jì)念日拴签,入職日期等孝常。
●LocalTime - 它表示的是不帶日期的時(shí)間
●LocalDateTime - 它包含了時(shí)間與日期,不過沒有帶時(shí)區(qū)的偏移量
●ZonedDateTime - 這是一個(gè)帶時(shí)區(qū)的完整時(shí)間蚓哩,它根據(jù)UTC/格林威治時(shí)間來進(jìn)行時(shí)區(qū)調(diào)整
●這個(gè)庫(kù)的主包是java.time构灸,里面包含了代表日期,時(shí)間岸梨,瞬時(shí)以及持續(xù)時(shí)間的類喜颁。它有兩個(gè)子package稠氮,一個(gè)是java.time.foramt,這個(gè)是什么用途就很明顯了半开,還有一個(gè)是java.time.temporal隔披,它能從更低層面對(duì)各個(gè)字段進(jìn)行訪問。
●時(shí)區(qū)指的是地球上共享同一標(biāo)準(zhǔn)時(shí)間的地區(qū)寂拆。每個(gè)時(shí)區(qū)都有一個(gè)唯一標(biāo)識(shí)符奢米,同時(shí)還有一個(gè)地區(qū)/城市(Asia/Tokyo)的格式以及從格林威治時(shí)間開始的一個(gè)偏移時(shí)間。比如說漓库,東京的偏移時(shí)間就是+09:00恃慧。
●OffsetDateTime類實(shí)際上包含了LocalDateTime與ZoneOffset。它用來表示一個(gè)包含格林威治時(shí)間偏移量(+/-小時(shí):分渺蒿,比如+06:00或者 -08:00)的完整的日期(年月日)及時(shí)間(時(shí)分秒痢士,納秒)。
●DateTimeFormatter類用于在Java中進(jìn)行日期的格式化與解析茂装。與SimpleDateFormat不同怠蹂,它是不可變且線程安全的,如果需要的話少态,可以賦值給一個(gè)靜態(tài)變量城侧。DateTimeFormatter類提供了許多預(yù)定義的格式器,你也可以自定義自己想要的格式彼妻。當(dāng)然了嫌佑,根據(jù)約定,它還有一個(gè)parse()方法是用于將字符串轉(zhuǎn)換成日期的侨歉,如果轉(zhuǎn)換期間出現(xiàn)任何錯(cuò)誤屋摇,它會(huì)拋出DateTimeParseException異常。類似的幽邓,DateFormatter類也有一個(gè)用于格式化日期的format()方法炮温,它出錯(cuò)的話則會(huì)拋出DateTimeException異常。
●再說一句牵舵,“MMM d yyyy”與“MMm dd yyyy”這兩個(gè)日期格式也略有不同柒啤,前者能識(shí)別出"Jan 2 2014"與"Jan 14 2014"這兩個(gè)串,而后者如果傳進(jìn)來的是"Jan 2 2014"則會(huì)報(bào)錯(cuò)畸颅,因?yàn)樗谕路萏巶鬟M(jìn)來的是兩個(gè)字符担巩。為了解決這個(gè)問題,在天為個(gè)位數(shù)的情況下没炒,你得在前面補(bǔ)0兵睛,比如"Jan 2 2014"應(yīng)該改為"Jan 02 2014"。
12、在java8中處理不同的時(shí)區(qū)
java8中不僅將日期和時(shí)間進(jìn)行了分離祖很,同時(shí)還有時(shí)區(qū)笛丙。比如ZonId代表的是某個(gè)特定時(shí)區(qū),ZonedDateTime代表帶時(shí)區(qū)的時(shí)間假颇,等同于以前的GregorianCalendar類胚鸯。使用該類,可以將本地時(shí)間轉(zhuǎn)換成另一個(gè)時(shí)區(qū)中的對(duì)應(yīng)時(shí)間笨鸡。
注意:對(duì)應(yīng)時(shí)區(qū)的文本可以直接手動(dòng)填寫姜钳,也可以調(diào)用定義好了的,手動(dòng)填寫的時(shí)候注意不可填錯(cuò)了形耗,否則你會(huì)遇到下面的異常
13哥桥、如何表示固定的日期,比如信用卡過期時(shí)間
正如MonthDay表示的是某個(gè)重復(fù)出現(xiàn)的日子激涤,YearMonth是另外一個(gè)組合拟糕,代表的是像信用卡還款日,定期存款到期日倦踢,options到期日這類的日期送滞。你可以用這個(gè)類找出這個(gè)月有多少天,LengthOfMonth()這個(gè)方法返回的是這個(gè)YearMonth實(shí)例有多少天辱挥,這對(duì)于檢查2月是否潤(rùn)2月很有用
14犁嗅、如何在java8中檢查閏年
LocalDate類由一個(gè)isLeapYear()方法來返回當(dāng)前LocalDate對(duì)應(yīng)的那年是否是閏年
15、兩個(gè)日期之間包含多少天晤碘,多少月
計(jì)算兩個(gè)日期之間包含多少天褂微、周、月园爷、年宠蚂。可以用java.time.Period類完成該功能腮介。下面例子中將計(jì)算日期與將來的日期之間一共有幾個(gè)月
16、帶時(shí)區(qū)的日期與時(shí)間
在java8中端衰,可以使用ZoneOffset來代表某個(gè)時(shí)區(qū)叠洗,可以使用它的靜態(tài)方法ZoneOffset.of()方法來獲取對(duì)應(yīng)的時(shí)區(qū),只要獲得了這個(gè)偏移量旅东,就可以用這個(gè)偏移量和LocalDateTime創(chuàng)建一個(gè)新的OffsetDateTime
可以看到現(xiàn)在時(shí)間日期和時(shí)區(qū)關(guān)聯(lián)上了灭抑,注意OffsetDateTime主要是用來給機(jī)器理解的,平時(shí)使用就用前面結(jié)束的ZoneDateTime類就可以了
17抵代、在java8中獲取當(dāng)前時(shí)間戳
java8獲取時(shí)間戳特別簡(jiǎn)單腾节。Instant類由一個(gè)靜態(tài)的工廠方法now()可以返回當(dāng)前時(shí)間戳
可以看到,當(dāng)前時(shí)間戳是包含日期和時(shí)間的,與java.util.Date很類似案腺,事實(shí)上Instant就是java8以前的Date庆冕,可以使用這個(gè)兩個(gè)類中的方法在這兩個(gè)類型之間進(jìn)行轉(zhuǎn)換,比如Date.from(Instant)就是用來把Instant轉(zhuǎn)換成java.util.date的劈榨,而Date访递。toInstant()就是將Date轉(zhuǎn)換成Instant的
18,如何在java8中使用預(yù)定義的格式器來對(duì)日期進(jìn)行解析/格式化
在java8之前同辣,時(shí)間日期的格式化非常麻煩拷姿,經(jīng)常使用SimpleDateFormat來進(jìn)行格式化,但是SimpleDateFormat并不是線程安全的旱函。在java8中响巢,引入了一個(gè)全新的線程安全的日期與時(shí)間格式器。并且預(yù)定義好了格式棒妨。比如踪古,本例中使用的BASICISODATE格式會(huì)將20160414格式化成2016-04-14
在DateTimeFormatter中還有很多定義好的格式,有興趣的可以自己去看一下
關(guān)于Java 8這個(gè)新的時(shí)間日期API就講到這了靶衍。這幾個(gè)簡(jiǎn)短的示例 對(duì)于理解這套新的API中的一些新增類已經(jīng)足夠了灾炭。我們學(xué)習(xí)了如何創(chuàng)建與修改日期實(shí)例。我們還了解了純?nèi)掌诼簦掌诩訒r(shí)間蜈出,日期加時(shí)區(qū)的區(qū)別,知道如何比較兩個(gè)日期涛酗,如何找到某天到指定日期比如說下一個(gè)生日铡原,周年紀(jì)念日或者保險(xiǎn)日還有多少天。我們還學(xué)習(xí)了如何在Java 8中用線程安全的方式對(duì)日期進(jìn)行解析及格式化商叹,而無需再使用線程本地變量或者第三方庫(kù)這種取巧的方式燕刻。新的API能勝任任何與時(shí)間日期相關(guān)的任務(wù)。