2020-08-15 java 8 LocalDateTime 20 例

轉(zhuǎn)載于:https://www.cnblogs.com/feika/p/4448924.html

伴隨lambda表達(dá)式、streams以及一系列小優(yōu)化刀崖,Java 8 推出了全新的日期時(shí)間API键袱,在教程中我們將通過一些簡(jiǎn)單的實(shí)例來學(xué)習(xí)如何使用新API膘茎。Java處理日期扳埂、日歷和時(shí)間的方式一直為社區(qū)所詬病恩溅,將 java.util.Date設(shè)定為可變類型,以及SimpleDateFormat的非線程安全使其應(yīng)用非常受限。Java也意識(shí)到需要一個(gè)更好的 API來滿足社區(qū)中已經(jīng)習(xí)慣了使用JodaTime?API的人們坎背。全新API的眾多好處之一就是替劈,明確了日期時(shí)間概念,例如:瞬時(shí)(instant)得滤、 長短(duration)陨献、日期、時(shí)間懂更、時(shí)區(qū)和周期眨业。同時(shí)繼承了Joda庫按人類語言和計(jì)算機(jī)各自解析的時(shí)間處理方式。不同于老版本沮协,新API基于ISO標(biāo)準(zhǔn)日歷系統(tǒng)龄捡,java.time包下的所有類都是不可變類型而且線程安全。下面是新版API中java.time包里的一些關(guān)鍵類:

Instant:瞬時(shí)實(shí)例慷暂。

LocalDate:本地日期聘殖,不包含具體時(shí)間 例如:2014-01-14 可以用來記錄生日、紀(jì)念日行瑞、加盟日等就斤。

LocalTime:本地時(shí)間,不包含日期蘑辑。

LocalDateTime:組合了日期和時(shí)間洋机,但不包含時(shí)差和時(shí)區(qū)信息。

ZonedDateTime:最完整的日期時(shí)間洋魂,包含時(shí)區(qū)和相對(duì)UTC或格林威治的時(shí)差绷旗。

新API還引入了ZoneOffSet和ZoneId類,使得解決時(shí)區(qū)問題更為簡(jiǎn)便副砍。解析衔肢、格式化時(shí)間的DateTimeFormatter類也全部重新設(shè) 計(jì)。注意豁翎,這篇文章是我在一年前Java 8即將發(fā)布時(shí)寫的角骤,以下示例代碼中的時(shí)間都是那一年的,當(dāng)運(yùn)行這些例子時(shí)會(huì)返回你當(dāng)前的時(shí)間心剥。


在Java 8中如何處理日期和時(shí)間

常有人問我學(xué)習(xí)一個(gè)新庫的最好方式是什么邦尊?我的答案是在實(shí)際項(xiàng)目中使用它。項(xiàng)目中有很多真正的需求驅(qū)使開發(fā)者去發(fā)掘并學(xué)習(xí)新庫优烧。簡(jiǎn)單得說就是任務(wù)驅(qū)動(dòng)學(xué)習(xí)探 索蝉揍。這對(duì)Java 8新日期時(shí)間API也不例外。我創(chuàng)建了20個(gè)基于任務(wù)的實(shí)例來學(xué)習(xí)Java 8的新特性畦娄。從最簡(jiǎn)單創(chuàng)建當(dāng)天的日期開始又沾,然后創(chuàng)建時(shí)間及時(shí)區(qū)弊仪,接著模擬一個(gè)日期提醒應(yīng)用中的任務(wù)——計(jì)算重要日期的到期天數(shù),例如生日杖刷、紀(jì)念日励饵、賬單 日、保費(fèi)到期日滑燃、信用卡過期日等役听。

示例 1、在Java 8中獲取今天的日期

Java 8?中的?LocalDate 用于表示當(dāng)天日期不瓶。和java.util.Date不同禾嫉,它只有日期灾杰,不包含時(shí)間蚊丐。當(dāng)你僅需要表示日期時(shí)就用這個(gè)類。

LocalDate today = LocalDate.now();

System.out.println("Today's Local date : "?+ today);

Output

