Java8時間日期庫中的常用使用示例_第1頁
Java8時間日期庫中的常用使用示例_第2頁
Java8時間日期庫中的常用使用示例_第3頁
Java8時間日期庫中的常用使用示例_第4頁
Java8時間日期庫中的常用使用示例_第5頁
已閱讀5頁,還剩4頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、Java8時間日期庫中的常用使用示例這篇文章主要介紹了Java8時間日期庫中的20個常用使用示例,幫助大家更好學習Java8是如何處理時間及日期的方法,感興趣的朋友可以參考一下有人問我學習一個新庫的最佳途徑是什么?我的回答是,就是在實際項目中那樣去使用它。在一個真實的項目中會有各種各樣的需求,這會促使開發(fā)人員去探索和研究這個新庫。簡言之,只有任務本身才會真正促使你去探索及學習。java 8的新的日期及時間API也是一樣。為了學習Java 8的這個新庫,這里我創(chuàng)建了20個以任務為導向的例子。我們先從一個簡單的任務開始,比如說如何用Java 8的時間日期庫來表示今天,接著再進一步生成一個帶時間及時

2、區(qū)的完整日期,然后再研究下如何完成一些更實際的任務,比如說開發(fā)一個提醒類的應用,來找出距離一些特定日期比如生日,周日紀念日,下一個帳單日,下一個溢價日或者信用卡過期時間還有多少天。 示例1 如何 在Java 8中獲取當天的日期 Java 8中有一個叫LocalDate的類,它能用來表示今天的日期。這個類與java.util.Date略有不同,因為它只包含日期,沒有時間。因此,如果你只需要表示日期而不包含時間,就可以使用它。LocalDate today = LocalDate.now(); System.out.println("Today's Local date : &q

3、uot; + today); Output Today's Local date : 2014-01-14 你可以看到它創(chuàng)建了今天的日期卻不包含時間信息。它還將日期格式化完了再輸出出來,不像之前的Date類那樣,打印出來的數(shù)據(jù)都是未經(jīng)格式化的。 示例2 如何在Java 8中獲取當前的年月日 LocalDate類中提供了一些很方便的方法可以用于提取出年月日以及其它的日期屬性。使用這些方法,你可以獲取到任何你所需要的日期屬性,而不再需要使用java.util.Calendar這樣的類了:LocalDate today = LocalDate.now(); int year = today.

4、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-14Year : 2014 Month : 1 day : 14 可以看到,在Java 8中獲取年月信息非常簡單,只需使用對應的getter方法就好了,無需記憶,非常直觀。你可以拿它和Java

5、中老的獲取當前年月日的寫法進行一下比較。 示例3 在Java 8中如何獲取某個特定的日期 在第一個例子中,我們看到通過靜態(tài)方法now()來生成當天日期是非常簡單的,不過通過另一個十分有用的工廠方法LocalDate.of(),則可以創(chuàng)建出任意一個日期,它接受年月日的參數(shù),然后返回一個等價的LocalDate實例。關于這個方法還有一個好消息就是它沒有再犯之前API中的錯,比方說,年只能從1900年開始,月必須從0開始,等等。這里的日期你寫什么就是什么,比如說,下面這個例子中它代表的就是1月14日,沒有什么隱藏邏輯。 LocalDate dateOfBirth = LocalDate.of(201

6、0, 01, 14); System.out.println("Your Date of birth is : " + dateOfBirth); Output : Your Date of birth is : 2010-01-14 可以看出,創(chuàng)建出來的日期就是我們所寫的那樣,2014年1月14日。 示例4 在Java 8中如何檢查兩個日期是否相等 如果說起現(xiàn)實中實際的處理時間及日期的任務,有一個常見的就是要檢查兩個日期是否相等。你可能經(jīng)常會碰到要判斷今天是不是某個特殊的日子,比如生日啊,周年紀念日啊,或者假期之類。有的時候,會給你一個日期,讓你檢查它是不是某個日子比方說

7、假日。下面這個例子將會幫助你在Java 8中完成這類任務。正如你所想的那樣,LocalDate重寫了equals方法來進行日期的比較,如下所示: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 在本例中我們比較的兩個日期是相

