Java SE 8新功能介绍:使用新的DateTime API计算时间跨度
使用Java SE 8新的DateTime API JSR 310…可以實現更清晰,可讀且功能強大的編碼。
Java SE 8,JSR 310
在上一篇文章“ 使用Streams API處理集合 ”中; 我已深入探討和探索如何使用流遍歷集合,如何從集合和數組創建流以及最終匯總流值。在“ Java SE 8新功能導覽”系列的這篇文章中,我們將深入探討解釋,并探索JSR 310規范的代碼,包括如何使用新的DateTime API計算時間跨度,如何使用Instant和Duration來計算時間跨度,表示日期和時間值,格式化日期和時間值以及支持時區偏移量。
源代碼托管在我的Github帳戶上:從此處克隆它。
表中的內容:
1-用即時和持續時間計算時間跨度:
介紹:
Java SE 8包括一個用于管理日期和時間值的全新API。 在此新API中實際保存數據的類都是不可變的,并且是線程安全的 。 因此,這意味著您不必擔心在多線程環境中傳遞對象。 而且,如果您在并行流中使用它們,那么一切都將始終正常運行。 這個新API中的所有類都是包java.time成員。 我將從命名為Instant和Duration兩個核心類開始。
怎么運行的:
我將從eg.com.tm.java8.features.datetime.InstDuration項目的Java8Features包中的示例開始。 在名為InstantAndDuration的類代碼中。 然后將所有這些代碼放入main方法中。 我將描述的第一堂課稱為Instant 。 我將輸入類的名稱,然后按Ctrl + Space ,然后從java.time包中選擇該類,并將其導入上方。 即時對象表示Java時間軸上的即時。 就像日期類是管理日期和時間的舊方法的一部分一樣,實例代表了毫秒數。
從1970年1月1日Java時代開始。要聲明一個即時對象,我將使用其類型對其進行聲明,并將其命名為start。 然后,我將調用即時類的靜態方法now() 。 這代表了當前機??器上調用代碼的時刻。 然后,我將使用標準系統輸出將該值作為字符串輸出。 運行代碼,您將看到輸出開始于以年,月,日期格式的日期,然后是字母T之后的時間。
結果:
2016-08-05T21:21:59.601Z一旦有時間,您可以使用它來計算該時間與另一個時間之間的差異。 因此,我將創建另一個瞬間,稱為結束。 我也會從now()方法中獲得它的價值。 然后,我將使用系統輸出,并輸出該值。 請注意,兩個值之間存在細微差別,這就是我的系統所花費的時間。 要處理這一行代碼,即輸出起始值。
結果:
2016-08-05T21:33:55.971Z 2016-08-05T21:33:56.048Z如果我要將那行代碼向下移動,那么在兩次調用now方法之間沒有進行任何其他處理,則這兩個值將是相同的,或者可能相差千分之一秒。
結果:
2016-08-05T21:34:43.365Z 2016-08-05T21:34:43.365Z現在,我將向您展示如何計算這兩個值之間的差。 當您將兩個瞬間相互比較時,您會得到一個稱為持續時間的對象。 它由Duration類表示,該類也是Java.time的成員。 我將這個對象命名為過去。 我將調用持續時間類的靜態方法, between(Temporal startInclusive, Temporal endExclusive)稱為between(Temporal startInclusive, Temporal endExclusive) 。 注意,它正在尋找類型為Temporal對象。 Instant類是Temporal的子類。
結果:
Elapsed: PT0S我將以兩個時間值作為起點和終點。 然后我將輸出差異。 我將傳遞過去的文字標簽,然后傳遞變量。 該持續時間對象以字母p開頭,然后以t開頭。 這也是ISO格式的值。 然后它告訴我零秒。 好吧,讓我們看看如果我們調用sleep方法會發生什么。 我將光標放在開始和結束調用之間。 我將使用Thread類。
我將按點號,然后按Ctrl + Space 。 然后,我將調用sleep()方法并傳遞一個1,000的值。 意思是睡一秒鐘。 sleep方法可能會引發錯誤,因此我將使用快速修復方法,并在主方法簽名中添加throws聲明。 我將保存并運行代碼,現在我的經過時間為1.001秒。 您永遠無法真正指望確切的事情,這完全取決于正在處理的計算機上發生的事情。
結果:
Elapsed: PT1.001S接下來,我將進行此打印線調用,并將其移回其原始位置。 因此,現在在獲得起始值之后,我將執行打印線命令。 我要睡一秒鐘。 我將運行代碼。 現在我的經過時間為1.057秒。
結果:
2016-08-05T22:28:42.685Z 2016-08-05T22:28:43.769Z Elapsed: PT1.084S為了使它更具可讀性,我將使用elapsed.to millis向duration對象的方法添加一個調用。 也就是說,獲得毫秒數等效值。 我將以毫秒為單位追加代碼,然后運行代碼。
結果:
2016-08-05T22:32:52.657Z 2016-08-05T22:32:53.731Z Elapsed: 1074 milliseconds 結論:
現在,我看到的可讀值為1,054毫秒。 因此,這就是Instant類和Duration類。 Java SE 8中的兩個核心類,新的日期時間API。
2-表示日期和時間值:
介紹:
之前,我描述了如何在新的日期時間API中使用Instant類來表示Java時間軸中的時刻。 這是另外三個有用的類,分別代表日期和時間的一部分。 它們稱為本地日期 , 本地時間和本地日期時間 。 例如,假設您只想表示一個日期值。 并且您不在乎時間,秒或毫秒,而只關心當前日期。 創建一個名為LocalDate的類的實例。
運作方式 : 我正在使用eg.com.tm.java8.features.datetime.localdt項目的Java8Features包。 在名為LocalDateAndTime的類代碼中。 主要方法 我將從類LocalDate的名稱開始。 當我按Ctrl + Space時 ,我將從java.time包中選擇類。 我將對象命名為currentDate并通過localDate.now獲得其值。 請注意,在處理即時,日期,時間和日期時間之間,語法上存在一致性。
要在當前計算機上獲取當前值,請始終使用now方法。 現在,我將以默認格式輸出該日期。 我將保存并運行代碼,并以年-月-日格式顯示日期 。
結果:
2016-08-06您還可以使用特定的年份,月份和日期值創建日期對象。 再一次,我將創建一個類型為LocalDate的對象。 我將其命名為一個specificDate 。 要獲取此值,請調用LocalDate.of 。
并且有幾個可用的版本。 我將使用帶有三個整數值的那個。 它們沒有在文檔中命名,但是它們代表年,月和日。 我將修補2,000、1和1的值。現在,在較早版本的date time API中,使用date類。 當您處理幾個月時,您總是必須將偏移量設置為0。 因此,對于一月,您將使用0,對于二月1,等等。
這并不是特別直觀。 在新的日間時間API中,所有內容均基于1。 因此1表示一月 ,2表示二月 ,依此類推。 就像您通常期望的那樣。
我將再次使用系統輸出,這次,我將放置新的特定日期。 保存并運行后,我得到的價值是2000年1月1日輸入的。
結果:
2016-01-01如果您只想表示一個時間值,請使用LocalTime類,我將鍵入該類的名稱并將其導入,將其命名為currentTime對象,然后從LocalTime.now獲取其值。
同樣,使用與localdate和Instant相同的語法。 然后,我將使用系統輸出。 我將輸出當前時間。 時間的默認值是24小時表示法,它顯示小時,分鐘,秒和毫秒。
結果:
01:18:11.779我將使用LocalTime 。 我將其命名為specificTime 。 而且,同樣與當地的日期類,我會打電話叫方法of 。 同樣,有許多不同的版本采用不同數量的參數。
我將使用尋找三個整數值的版本,并輸入14、0和45。然后,將該值輸出到控制臺。 結果就來了。 14、00和45秒。 請注意,由于我沒有提供毫秒值,因此該時間的格式化版本在點后不顯示值。
結果:
14:00:45最后,我將展示如何使用LocalDateTime類。
我將輸入類的名稱并將其導入。 我將此對象命名為currentDT 。 我將從LocalDateTime.now獲得它的值。 輸出日期時間值時,將獲得長格式的ISO日期時間。 從日期開始,到時間結束。 并且如果值中包含毫秒,則將顯示它們。 最后,我將創建一個特定的日期和時間,并將其與特定的日期和時間結合起來。
該代碼將類似于下一個代碼。 我將創建一個LocalDateTime對象。 我將其命名為specificDT然后再次調用LocalDateTime.of 。 這次,我將使用該方法的第一個版本,該版本接受本地日期對象和本地時間對象。 您還可以根據年份,月份,日期和時間值的組合來構造日期時間值。 我將輸入具體的日期和時間。 然后將其輸出到控制臺。 當我運行該代碼時,我的特定日期時間是我的特定日期和時間的組合。
結果:
2016-08-06T01:30:46.625 2016-01-01T14:00:45 結論:
因此,可以使用這三個類來表示當前時區中本地計算機上的日期和時間值。 您還可以使用一些類來獲取時區敏感值。 接下來我將描述這些。
3-格式化日期和時間值:
介紹:
前面已經描述了如何使用LocalDate , LocalTime和LocalDateTime類表示時間值。 要將這些信息呈現給用戶,您需要對其進行格式化。 為此,有一個名為DateTimeFormatter的新類。 我將向您展示如何使用一些簡單的語法創建格式化程序。 然后如何使用稱為Daytime Formatter Builder的類完成非常自定義的工作。
怎么運行的:
我正在使用eg.com.tm.java8.features.datetime.format項目的Java8Features 。 在名為DateTimeFormater的類代碼中。 主要方法
首先,我將創建一個日期。 我給它一種LocalDate ,確保導入該類。 我將其命名為currentDate 。 我將從LocalDate.now獲得它的價值。 接下來,我將創建一個格式化程序對象。 我將輸入類的名稱DateTimeFormatter ,然后從java.time.format包中選擇它。 我將此對象命名為df 。 現在有多種創建格式化程序的方法。 最簡單的方法之一是使用DateTmeFormatter類的常量。
我將再次輸入DateTimeFormatter 。 然后輸入句點后,我會看到所有可用常量的列表。 我將選擇ISO Date 。 這將為此對象提供默認格式。 然后,我將使用系統輸出。 我將調用格式化對象的format方法并傳遞date對象。 這就是結果。 我正在以年份月份日期格式輸出值。 月份和日期分別填充為兩個字符。 現在,您可以使用時間和日期時間來做同樣的事情。
結果:
2016-08-06我將使用上面的代碼,并將其重復幾次,然后進行一些更改。 在第二個版本中,我將類型從本地日期更改為本地時間。 當前時間的對象名稱,以及我用來獲取本地時間值的類的名稱。 我將日期時間格式化程序的名稱從DF更改為TF,以進行時間格式化程序。 然后將使用的常量更改為ISO Time 。 然后,我將更改要格式化的對象。 我將確保導入LocalTime類。
然后,我將對第三個版本進行類似的更改。 我這次要使用的類是LocalDateTime 。 我一定會導入它。 我將此對象命名為當前DT。 然后,我將更改從其調用now方法的類。 我將DateTimeFormatter的格式化程序更改為DTF。 然后將常數更改為ISO日期時間。 然后,我將格式化當前的DT對象。 我將確保在每個版本的代碼中都使用正確的格式化程序。 我將保存更改,然后運行代碼。
并且有三個格式化的值。 到目前為止,我還沒有真正做到那么多,因為我使用了代表默認格式的常量。 但是,讓我們看一下一些可用的自定義格式。
結果:
2016-08-09 20:37:11.535 2016-08-09T20:37:11.538我下移到現有代碼的下方。 然后我將創建另一個DateTimeFormatter ,將其命名為長日期格式的f_long ,然后通過調用DateTimeFormatter類的一種稱為Localized Date的方法來獲取其值。
請注意,存在用于日期,時間和日期時間的方法,并帶有各種參數。 我將選擇一個本地化日期,并傳入一個名為FormatStyle的類的常量。 確保導入此類。 然后,鍵入句點后,您將看到有四個可用常數。 完整,長,中和短。 我將選擇長版本,然后通過調用F _ long.format輸出格式化的日期,然后傳入當前的DT對象。
當我運行此代碼時,會得到該日期的長版本。
結果:
August 9, 2016我將通過復制這兩行代碼向您展示該版本的另一個版本,對于該版本,我將格式器名稱更改為f_short,還將使用的常量也更改為short。 然后,我將更改正在調用的格式化程序的名稱。 因此,長版本是闡明的月份名稱。 日期后的逗號,然后是四位數字的年份,以及至少對于當前語言環境而言是短版的逗號,是月份和日期,不帶填充,并使用斜杠分隔值和兩個字符的年份。
結果:
8/9/16接下來,我將向您展示如何使用語言環境。 我將創建幾個字符串。 第一個縮寫為fr_ short(法語),采用短格式。 為了獲得該值,我將調用f_short格式化程序,然后將使用withLocal()調用方法名稱。 為了獲得語言環境值,我將使用Local類,這是Java的早期版本中可用的現有類。 它是程序包Java.util的成員。
然后,我可以調用代表各種語言環境的眾多常量之一。 我會用法語。 然后從那里,我將調用format方法,并傳入當前日期時間。
我將復制該行代碼,對于該版本,我將使用fr_long。 我將使用長格式程序,否則代碼將相同。 然后,我將輸出這兩個值fr_short和fr_long 。
這就是結果。 注意,對于fr_short,月份和日期與美國版本相反。 那是因為在歐洲,日期是第一個陳述的,然后是月份,然后是年份。 當我使用長版本時,我得到的月份是法文拼寫的。
結果:
09/08/16 9 ao?t 2016最后,我將向您展示如何使用稱為日期時間格式化程序構建器的類來構建完全自定義格式化程序。 它使用構建器設計模式,您可以在其中調用多個方法,每個方法都返回當前構建器的一個實例。
我將輸入類的名稱,并確保已將其導入。 我將對象命名為b。 我將使用new關鍵字和構造方法將其實例化。
現在,在該代碼的末尾,我將不會放入分號,因為我想立即調用一系列讓我從頭開始構建格式化程序的方法。 我將從名為Append Value的方法開始。 請注意,有附加即時,附加文字,附加本地化等許多其他功能。 我將調用一個名為appendValue()的方法,該方法接受一個名為TemporalField的類的實例,然后使用一個名為ChronoField的枚舉ChronoField 。 這是從該TemporalField擴展的。
從那里開始,我將使用一年中月份的常量名稱。 接下來,我將附加一個文字值。 這可以是任何字符或任何字符串。 為了使它變得完全獨特,我將添加幾個豎線字符。 現在,我將使用這兩行代碼并將其復制為第二個版本,而不是一年中的月份。 我會輸入一個月中的某天。 請注意,還有星期幾和一年中的某天。 然后,我將復制該行代碼并將其向下移動。 然后用ChronoField.year完成表達式。
一旦創建了構建器對象,就可以獲取格式化程序。 我將創建一個新對象,其類型為DateTimeFormatter 。 我將其命名為Formatter f 。 然后將其稱為構建器對象,以格式化程序的方法,最后我將格式化當前日期時間值。 我將使用系統輸出并調用f.format() ,并傳入currentDT 。
現在,當我運行代碼時,我得到了完全自定義的格式。
結果:
222||9||2016 結論:
您可以使用DateTimeFormatter構建器構建所需的任何格式。 并且由于它使用了構建器設計模式,因此易于創建和維護代碼。
4-支持時區偏移量:
介紹:
新的日期時間API提供了許多類,可讓您管理時區 。 創建從格林威治時間偏移,通過一定的小時數 ,或者通過特定位置白天對象,計算時區之間的差異 。
怎么運行的:
我正在使用eg.com.tm.java8.features.datetime.zone項目的Java8Features包。 在名為TimeZones的類代碼中。 main方法
在其主要方法中,我創建了一個DateTimeFormatter和一個LocalDateTime對象。 LocalDateTime代表我的系統上當前時區中的當前日期和時間 。 那就是埃及時間,因為我在中東。
然后,我將格式化的值輸出到控制臺。 我正在使用短格式輸出值。 在埃及符號中,它是月,日和年。
結果:
8/9/16 10:22 PM為了表示基于時區的日期時間值,請使用ZonedDateTime類。 就像LocalDateTime一樣,它是不可變的并且是線程安全的。 我將輸入類的名稱,然后按Control + Space來添加import語句。 我將對象gmt命名為格林威治標準時間。
創建此對象有幾種不同的方法。 我將向您展示如何創建計算格林威治標準時間的偏移量的對象。 我將再次使用ZonedDateTime類,并在鍵入句點后,將看到有許多可用的方法。 我可以再次調用now() ,以獲取我所在區域的日期時間值。 我可以調用允許進行各種計算的of()方法。 我可以解析字符串,但是我將使用此版本的now方法。 我將傳遞ZoneId類的實例。
ZoneId表示從格林威治標準時間偏移一定小時數。 我將通過調用名為ZoneId.of()的方法來獲得該值。 然后我將傳遞一個文字字符串“ GMT + 0” 。 這就是說,請向我顯示格林威治標準時間的當前日期和時間值。
現在,我將復制將值輸出到控制臺的代碼。 我將其向下移動,并將此版本更改為輸出gmt。 我將運行代碼,并得到結果。
結果:
8/9/16 8:28 PM我在中東埃及,現在,格林威治標準時間要提前兩個小時。
這是獲取ZonedDateTime另一種方法。 假設您想在紐約獲得ZoneDateTime。 有許多內置的字符串或常量,它們可以讓您命名特定的位置,并且您將獲得該位置的正確ZoneId ,而您不必自己擔心數學。 我將創建另一個ZonedDateTime對象,這次我將其命名為ny,代表紐約,并且我將通過調用ZonedDateTime.now()獲得它的值,然后再次傳遞Z oneId.of() ,但這一次我要傳遞一串America / New_York 。
確保完全按照您在此處看到的字符串進行拼寫 。 我將創建一行代碼以輸出該值。 我將保存更改,然后運行它。 紐約是美國東海岸時間,比太平洋時間早三小時。
結果:
8/9/16 4:36 PM要找出所有可用的字符串,可以調用ZoneId類的方法,稱為getAvailableZoneIds() 。 您將獲得一套。 我將輸入Set并按Control + Space ,然后從Java.util選擇set。
然后將其中的項目的通用類型設置為String 。 我叫設置區。 然后,我將調用方法ZoneId.getAvailableZoneIds 。 然后,我將使用forEach()方法遍歷字符串。 然后我將傳遞Lambda表達式。 因此,我可以依次處理每個項目。
結果:
運行該代碼時,我會看到所有可用的字符串。
現在,有太多東西可能很難找到想要的那個。 假設我想尋找倫敦 。
并在一年中的特定時間為該特定位置使用時區。 正如我在本文前面所展示的,我可以使用predicate來搜索字符串。 我將創建一個謂詞對象。 然后將通用類型設置為String 。 我將命名對象條件。 然后,我將使用lambda表達式實現謂詞。 我將傳入str,然后使用條件實現該謂詞。 str。包含,我將經過一系列倫敦。
然后,我將重構我的Lamba表達式。 我將用大括號將System.out.println()包裝起來。 然后,我將擴展代碼以使其更易于使用。 我將在打印行的末尾添加分號,然后創建一個if語句。 然后將條件設置為condition.test() ,并在z傳遞當前區域。 我將把p rintln()語句移到條件內,現在只打印與謂詞測試匹配的字符串。
我將保存更改并運行代碼,并得到結果。 我發現倫敦的正確字符串是:
結果:
Europe/London 結論:
因此,這與處理時區有關。 同樣,使用ZonedDateTime類而不是LocalDateTime表示可以修改和計算的值。 ZoneId表示與格林威治標準時間的偏移量。 還有一個名為“區域偏移”的類,您可以用來計算彼此之間的不同時區。
資源:
我希望您喜歡閱讀它,就像我喜歡編寫它一樣,如果您喜歡它,請分享,傳播信息。
翻譯自: https://www.javacodegeeks.com/2016/08/java-se-8-new-features-tour-calculating-timespans-new-datetime-api.html
總結
以上是生活随笔為你收集整理的Java SE 8新功能介绍:使用新的DateTime API计算时间跨度的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 角色扮演英文名怎么读 角色扮演英文名是什
- 下一篇: 在家千日好的下一句 在家千日好的下一句是