Today's Local date?: 2014-01-14

上面的代碼創(chuàng)建了當(dāng)天的日期艳吠,不含時(shí)間信息麦备。打印出的日期格式非常友好,不像老的Date類打印出一堆沒有格式化的信息昭娩。

示例 2凛篙、在Java 8中獲取年、月栏渺、日信息

LocalDate類提供了獲取年呛梆、月、日的快捷方法磕诊,其實(shí)例還包含很多其它的日期屬性填物。通過調(diào)用這些方法就可以很方便的得到需要的日期信息,不用像以前一樣需要依賴java.util.Calendar類了霎终。

LocalDate today = LocalDate.now();

int?year = today.getYear();

int?month = today.getMonthValue();

int?day = today.getDayOfMonth();

System.out.printf("Year : %d? Month : %d? day : %d t %n", year, month, day);

Output

Today's Local date?: 2014-01-14

Year : 2014? Month : 1? day : 14

看到了吧滞磺,在Java?8 中得到年、月夏跷、日信息是這么簡(jiǎn)單直觀规伐,想用就用方妖,沒什么需要記的。對(duì)比看看以前Java是怎么處理年月日信息的吧阅茶。

示例 3、在Java 8中處理特定日期

在 第一個(gè)例子里谅海,我們通過靜態(tài)工廠方法now()非常容易地創(chuàng)建了當(dāng)天日期目派,你還可以調(diào)用另一個(gè)有用的工廠方法LocalDate.of()創(chuàng)建任意日期, 該方法需要傳入年胁赢、月企蹭、日做參數(shù)白筹,返回對(duì)應(yīng)的LocalDate實(shí)例。這個(gè)方法的好處是沒再犯老API的設(shè)計(jì)錯(cuò)誤谅摄,比如年度起始于1900徒河,月份是從0開 始等等。日期所見即所得送漠,就像下面這個(gè)例子表示了1月14日顽照,沒有任何隱藏機(jī)關(guān)。

LocalDate dateOfBirth = LocalDate.of(2010, 01, 14);

System.out.println("Your Date of birth is : "?+ dateOfBirth);

1Output : Your Date of birth is : 2010-01-14

可以看到創(chuàng)建的日期完全符合預(yù)期闽寡,與你寫入的2010年1月14日完全一致代兵。

示例 4、在Java 8中判斷兩個(gè)日期是否相等

現(xiàn) 實(shí)生活中有一類時(shí)間處理就是判斷兩個(gè)日期是否相等爷狈。你常常會(huì)檢查今天是不是個(gè)特殊的日子植影,比如生日、紀(jì)念日或非交易日涎永。這時(shí)就需要把指定的日期與某個(gè)特定 日期做比較思币,例如判斷這一天是否是假期。下面這個(gè)例子會(huì)幫助你用Java 8的方式去解決羡微,你肯定已經(jīng)想到了谷饿,LocalDate重載了equal方法,請(qǐng)看下面的例子:

LocalDate date1 = LocalDate.of(2014, 01, 14);

if(date1.equals(today)){

????System.out.printf("Today %s and date1 %s are same date %n", today, date1);

}

Output

today 2014-01-14 and date1 2014-01-14 are same date

這個(gè)例子中我們比較的兩個(gè)日期相同妈倔。注意博投,如果比較的日期是字符型的,需要先解析成日期對(duì)象再作判斷盯蝴。對(duì)比Java老的日期比較方式毅哗,你會(huì)感到清風(fēng)拂面。

示例 5结洼、在Java 8中檢查像生日這種周期性事件

Java 中另一個(gè)日期時(shí)間的處理就是檢查類似每月賬單黎做、結(jié)婚紀(jì)念日、EMI日或保險(xiǎn)繳費(fèi)日這些周期性事件松忍。如果你在電子商務(wù)網(wǎng)站工作蒸殿,那么一定會(huì)有一個(gè)模塊用來在 圣誕節(jié)、感恩節(jié)這種節(jié)日時(shí)向客戶發(fā)送問候郵件鸣峭。Java中如何檢查這些節(jié)日或其它周期性事件呢宏所?答案就是MonthDay類。這個(gè)類組合了月份和日摊溶,去掉 了年爬骤,這意味著你可以用它判斷每年都會(huì)發(fā)生事件。和這個(gè)類相似的還有一個(gè)YearMonth類莫换。這些類也都是不可變并且線程安全的值類型霞玄。下面我們通過 MonthDay來檢查周期性事件:


LocalDate dateOfBirth = LocalDate.of(2010, 01, 14);

MonthDay birthday = MonthDay.of(dateOfBirth.getMonth(), dateOfBirth.getDayOfMonth());

MonthDay currentMonthDay = MonthDay.from(today);


if(currentMonthDay.equals(birthday)){

???System.out.println("Many Many happy returns of the day !!");

}else{

???System.out.println("Sorry, today is not your birthday");

}

Output:

Many Many happy returns of the day !!

只要當(dāng)天的日期和生日匹配骤铃,無論是哪一年都會(huì)打印出祝賀信息。你可以把程序整合進(jìn)系統(tǒng)時(shí)鐘坷剧,看看生日時(shí)是否會(huì)受到提醒惰爬,或者寫一個(gè)單元測(cè)試來檢測(cè)代碼是否運(yùn)行正確。

示例 6惫企、在Java 8中獲取當(dāng)前時(shí)間

與Java 8獲取日期的例子很像撕瞧,獲取時(shí)間使用的是LocalTime類,一個(gè)只有時(shí)間沒有日期的LocalDate近親狞尔〈园妫可以調(diào)用靜態(tài)工廠方法now()來獲取當(dāng)前時(shí)間。默認(rèn)的格式是hh:mm:ss:nnn偏序。對(duì)比一下Java 8之前獲取當(dāng)前時(shí)間的方式页畦。

LocalTime time = LocalTime.now();

System.out.println("local time now : "?+ time);

Output

local?time?now : 16:33:33.369? //?in?hour, minutes, seconds, nano seconds

可以看到當(dāng)前時(shí)間就只包含時(shí)間信息,沒有日期禽车。

示例 7寇漫、如何在現(xiàn)有的時(shí)間上增加小時(shí)

通過增加小時(shí)刊殉、分殉摔、秒來計(jì)算將來的時(shí)間很常見。Java 8除了不變類型和線程安全的好處之外记焊,還提供了更好的plusHours()方法替換add()逸月,并且是兼容的。注意遍膜,這些方法返回一個(gè)全新的LocalTime實(shí)例碗硬,由于其不可變性,返回后一定要用變量賦值瓢颅。

LocalTime time = LocalTime.now();

LocalTime newTime = time.plusHours(2); // adding two hours

System.out.println("Time after 2 hours : "?+? newTime);

Output :

Time after 2 hours : 18:33:33.369

可以看到恩尾,新的時(shí)間在當(dāng)前時(shí)間16:33:33.369的基礎(chǔ)上增加了2個(gè)小時(shí)。和舊版Java的增減時(shí)間的處理方式對(duì)比一下挽懦,看看哪種更好翰意。

示例 8、如何計(jì)算一周后的日期

和上個(gè)例子計(jì)算兩小時(shí)以后的時(shí)間類似信柿,這個(gè)例子會(huì)計(jì)算一周后的日期冀偶。LocalDate日期不包含時(shí)間信息,它的plus()方法用來增加天渔嚷、周进鸠、月,ChronoUnit類聲明了這些時(shí)間單位形病。由于LocalDate也是不變類型客年,返回后一定要用變量賦值霞幅。

LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);

System.out.println("Today is : "?+ today);

System.out.println("Date after 1 week : "?+ nextWeek);

Output:

Today is : 2014-01-14

Date after 1 week : 2014-01-21

可以看到新日期離當(dāng)天日期是7天,也就是一周量瓜。你可以用同樣的方法增加1個(gè)月蝗岖、1年、1小時(shí)榔至、1分鐘甚至一個(gè)世紀(jì)抵赢,更多選項(xiàng)可以查看Java 8 API中的ChronoUnit類。