8、等的。同時,如果在代碼中你拿到了一個格式化好的日期串,你得先將它解析成日期然后才能比較。你可以將這個例子與Java之前比較日期的方式進行下比較,你會發(fā)現(xiàn)它真是爽多了。 示例5 在Java 8中如何檢查重復事件,比如說生日 在Java中還有一個與時間日期相關的實際任務就是檢查重復事件,比如說每月的帳單日,結婚紀念日,每月還款日或者是每年交保險費的日子。如果你在一家電商公司工作的話,那么肯定會有這么一個模塊,會去給用戶發(fā)送生日祝福并且在每一個重要的假日給他們捎去問候,比如說圣誕節(jié),感恩節(jié),在印度則可能是萬燈節(jié)(Deepawali)。如何在Java中判斷是否是某個節(jié)日或者重復事件?使用MonthDa

9、y類。這個類由月日組合,不包含年信息,也就是說你可以用它來代表每年重復出現(xiàn)的一些日子。當然也有一些別的組合,比如說YearMonth類。它和新的時間日期庫中的其它類一樣也都是不可變且線程安全的,并且它還是一個值類(value class)。我們通過一個例子來看下如何使用MonthDay來檢查某個重復的日期:LocalDate dateOfBirth = LocalDate.of(2010, 01, 14); MonthDay birthday = MonthDay.of(dateOfBirth.getMonth(), dateOfBirth.getDayOfMonth(); MonthDay

10、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 ! 雖然年不同,但今天就是生日的那天,所以在輸出那里你會看到一條生日祝福。你可

11、以調整下系統(tǒng)的時間再運行下這個程序看看它是否能提醒你下一個生日是什么時候,你還可以試著用你的下一個生日來編寫一個JUnit單元測試看看代碼能否正確運行。 示例6 如何在Java 8中獲取當前時間 這與第一個例子中獲取當前日期非常相似。這次我們用的是一個叫LocalTime的類,它是沒有日期的時間,與LocalDate是近親。這里你也可以用靜態(tài)工廠方法now()來獲取當前時間。默認的格式是hh:mm:ss:nnn,這里的nnn是納秒??梢院蚃ava 8以前如何獲取當前時間做一下比較。LocalTime time = LocalTime.now(); System.out.println(&quo

12、t;local time now : " + time); Output local time now : 16:33:33.369 / in hour, minutes, seconds, nano seconds 可以看到,當前時間是不包含日期的,因為LocalTime只有時間,沒有日期。 示例7 如何增加時間里面的小時數(shù) 很多時候我們需要增加小時,分或者秒來計算出將來的時間。Java 8不僅提供了不可變且線程安全的類,它還提供了一些更方便的方法譬如plusHours()來替換原來的add()方法。順便說一下,這些方法返回的是一個新的LocalTime實例的引用,因為LocalT

13、ime是不可變的,可別忘了存儲好這個新的引用。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 可以看到當前時間2小時后是16:33:33.369?,F(xiàn)在你可以將它和Java中增加或者減少小時的老的方式進行下比較。一看便知哪種方式更好。 示例8 如何獲

14、取1周后的日期 這與前一個獲取2小時后的時間的例子類似,這里我們將學會如何獲取到1周后的日期。LocalDate是用來表示無時間的日期的,它有一個plus()方法可以用來增加日,星期,或者月,ChronoUnit則用來表示這個時間單位。由于LocalDate也是不可變的,因此任何修改操作都會返回一個新的實例,因此別忘了保存起來。LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS); System.out.println("Today is : " + today); System.out.println("Dat

15、e after 1 week : " + nextWeek); Output: Today is : 2014-01-14Date after 1 week : 2014-01-21 可以看到7天也就是一周后的日期是什么。你可以用這個方法來增加一個月,一年,一小時,一分鐘,甚至是十年,查看下Java API中的ChronoUnit類來獲取更多選項。 示例9 一年前后的日期 這是上個例子的續(xù)集。上例中,我們學習了如何使用LocalDate的plus()方法來給日期增加日,周或者月,現(xiàn)在我們來學習下如何用minus()方法來找出一年前的那天。LocalDate previousYear

16、= 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-14Date after 1 year : 2015-01-14 可以看到現(xiàn)在一共有兩年,一個是2

17、013年,一個是2015年,分別是2014的前后那年。 示例10 在Java 8中使用時鐘 Java 8中自帶了一個Clock類,你可以用它來獲取某個時區(qū)下當前的瞬時時間,日期或者時間。可以用Clock來替代System.currentTimeInMillis()與 TimeZone.getDefault()方法。/ Returns the current time based on your system clock and set to UTC. Clock clock = Clock.systemUTC(); System.out.println("Clock : "

18、 + clock); / Returns time based on system clock zone Clock defaultClock = Clock.systemDefaultZone(); System.out.println("Clock : " + clock); Output: Clock : SystemClockZ Clock : SystemClockZ 你可以用指定的日期來和這個時鐘進行比較,比如下面這樣:public class MyClass private Clock clock; / dependency inject . public v

19、oid process(LocalDate eventDate) if(eventDate.isBefore(LocalDate.now(clock) . 如果你需要對不同時區(qū)的日期進行處理的話這是相當方便的。 示例11 在Java中如何判斷某個日期是在另一個日期的前面還是后面 這也是實際項目中常見的一個任務。你怎么判斷某個日期是在另一個日期的前面還是后面,或者正好相等呢?在Java 8中,LocalDate類有一個isBefore()和isAfter()方法可以用來比較兩個日期。如果調用方法的那個日期比給定的日期要早的話,isBefore()方法會返回true。LocalDate tomor

20、row = 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 Yesterda

21、y is day before today 可以看到在Java 8中進行日期比較非常簡單。不需要再用像Calendar這樣的另一個類來完成類似的任務了。 示例12 在Java 8中處理不同的時區(qū) Java 8不僅將日期和時間進行了分離,同時還有時區(qū)?,F(xiàn)在已經(jīng)有好幾組與時區(qū)相關的類了,比如ZonId代表的是某個特定的時區(qū),而ZonedDateTime代表的是帶時區(qū)的時間。它等同于Java 8以前的GregorianCalendar類。使用這個類,你可以將本地時間轉換成另一個時區(qū)中的對應時間,比如下面這個例子:/ Date and time with timezone in Java 8 Zone

22、Id 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); O

23、utput : Current date and time in a particular timezone : 2014-01-14T16:33:33.373-05:00America/New_York 可以拿它跟之前將本地時間轉換成GMT時間的方式進行下比較。順便說一下,正如Java 8以前那樣,對應時區(qū)的那個文本可別弄錯了,否則你會碰到這么一個異常:Exception in thread "main" java.time.zone.ZoneRulesException: Unknown time-zone ID: ASIA/Tokyo at java.time.zon

24、e.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 如何表示固定的日期,比如信用卡過期時間 正如MonthDay表示

25、的是某個重復出現(xiàn)的日子的,YearMonth又是另一個組合,它代表的是像信用卡還款日,定期存款到期日,options到期日這類的日期。你可以用這個類來找出那個月有多少天,lengthOfMonth()這個方法返回的是這個YearMonth實例有多少天,這對于檢查2月到底是28天還是29天可是非常有用的。YearMonth currentYearMonth = YearMonth.now(); System.out.printf("Days in month year %s: %d%n", currentYearMonth, currentYearMonth.lengthOf

26、Month(); 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: 31Your credit card expires on 2018-02 示例14 如何在Java 8中檢查閏年 這并沒什么復雜的,LocalDate類有一個isLeapYear()的方法能夠返回當前Local

27、Date對應的那年是否是閏年。如果你還想重復造輪子的話,可以看下這段代碼,這是純用Java編寫的判斷某年是否是閏年的邏輯。if(today.isLeapYear() System.out.println("This year is Leap year"); else S.println("2014 is not a Leap year"); Output: 2014 is not a Leap year 你可以多檢查幾年看看結果是否正確,最好寫一個單元測試來對正常年份和閏年進行下測試。 示例15 兩個日期之間包含多少天,多少個月 還有一個常見的任務就是計

28、算兩個給定的日期之間包含多少天,多少周或者多少年。你可以用java.time.Period類來完成這個功能。在下面這個例子中,我們將計算當前日期與將來的一個日期之前一共隔著幾個月。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 : "

29、 + periodToNextJavaRelease.getMonths() ); Output: Months left between today and Java 8 release : 2 可以看到,本月是1月,而Java 8的發(fā)布日期是3月,因此中間隔著2個月。 示例16 帶時區(qū)偏移量的日期與時間 在Java 8里面,你可以用ZoneOffset類來代表某個時區(qū),比如印度是GMT或者UTC5:30,你可以使用它的靜態(tài)方法ZoneOffset.of()方法來獲取對應的時區(qū)。只要獲取到了這個偏移量,你就可以拿LocalDateTime和這個偏移量創(chuàng)建出一個OffsetDateTime。L

30、ocalDateTime 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 wi

31、th timezone offset in Java : 2014-01-14T19:30+05:30 可以看到現(xiàn)在時間日期與時區(qū)是關聯(lián)上了。還有一點就是,OffSetDateTime主要是給機器來理解的,如果是給人看的,可以使用ZoneDateTime類。 示例17 在Java 8中如何獲取當前時間戳 如果你還記得在Java 8前是如何獲取當前時間戳的,那現(xiàn)在這簡直就是小菜一碟了。Instant類有一個靜態(tài)的工廠方法now()可以返回當前時間戳,如下:Instant timestamp = Instant.now(); System.out.println("What is val

32、ue of this instant " + timestamp); Output : What is value of this instant 2014-01-14T08:33:33.379Z 可以看出,當前時間戳是包含日期與時間的,與java.util.Date很類似,事實上Instant就是Java 8前的Date,你可以使用這兩個類中的方法來在這兩個類型之間進行轉換,比如Date.from(Instant)是用來將Instant轉換成java.util.Date的,而Date.toInstant()是將Date轉換成Instant的。 示例18 如何在Java 8中使用預定

33、義的格式器來對日期進行解析/格式化 在Java 8之前,時間日期的格式化可是個技術活,我們的好伙伴SimpleDateFormat并不是線程安全的,而如果用作本地變量來格式化的話又顯得有些笨重。多虧了線程本地變量,這使得它在多線程環(huán)境下也算有了用武之地,但Java維持這一狀態(tài)也有很長一段時間了。這次它引入了一個全新的線程安全的日期與時間格式器。它還自帶了一些預定義好的格式器,包含了常用的日期格式。比如說,本例 中我們就用了預定義的BASICISODATE格式,它會將2014年2月14日格式化成20140114。String dayAfterTommorrow = "20140116&

34、quot; LocalDate formatted = LocalDate.parse(dayAfterTommorrow, DateTimeFormatter.BASIC_ISO_DATE); System.out.printf("Date generated from String %s is %s %n", dayAfterTommorrow, formatted); Output : Date generated from String 20140116 is 2014-01-16 你可以看到生成的日期與指定字符串的值是匹配的,就是日期格式上略有不同。 示例19 如

35、何在Java中使用自定義的格式器來解析日期 在上例中,我們使用了內建的時間日期格式器來解析日期字符串。當然了,預定義的格式器的確不錯但有時候你可能還是需要使用自定義的日期格式,這個時候你就得自己去創(chuàng)建一個自定義的日期格式器實例了。下面這個例子中的日期格式是”MMM dd yyyy”。你可以給DateTimeFormatter的ofPattern靜態(tài)方法()傳入任何的模式,它會返回一個實例,這個模式的字面量與前例中是相同的。比如說M還是代表月,而m仍是分。無效的模式會拋出DateTimeParseException異常,但如果是邏輯上的錯誤比如說該用M的時候用成m,這樣就沒辦法了。String

36、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 (DateTimePar

37、seException 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中對日期進行格式化,轉換成字符串 在上兩個例子中,盡管我們用到了DateTimeFormatter類但我們主要是進行日期字符串的解析。在這個例子中我們要做的事情正好相反

38、。這里我們有一個LocalDateTime類的實例,我們要將它轉換成一個格式化好的日期串。這是目前為止Java中將日期轉換成字符串最簡單便捷的方式了。下面這個例子將會返回一個格式化好的字符串。與前例相同的是,我們仍需使用指定的模式串去創(chuàng)建一個DateTimeFormatter類的實例,但調用的并不是LocalDate類的parse方法,而是它的format()方法。這個方法會返回一個代表當前日期的字符串,對應的模式就是傳入的DateTimeFormatter實例中所定義好的。LocalDateTime arrivalDate = LocalDateTime.now(); try DateTim

39、eFormatter 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.printS

40、tackTrace(); Output : Arriving at : Jan 14 2014 04:33 PM 可以看到,當前時間是用給定的”MMM dd yyyy hh:mm a”模式來表示的,它包含了三個字母表示的月份以及用AM及PM來表示的時間。 Java 8中日期與時間API的幾個關鍵點 看完了這些例子后,我相信你已經(jīng)對Java 8這套新的時間日期API有了一定的了解了。現(xiàn)在我們來回顧下關于這個新的API的一些關鍵的要素。 1、它提供了javax.time.ZoneId用來處理時區(qū)。 2、它提供了LocalDate與LocalTime類 3、Java 8中新的時間與日期API中的所有類都是不可變且線程安全的,這與之前的Date與Calendar API中的恰好相反,那里面像java.util.Date以及SimpleDateFormat這些關鍵的類都不是線程安全的。 4、新的時間與日期API中很重要的一點是它定義清楚了基本的時間與日期的概念,比方說,瞬時時間,持續(xù)時間,日期,時間,時區(qū)以及時間段。它們都是基于ISO日歷體系的。 5、每個Java開發(fā)人員都應該至少了解這套新的API中的這五個類: 1.Instant 它代表的是時間戳,比如2014-01-14T02:20:13.592Z,這可以從jav

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論