示例 9唧取、計(jì)算一年前或一年后的日期

繼續(xù)上面的例子铅鲤,上個(gè)例子中我們通過LocalDate的plus()方法增加天數(shù)、周數(shù)或月數(shù)枫弟,這個(gè)例子我們利用minus()方法計(jì)算一年前的日期邢享。

LocalDate previousYear = today.minus(1, ChronoUnit.YEARS);

System.out.println("Date before 1 year : "?+ previousYear);


LocalDate nextYear = today.plus(1, YEARS);

System.out.println("Date after 1 year : "?+ nextYear);

Output:

Date before 1 year : 2013-01-14

Date after 1 year : 2015-01-14

例子結(jié)果得到了兩個(gè)日期,一個(gè)2013年淡诗、一個(gè)2015年骇塘、分別是2014年的前一年和后一年。

示例 10韩容、使用Java 8的Clock時(shí)鐘類

Java 8增加了一個(gè)Clock時(shí)鐘類用于獲取當(dāng)時(shí)的時(shí)間戳款违,或當(dāng)前時(shí)區(qū)下的日期時(shí)間信息。以前用到System.currentTimeInMillis()和TimeZone.getDefault()的地方都可用Clock替換群凶。

// Returns the current time based on your system clock and set to UTC.

Clock clock = Clock.systemUTC();

System.out.println("Clock : "?+ clock);


// Returns time based on system clock zone

Clock defaultClock = Clock.systemDefaultZone();

System.out.println("Clock : "?+ clock);

Output:

Clock : SystemClock[Z]

Clock : SystemClock[Z]

還可以針對(duì)clock時(shí)鐘做比較插爹,像下面這個(gè)例子:


public?class?MyClass {

????private?Clock clock;? // dependency inject

????...

????public?void?process(LocalDate eventDate) {

??????if?(eventDate.isBefore(LocalDate.now(clock)) {

????????...

??????}

????}

}

這種方式在不同時(shí)區(qū)下處理日期時(shí)會(huì)非常管用。

示例 11请梢、如何用Java判斷日期是早于還是晚于另一個(gè)日期

另一個(gè)工作中常見的操作就是如何判斷給定的一個(gè)日期是大于某天還是小于某天赠尾?在Java 8中,LocalDate類有兩類方法isBefore()和isAfter()用于比較日期毅弧。調(diào)用isBefore()方法時(shí)气嫁,如果給定日期小于當(dāng)前日期則返回true。


LocalDate tomorrow = LocalDate.of(2014, 1, 15);

if(tommorow.isAfter(today)){

????System.out.println("Tomorrow comes after today");

}


LocalDate yesterday = today.minus(1, DAYS);


if(yesterday.isBefore(today)){

????System.out.println("Yesterday is day before today");

}

Output:

Tomorrow comes after today

Yesterday is day before today

在Java 8中比較日期非常方便够坐,不需要使用額外的Calendar類來做這些基礎(chǔ)工作了寸宵。

示例 12、在Java 8中處理時(shí)區(qū)

Java 8不僅分離了日期和時(shí)間咆霜,也把時(shí)區(qū)分離出來了〉寺現(xiàn)在有一系列單獨(dú)的類如ZoneId來處理特定時(shí)區(qū),ZoneDateTime類來表示某時(shí)區(qū)下的時(shí)間蛾坯。這在Java 8以前都是GregorianCalendar類來做的光酣。下面這個(gè)例子展示了如何把本時(shí)區(qū)的時(shí)間轉(zhuǎn)換成另一個(gè)時(shí)區(qū)的時(shí)間。


// Date and time with timezone in Java 8

ZoneId america = ZoneId.of("America/New_York");

LocalDateTime localtDateAndTime = LocalDateTime.now();

ZonedDateTime dateAndTimeInNewYork? = ZonedDateTime.of(localtDateAndTime, america );

System.out.println("Current date and time in a particular timezone : "?+ dateAndTimeInNewYork);


Output :

Current date?and time?in?a particular timezone : 2014-01-14T16:33:33.373-05:00[America/New_York]

以前使用GMT的方式轉(zhuǎn)換本地時(shí)間對(duì)比一下脉课。注意救军,在Java 8以前财异,一定要牢牢記住時(shí)區(qū)的名稱,不然就會(huì)拋出下面的異常:


Exception in?thread "main"?java.time.zone.ZoneRulesException: Unknown time-zone ID: ASIA/Tokyo

????????at java.time.zone.ZoneRulesProvider.getProvider(ZoneRulesProvider.java:272)

????????at java.time.zone.ZoneRulesProvider.getRules(ZoneRulesProvider.java:227)

????????at java.time.ZoneRegion.ofId(ZoneRegion.java:120)

????????at java.time.ZoneId.of(ZoneId.java:403)

????????at java.time.ZoneId.of(ZoneId.java:351)

示例 13唱遭、如何表示信用卡到期這類固定日期戳寸,答案就在YearMonth

與 MonthDay檢查重復(fù)事件的例子相似,YearMonth是另一個(gè)組合類拷泽,用于表示信用卡到期日疫鹊、FD到期日、期貨期權(quán)到期日等司致。還可以用這個(gè)類得到 當(dāng)月共有多少天拆吆,YearMonth實(shí)例的lengthOfMonth()方法可以返回當(dāng)月的天數(shù),在判斷2月有28天還是29天時(shí)非常有用脂矫。


YearMonth currentYearMonth = YearMonth.now();

System.out.printf("Days in month year %s: %d%n", currentYearMonth, currentYearMonth.lengthOfMonth());

YearMonth creditCardExpiry = YearMonth.of(2018, Month.FEBRUARY);

System.out.printf("Your credit card expires on %s %n", creditCardExpiry);


Output:

Days in?month year 2014-01: 31

Your credit card expires on 2018-02

根據(jù)上述數(shù)據(jù)枣耀,你可以提醒客戶信用卡快要到期了,個(gè)人認(rèn)為這個(gè)類非常有用庭再。

示例 14捞奕、如何在Java 8中檢查閏年

LocalDate類有一個(gè)很實(shí)用的方法isLeapYear()判斷該實(shí)例是否是一個(gè)閏年,如果你還是想重新發(fā)明輪子拄轻,這有一個(gè)代碼示例颅围,純Java邏輯編寫的判斷閏年的程序


if(today.isLeapYear()){

???System.out.println("This year is Leap year");

}else?{

????System.out.println("2014 is not a Leap year");

}

Output:

2014 is not a Leap year

你可以多寫幾個(gè)日期來驗(yàn)證是否是閏年哺眯,最好是寫JUnit單元測(cè)試做判斷谷浅。

示例 15扒俯、計(jì)算兩個(gè)日期之間的天數(shù)和月數(shù)

有一個(gè)常見日期操作是計(jì)算兩個(gè)日期之間的天數(shù)奶卓、周數(shù)或月數(shù)。在Java?8中可以用java.time.Period類來做計(jì)算撼玄。下面這個(gè)例子中夺姑,我們計(jì)算了當(dāng)天和將來某一天之間的月數(shù)。


LocalDate java8Release = LocalDate.of(2014, Month.MARCH, 14);

Period periodToNextJavaRelease = Period.between(today, java8Release);

System.out.println("Months left between today and Java 8 release : "

???????????????????????????????????+ periodToNextJavaRelease.getMonths() );

Output:

Months left between today and Java 8 release : 2

從上面可以看到現(xiàn)在是一月掌猛,Java 8的發(fā)布日期是3月盏浙,中間相隔兩個(gè)月。

示例 16荔茬、包含時(shí)差信息的日期和時(shí)間

在Java 8中废膘,ZoneOffset類用來表示時(shí)區(qū),舉例來說印度與GMT或UTC標(biāo)準(zhǔn)時(shí)區(qū)相差+05:30慕蔚,可以通過ZoneOffset.of()靜態(tài)方法來 獲取對(duì)應(yīng)的時(shí)區(qū)丐黄。一旦得到了時(shí)差就可以通過傳入LocalDateTime和ZoneOffset來創(chuàng)建一個(gè)OffSetDateTime對(duì)象。


LocalDateTime datetime = LocalDateTime.of(2014, Month.JANUARY, 14, 19, 30);

ZoneOffset offset = ZoneOffset.of("+05:30");

OffsetDateTime date = OffsetDateTime.of(datetime, offset);?

System.out.println("Date and Time with timezone offset in Java : "?+ date);


Output :

Date and Time with timezone offset in?Java : 2014-01-14T19:30+05:30

現(xiàn)在的時(shí)間信息里已經(jīng)包含了時(shí)區(qū)信息了孔飒。注意:OffSetDateTime是對(duì)計(jì)算機(jī)友好的灌闺,ZoneDateTime則對(duì)人更友好艰争。

示例 17、在Java 8中獲取當(dāng)前的時(shí)間戳

如果你還記得Java 8以前是如何獲得當(dāng)前時(shí)間戳桂对,那么現(xiàn)在你終于解脫了甩卓。Instant類有一個(gè)靜態(tài)工廠方法now()會(huì)返回當(dāng)前的時(shí)間戳,如下所示:

Instant timestamp = Instant.now();

System.out.println("What is value of this instant "?+ timestamp);

Output :

What is value of this instant 2014-01-14T08:33:33.379Z

時(shí)間戳信息里同時(shí)包含了日期和時(shí)間蕉斜,這和java.util.Date很像逾柿。實(shí)際上Instant類確實(shí)等同于 Java 8之前的Date類,你可以使用Date類和Instant類各自的轉(zhuǎn)換方法互相轉(zhuǎn)換宅此,例如:Date.from(Instant) 將Instant轉(zhuǎn)換成java.util.Date鹿寻,Date.toInstant()則是將Date類轉(zhuǎn)換成Instant類。

示例 18诽凌、在Java 8中如何使用預(yù)定義的格式化工具去解析或格式化日期

在Java 8以前的世界里毡熏,日期和時(shí)間的格式化非常詭異,唯一的幫助類SimpleDateFormat也是非線程安全的侣诵,而且用作局部變量解析和格式化日期時(shí)顯得很笨重痢法。幸好線程局部變量能使它在多線程環(huán)境中變得可用,不過這都是過去時(shí)了杜顺。Java 8引入了全新的日期時(shí)間格式工具财搁,線程安全而且使用方便。它自帶了一些常用的內(nèi)置格式化工具躬络。下面這個(gè)例子使用了BASIC_ISO_DATE格式化工具將2014年1月14日格式化成20140114尖奔。


String dayAfterTommorrow = "20140116";

LocalDate formatted = LocalDate.parse(dayAfterTommorrow,

????????????????????????DateTimeFormatter.BASIC_ISO_DATE);

System.out.printf("Date generated from String %s is %s %n",

????????????????????dayAfterTommorrow, formatted);

1

2

Output :

Date generated from String 20140116 is 2014-01-16

很明顯的看出得到的日期和給出的日期是同一天,但是格式不同穷当。

示例 19提茁、如何在Java中使用自定義格式化工具解析日期

上 個(gè)例子使用了Java內(nèi)置的格式化工具去解析日期字符串。盡管內(nèi)置格式化工具很好用馁菜,有時(shí)還是需要定義特定的日期格式茴扁,下面這個(gè)例子展示了如何創(chuàng)建自定義 日期格式化工具。例子中的日期格式是“MMM dd yyyy”汪疮∏突穑可以調(diào)用DateTimeFormatter的 ofPattern()靜態(tài)方法并傳入任意格式返回其實(shí)例,格式中的字符和以前代表的一樣智嚷,M?代表月卖丸,m代表分。如果格式不規(guī)范會(huì)拋出 DateTimeParseException異常盏道,不過如果只是把M寫成m這種邏輯錯(cuò)誤是不會(huì)拋異常的稍浆。


String goodFriday = "Apr 18 2014";

try?{

????DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy");

????LocalDate holiday = LocalDate.parse(goodFriday, formatter);

????System.out.printf("Successfully parsed String %s, date is %s%n", goodFriday, holiday);

} catch?(DateTimeParseException ex) {

????System.out.printf("%s is not parsable!%n", goodFriday);

????ex.printStackTrace();

}


Output :

Successfully parsed String Apr 18 2014, date?is 2014-04-18

日期值與傳入的字符串是匹配的,只是格式不同而已。

示例 20粹湃、在Java?8中如何把日期轉(zhuǎn)換成字符串

上 兩個(gè)例子都用到了DateTimeFormatter類恐仑,主要是從字符串解析日期。現(xiàn)在我們反過來为鳄,把LocalDateTime日期實(shí)例轉(zhuǎn)換成特定格式的字符串裳仆。這是迄今為止Java日期轉(zhuǎn)字符串最為簡(jiǎn)單的方式了。下面的例子將返回一個(gè)代表日期的格式化字符串孤钦。和前面類似歧斟,還是需要?jiǎng)?chuàng)建 DateTimeFormatter實(shí)例并傳入格式,但這回調(diào)用的是format()方法偏形,而非parse()方法静袖。這個(gè)方法會(huì)把傳入的日期轉(zhuǎn)化成指定格式的字符串。

LocalDateTime arrivalDate? = LocalDateTime.now();

try?{

????DateTimeFormatter format = DateTimeFormatter.ofPattern("MMM dd yyyy? hh:mm a");

????String landing = arrivalDate.format(format);

????System.out.printf("Arriving at :? %s %n", landing);

} catch?(DateTimeException ex) {

????System.out.printf("%s can't be formatted!%n", arrivalDate);

????ex.printStackTrace();

}

1Output : Arriving at :? Jan 14 2014? 04:33 PM

當(dāng)前時(shí)間被指定的“MMM dd yyyy hh:mm a”格式格式化俊扭,格式包含3個(gè)代表月的字符串队橙,時(shí)間后面帶有AM和PM標(biāo)記。

Java?8日期時(shí)間API的重點(diǎn)

通過這些例子萨惑,你肯定已經(jīng)掌握了Java 8日期時(shí)間API的新知識(shí)點(diǎn)【杩担現(xiàn)在我們來回顧一下這個(gè)優(yōu)雅API的使用要點(diǎn):

1)提供了javax.time.ZoneId 獲取時(shí)區(qū)。

2)提供了LocalDate和LocalTime類庸蔼。

3)Java 8 的所有日期和時(shí)間API都是不可變類并且線程安全解总,而現(xiàn)有的Date和Calendar API中的java.util.Date和SimpleDateFormat是非線程安全的。

4)主包是?java.time,包含了表示日期姐仅、時(shí)間花枫、時(shí)間間隔的一些類。里面有兩個(gè)子包java.time.format用于格式化掏膏, java.time.temporal用于更底層的操作劳翰。

5)時(shí)區(qū)代表了地球上某個(gè)區(qū)域內(nèi)普遍使用的標(biāo)準(zhǔn)時(shí)間。每個(gè)時(shí)區(qū)都有一個(gè)代號(hào)壤追,格式通常由區(qū)域/城市構(gòu)成(Asia/Tokyo)磕道,在加上與格林威治或 UTC的時(shí)差。例如:東京的時(shí)差是+09:00行冰。

6)OffsetDateTime類實(shí)際上組合了LocalDateTime類和ZoneOffset類。用來表示包含和格林威治或UTC時(shí)差的完整日期(年伶丐、月悼做、日)和時(shí)間(時(shí)、分哗魂、秒肛走、納秒)信息。

7)DateTimeFormatter 類用來格式化和解析時(shí)間录别。與SimpleDateFormat不同朽色,這個(gè)類不可變并且線程安全邻吞,需要時(shí)可以給靜態(tài)常量賦值。 DateTimeFormatter類提供了大量的內(nèi)置格式化工具葫男,同時(shí)也允許你自定義抱冷。在轉(zhuǎn)換方面也提供了parse()將字符串解析成日期,如果解析出錯(cuò)會(huì)拋出DateTimeParseException梢褐。DateTimeFormatter類同時(shí)還有format()用來格式化日期旺遮,如果出錯(cuò)會(huì)拋出DateTimeException異常。

8)再補(bǔ)充一點(diǎn)盈咳,日期格式“MMM d yyyy”和“MMM dd yyyy”有一些微妙的不同耿眉,第一個(gè)格式可以解析“Jan 2 2014”和“Jan 14 2014”,而第二個(gè)在解析“Jan 2 2014”就會(huì)拋異常鱼响,因?yàn)榈诙€(gè)格式里要求日必須是兩位的鸣剪。如果想修正,你必須在日期只有個(gè)位數(shù)時(shí)在前面補(bǔ)零丈积,就是說“Jan 2 2014”應(yīng)該寫成?“Jan 02 2014”西傀。

如何使用Java?8的全新日期時(shí)間API就介紹到這了。這些簡(jiǎn)單的例子對(duì)幫助理解新API非常有用桶癣。由于這些例子都基于真實(shí)任務(wù)拥褂,你在做Java日期編程時(shí)不用再東張西望了。我們學(xué)會(huì)了如何創(chuàng)建并操作日期實(shí)例牙寞,學(xué)習(xí)了純?nèi)掌诮染椤⒁约鞍瑫r(shí)間信息和時(shí)差信息的日期、學(xué)會(huì)了怎樣計(jì)算兩個(gè)日期的間隔间雀,這些在計(jì)算當(dāng)天與某個(gè)特定日期間隔的例子中都有所展示悔详。 我們還學(xué)到了在Java 8中如何線程安全地解析和格式化日期,不用再使用蹩腳的線程局部變量技巧惹挟,也不用依賴Joda Time第三方庫茄螃。新API可以作為處理日期時(shí)間操作的標(biāo)準(zhǔn)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末连锯,一起剝皮案震驚了整個(gè)濱河市归苍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌运怖,老刑警劉巖拼弃,帶你破解...
    沈念sama閱讀 217,185評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異摇展,居然都是意外死亡吻氧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來盯孙,“玉大人鲁森,你說我怎么就攤上這事≌穸瑁” “怎么了歌溉?”我有些...
    開封第一講書人閱讀 163,524評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長报账。 經(jīng)常有香客問我研底,道長,這世上最難降的妖魔是什么透罢? 我笑而不...
    開封第一講書人閱讀 58,339評(píng)論 1 293
  • 正文 為了忘掉前任榜晦,我火速辦了婚禮,結(jié)果婚禮上羽圃,老公的妹妹穿的比我還像新娘乾胶。我一直安慰自己,他們只是感情好朽寞,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,387評(píng)論 6 391
  • 文/花漫 我一把揭開白布识窿。 她就那樣靜靜地躺著,像睡著了一般脑融。 火紅的嫁衣襯著肌膚如雪喻频。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評(píng)論 1 301
  • 那天肘迎,我揣著相機(jī)與錄音甥温,去河邊找鬼。 笑死妓布,一個(gè)胖子當(dāng)著我的面吹牛姻蚓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播匣沼,決...
    沈念sama閱讀 40,130評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼狰挡,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了释涛?” 一聲冷哼從身側(cè)響起加叁,我...
    開封第一講書人閱讀 38,985評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎枢贿,沒想到半個(gè)月后殉农,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡局荚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,617評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耀态。...
    茶點(diǎn)故事閱讀 39,779評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡轮傍,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出首装,到底是詐尸還是另有隱情创夜,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評(píng)論 5 345
  • 正文 年R本政府宣布仙逻,位于F島的核電站驰吓,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏系奉。R本人自食惡果不足惜檬贰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,088評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望缺亮。 院中可真熱鬧翁涤,春花似錦、人聲如沸萌踱。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽并鸵。三九已至鸳粉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間园担,已是汗流浹背届谈。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留粉铐,地道東北人疼约。 一個(gè)月前我還...
    沈念sama閱讀 47,876評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像蝙泼,于是被迫代替她去往敵國和親程剥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,700評(píng)論 2 354