成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

《java 8 實戰(zhàn)》讀書筆記 -第十二章 新的日期和時間 API

darry / 1374人閱讀

摘要:類似地,一天中的時間,比如,可以使用類表示。合并日期和時間這個復(fù)合類名叫,是和的合體。對于最常見的用例,日期和時間已經(jīng)提供了大量預(yù)定義的。你甚至還可以創(chuàng)建這樣的,它使用的歷法系統(tǒng),以相對于格林尼治時間的偏差方式表示日期時間。

一、LocalDate、LocalTime、Instant、Duration 以及 Period 1.使用 LocalDate 和 LocalTime

創(chuàng)建一個LocalDate對象并讀取其值

LocalDate date = LocalDate.of(2014, 3, 18); //2014-03-18
int year = date.getYear(); //2014
Month month = date.getMonth();//MARCH 
int day = date.getDayOfMonth();//18 
DayOfWeek dow = date.getDayOfWeek();//TUESDAY
int len = date.lengthOfMonth();//31
boolean leap = date.isLeapYear();//false

你還可以通過傳遞一個TemporalField參數(shù)給get方法拿到同樣的信息。TemporalField是一個接口,它定義了如何訪問temporal對象某個字段的值。ChronoField枚舉實現(xiàn)了這一接口,所以你可以很方便地使用get方法得到枚舉元素的值,如下所示。
使用TemporalField讀取LocalDate的值

int year = date.get(ChronoField.YEAR); 
int month = date.get(ChronoField.MONTH_OF_YEAR); 
int day = date.get(ChronoField.DAY_OF_MONTH);

類似地,一天中的時間,比如13:45:20,可以使用LocalTime類表示。類似地,一天中的時間,比如13:45:20,可以使用LocalTime類表示。

LocalTime time = LocalTime.of(13, 45, 20); 
int hour = time.getHour(); 
int minute = time.getMinute(); 
int second = time.getSecond();

LocalDate和LocalTime都可以通過解析代表它們的字符串創(chuàng)建。使用靜態(tài)方法parse,你可以實現(xiàn)這一目的:

LocalDate date = LocalDate.parse("2014-03-18"); 
LocalTime time = LocalTime.parse("13:45:20"); 
你可以向parse方法傳遞一個DateTimeFormatter。它是替換老版java.util.DateFormat的推薦替代品。
2.合并日期和時間

這個復(fù)合類名叫LocalDateTime,是LocalDate和LocalTime的合體。它同時表示了日期和時間,但不帶有時區(qū)信息,你可以直接創(chuàng)建,也可以通過合并日期和時間對象構(gòu)造,如下所示。
直接創(chuàng)建LocalDateTime對象,或者通過合并日期和時間的方式創(chuàng)建

// 2014-03-18T13:45:20 
LocalDateTime dt1 = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45, 20); 
LocalDateTime dt2 = LocalDateTime.of(date, time); 
LocalDateTime dt3 = date.atTime(13, 45, 20); 
LocalDateTime dt4 = date.atTime(time); 
LocalDateTime dt5 = time.atDate(date);

注意,通過它們各自的atTime或者atDate方法,向LocalDate傳遞一個時間對象,或者向LocalTime傳遞一個日期對象的方式,你可以創(chuàng)建一個LocalDateTime對象。你也可以使用toLocalDate或者toLocalTime方法,從LocalDateTime中提取LocalDate或者LocalTime組件:

LocalDate date1 = dt1.toLocalDate(); 
LocalTime time1 = dt1.toLocalTime();
3.機(jī)器的日期和時間格式

新的java.time.Instant類對時間建模的方式,基本上它是以Unix元年時間(傳統(tǒng)的設(shè)定為UTC時區(qū)1970年1月1日午夜時分)開始所經(jīng)歷的
秒數(shù)進(jìn)行計算。你可以通過向靜態(tài)工廠方法ofEpochSecond傳遞一個代表秒數(shù)的值創(chuàng)建一個該類的實例。靜態(tài)工廠方法ofEpochSecond還有一個增強(qiáng)的重載版本,它接收第二個以納秒為單位的參數(shù)值,對傳入作為秒數(shù)的參數(shù)進(jìn)行調(diào)整。重載的版本會調(diào)整納秒?yún)?shù),確保保存的納秒分片在0到999 999 999之間。這意味著下面這些對ofEpochSecond工廠方法的調(diào)用會返回幾乎同樣的Instant對象:

Instant.ofEpochSecond(3);
Instant.ofEpochSecond(3, 0);
Instant.ofEpochSecond(2, 1_000_000_000); 
Instant.ofEpochSecond(4, -1_000_000_000);
從Java7開始,你就可以在你的Java代碼里把長整型數(shù)字比如10000000000寫成一個更具可讀性10_000_000_000。

Instant類也支持靜態(tài)工廠方法now,它能夠幫你獲取當(dāng)前時刻的時間戳。它包含的是由秒及納秒所構(gòu)成的數(shù)字。所以,它無法處理那些我們非常容易理解的時間單位。比如下面這段語句:

int day = Instant.now().get(ChronoField.DAY_OF_MONTH); 

它會拋出下面這樣的異常:

java.time.temporal.UnsupportedTemporalTypeException: Unsupported field: 
 DayOfMonth
4.定義 Duration 或 Period

你可以創(chuàng)建兩個LocalTimes對象、兩個LocalDateTimes對象,或者兩個Instant對象之間的duration( 持續(xù)期間),如下所示:

Duration d1 = Duration.between(time1, time2); 
Duration d1 = Duration.between(dateTime1, dateTime2); 
Duration d2 = Duration.between(instant1, instant2);

如果你試圖在這兩類對象之間創(chuàng)建duration,會觸發(fā)一個DateTimeException異常。此外,由于Duration類主要用于以秒和納秒衡量時間的長短,你不能僅向between方法傳遞一個LocalDate對象做參數(shù)。

如果你需要以年、月或者日的方式對多個時間單位建模,可以使用Period類。使用該類的工廠方法between,你可以使用得到兩個LocalDate之間的時長,如下所示:

Period tenDays = Period.between(LocalDate.of(2014, 3, 8), 
 LocalDate.of(2014, 3, 18));

Duration和Period類都提供了很多非常方便的工廠類,直接創(chuàng)建對應(yīng)的實例;不再是只能以兩個temporal對象的差值的方式來定義它們的對象。
創(chuàng)建Duration和Period對象

Duration threeMinutes = Duration.ofMinutes(3); 
Duration threeMinutes = Duration.of(3, ChronoUnit.MINUTES); 
Period tenDays = Period.ofDays(10); 
Period threeWeeks = Period.ofWeeks(3); 
Period twoYearsSixMonthsOneDay = Period.of(2, 6, 1);

日期/時間類中表示時間間隔的通用方法

Temporal接口的實現(xiàn)類:
HijrahDate, Instant, JapaneseDate, LocalDate, LocalDateTime, LocalTime, MinguoDate, OffsetDateTime, OffsetTime, ThaiBuddhistDate, Year, YearMonth, ZonedDateTime
二、操縱、解析和格式化日期

如果你已經(jīng)有一個LocalDate對象,想要創(chuàng)建它的一個修改版,最直接也最簡單的方法是使用withAttribute方法。withAttribute方法會創(chuàng)建對象的一個副本,并按照需要修改它的屬性。注意,下面的這段代碼中所有的方法都返回一個修改了屬性的對象。它們都不會修改原來的對象!

LocalDate date1 = LocalDate.of(2014, 3, 18); 
LocalDate date2 = date1.withYear(2011); 
LocalDate date3 = date2.withDayOfMonth(25); 
LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 9);

采用更通用的with方法能達(dá)到同樣的目的,它接受的第一個參數(shù)是一個TemporalField對象,格式類似上面代碼最后一行。更確切地說,使用get和with方法,我們可以將Temporal對象值的讀取和修改區(qū)分開。如果Temporal對象不支持請求訪問的字段,它會拋出一個UnsupportedTemporalTypeException異常。

以相對方式修改LocalDate對象的屬性:

LocalDate date1 = LocalDate.of(2014, 3, 18); 
LocalDate date2 = date1.plusWeeks(1); 
LocalDate date3 = date2.minusYears(3); 
LocalDate date4 = date3.plus(6, ChronoUnit.MONTHS);

像LocalDate、LocalTime、LocalDateTime以及Instant這樣表示時間點的日期?時間類提供了大量通用的方法

1.使用 TemporalAdjuster

有的時候,你需要進(jìn)行一些更加復(fù)雜的操作,比如,將日期調(diào)整到下個周日、下個工作日,或者是本月的最后一天。這時,你可以使用重載版本的with方法,向其傳遞一個提供了更多定制化選擇的TemporalAdjuster對象,更加靈活地處理日期。對于最常見的用例,日期和時間API已經(jīng)提供了大量預(yù)定義的TemporalAdjuster。你可以通過TemporalAdjuster類的靜態(tài)工廠方法訪問它們。

使用預(yù)定義的TemporalAdjuster

import static java.time.temporal.TemporalAdjusters.*; 
LocalDate date1 = LocalDate.of(2014, 3, 18); 
LocalDate date2 = date1.with(nextOrSame(DayOfWeek.SUNDAY)); //2014-03-23
LocalDate date3 = date2.with(lastDayOfMonth());//2014-03-31

TemporalAdjuster類中的工廠方法

TemporalAdjuster接口

@FunctionalInterface 
public interface TemporalAdjuster { 
 Temporal adjustInto(Temporal temporal); 
}

如果你想要使用Lambda表達(dá)式定義TemporalAdjuster對象,推薦使用TemporalAdjusters類的靜態(tài)工廠方法ofDateAdjuster,它接受一個UnaryOperator

3.打印輸出及解析日期時間對象

新的java.time.format包就是特別為這個目的而設(shè)計的。這個包中,最重要的類是DateTimeFormatter。創(chuàng)建格式器最簡單的方法是通過它的靜態(tài)工廠方法以及常量。像BASIC_ISO_DATE和 ISO_LOCAL_DATE 這樣的常量是 DateTimeFormatter 類的預(yù)定義實例。

LocalDate date = LocalDate.of(2014, 3, 18);
String s1 = date.format(DateTimeFormatter.BASIC_ISO_DATE); //20140318
String s2 = date.format(DateTimeFormatter.ISO_LOCAL_DATE);//2014-03-18

你可以使用工廠方法parse達(dá)到重創(chuàng)該日期對象的目的:

LocalDate date1 = LocalDate.parse("20140318", 
 DateTimeFormatter.BASIC_ISO_DATE); 
LocalDate date2 = LocalDate.parse("2014-03-18", 
 DateTimeFormatter.ISO_LOCAL_DATE);

和老的java.util.DateFormat相比較,所有的DateTimeFormatter實例都是線程安全的。

按照某個模式創(chuàng)建DateTimeFormatter

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy"); 
LocalDate date1 = LocalDate.of(2014, 3, 18); 
String formattedDate = date1.format(formatter); 
LocalDate date2 = LocalDate.parse(formattedDate, formatter);

創(chuàng)建一個本地化的DateTimeFormatter

DateTimeFormatter italianFormatter = 
 DateTimeFormatter.ofPattern("d. MMMM yyyy", Locale.ITALIAN); 
LocalDate date1 = LocalDate.of(2014, 3, 18); 
String formattedDate = date.format(italianFormatter); // 18. marzo 2014 
LocalDate date2 = LocalDate.parse(formattedDate, italianFormatter);

DateTimeFormatterBuilder類還提供了更復(fù)雜的格式器,你可以通過DateTimeFormatterBuilder自己編程實現(xiàn)我們在上面代碼使用的italianFormatter,代碼清單如下。

DateTimeFormatter italianFormatter = new DateTimeFormatterBuilder() 
 .appendText(ChronoField.DAY_OF_MONTH) 
 .appendLiteral(". ") 
 .appendText(ChronoField.MONTH_OF_YEAR) 
 .appendLiteral(" ") 
 .appendText(ChronoField.YEAR) 
 .parseCaseInsensitive() 
 .toFormatter(Locale.ITALIAN);
三、處理不同的時區(qū)和歷法

新的java.time.ZoneId類是老版java.util.TimeZone的替代品。跟其他日期和時間類一樣,ZoneId類也是無法修改的。時區(qū)是按照一定的規(guī)則將區(qū)域劃分成的標(biāo)準(zhǔn)時間相同的區(qū)間。在ZoneRules這個類中包含了40個這樣的實例。你可以簡單地通過調(diào)用ZoneId的getRules()得到指定時區(qū)的規(guī)則。每個特定的ZoneId對象都由一個地區(qū)ID標(biāo)識,比如:

ZoneId romeZone = ZoneId.of("Europe/Rome");

地區(qū)ID都為“{區(qū)域}/{城市}”的格式,你可以通過Java 8的新方法toZoneId將一個老的時區(qū)對象轉(zhuǎn)換為ZoneId:

ZoneId zoneId = TimeZone.getDefault().toZoneId();

為時間點添加時區(qū)信息

LocalDate date = LocalDate.of(2014, Month.MARCH, 18); 
ZonedDateTime zdt1 = date.atStartOfDay(romeZone); 
LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45); 
ZonedDateTime zdt2 = dateTime.atZone(romeZone); 
Instant instant = Instant.now(); 
ZonedDateTime zdt3 = instant.atZone(romeZone);

通過ZoneId,你還可以將LocalDateTime轉(zhuǎn)換為Instant:

LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45); 
Instant instantFromDateTime = dateTime.toInstant(romeZone); 

你也可以通過反向的方式得到LocalDateTime對象:

Instant instant = Instant.now(); 
LocalDateTime timeFromInstant = LocalDateTime.ofInstant(instant, romeZone);
1.利用和 UTC/格林尼治時間的固定偏差計算時區(qū)

ZoneOffset類,它是ZoneId的一個子類,表示的是當(dāng)前時間和倫敦格林尼治子午線時間的差異:

ZoneOffset newYorkOffset = ZoneOffset.of("-05:00");

注意,使用這種方式定義的ZoneOffset并未考慮任何日光時的影響,所以在大多數(shù)情況下,不推薦使用。ZoneOffset也是ZoneId。
你甚至還可以創(chuàng)建這樣的OffsetDateTime,它使用ISO-8601的歷法系統(tǒng),以相對于UTC/格林尼治時間的偏差方式表示日期時間。

LocalDateTime dateTime = LocalDateTime.of(2014, Month.MARCH, 18, 13, 45); 
OffsetDateTime dateTimeInNewYork = OffsetDateTime.of(date, newYorkOffset)
2.使用別的日歷系統(tǒng)

Java 8中另外還提供了4種其他的日歷系統(tǒng)。這些日歷系統(tǒng)中的每一個都有一個對應(yīng)的日志類,分別是ThaiBuddhistDate、MinguoDate 、 JapaneseDate 以及HijrahDate 。所有這些類以及 LocalDate 都實現(xiàn)了ChronoLocalDate接口。
如下所示:

LocalDate date = LocalDate.of(2014, Month.MARCH, 18); 
JapaneseDate japaneseDate = JapaneseDate.from(date); 

或者,你還可以為某個Locale顯式地創(chuàng)建日歷系統(tǒng),接著創(chuàng)建該Locale對應(yīng)的日期的實例。新的日期和時間API中,Chronology接口建模了一個日歷系統(tǒng),使用它的靜態(tài)工廠方法ofLocale,可以得到它的一個實例,代碼如下:

Chronology japaneseChronology = Chronology.ofLocale(Locale.JAPAN); 
ChronoLocalDate now = japaneseChronology.dateNow(); 

日期及時間API的設(shè)計者建議我們使用LocalDate,盡量避免使用ChronoLocalDate,原因是開發(fā)者在他們的代碼中可能會做一些假設(shè),而這些假設(shè)在不同的日歷系統(tǒng)中,有可能不成立。比如,有人可能會做這樣的假設(shè),即一個月天數(shù)不會超過31天,一年包括12個月,或者一年中包
含的月份數(shù)目是固定的。由于這些原因,我們建議你盡量在你的應(yīng)用中使用LocalDate,包括存儲、操作、業(yè)務(wù)規(guī)則的解讀;不過如果你需要將程序的輸入或者輸出本地化,這時你應(yīng)該使用ChronoLocalDate類。

伊斯蘭教日歷
在Java 8新添加的幾種日歷類型中,HijrahDate(伊斯蘭教日歷)是最復(fù)雜一個,因為它會發(fā)生各種變化。Hijrah日歷系統(tǒng)構(gòu)建于農(nóng)歷月份繼承之上。Java 8提供了多種方法判斷一個月份,比如新月,在世界的哪些地方可見,或者說它只能首先可見于沙特阿拉伯。withVariant方法可以用于選擇期望的變化。為了支持HijrahDate這一標(biāo)準(zhǔn),Java 8中還包括了烏姆庫拉(Umm Al-Qura)變量。
下面這段代碼作為一個例子說明了如何在ISO日歷中計算當(dāng)前伊斯蘭年中齋月的起始和終止日期:

HijrahDate ramadanDate = 
 HijrahDate.now().with(ChronoField.DAY_OF_MONTH, 1)
 .with(ChronoField.MONTH_OF_YEAR, 9); 
System.out.println("Ramadan starts on " + 
 IsoChronology.INSTANCE.date(ramadanDate) + 
 " and ends on " + 
 IsoChronology.INSTANCE.date( 
 ramadanDate.with( 
 TemporalAdjusters.lastDayOfMonth())));

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/74429.html

相關(guān)文章

  • Java8實戰(zhàn)》-讀書筆記第一章(02)

    摘要:實戰(zhàn)讀書筆記第一章從方法傳遞到接著上次的,繼續(xù)來了解一下,如果繼續(xù)簡化代碼。去掉并且生成的數(shù)字是萬,所消耗的時間循序流并行流至于為什么有時候并行流效率比循序流還低,這個以后的文章會解釋。 《Java8實戰(zhàn)》-讀書筆記第一章(02) 從方法傳遞到Lambda 接著上次的Predicate,繼續(xù)來了解一下,如果繼續(xù)簡化代碼。 把方法作為值來傳遞雖然很有用,但是要是有很多類似與isHeavy...

    lushan 評論0 收藏0
  • java 8 實戰(zhàn)讀書筆記 -第九章 默認(rèn)方法

    摘要:類或父類中聲明的方法的優(yōu)先級高于任何聲明為默認(rèn)方法的優(yōu)先級。只有聲明了一個默認(rèn)方法。由于比更加具體,所以編譯器會選擇中聲明的默認(rèn)方法。 如果在現(xiàn)存的接口上引入了非常多的新方法,所有的實現(xiàn)類都必須進(jìn)行改造,實現(xiàn)新方法,為了解決這個問題,Java 8為了解決這一問題引入了一種新的機(jī)制。Java 8中的接口現(xiàn)在支持在聲明方法的同時提供實現(xiàn),這聽起來讓人驚訝!通過兩種方式可以完成這種操作。其一...

    phoenixsky 評論0 收藏0
  • java 8 實戰(zhàn)讀書筆記 -第四章 引入流

    摘要:第四章引入流一什么是流流是的新成員,它允許你以聲明性方式處理數(shù)據(jù)集合通過查詢語句來表達(dá),而不是臨時編寫一個實現(xiàn)。 第四章 引入流 一、什么是流 流是Java API的新成員,它允許你以聲明性方式處理數(shù)據(jù)集合(通過查詢語句來表達(dá),而不是臨時編寫一個實現(xiàn))。就現(xiàn)在來說,你可以把它們看成遍歷數(shù)據(jù)集的高級迭代器。此外,流還可以透明地并行處理,你無需寫任何多線程代碼。 下面兩段代碼都是用來返回低...

    jeyhan 評論0 收藏0
  • 20 個案例教你在 Java 8 中如何處理日期時間?

    摘要:前言前面一篇文章寫了如何安全的使用里面介紹了如何處理日期時間,以及如何保證線程安全,及其介紹了在中的處理時間日期默認(rèn)就線程安全的類。引入了全新的日期時間格式工具,線程安全而且使用方便。 前言 前面一篇文章寫了《SimpleDateFormat 如何安全的使用?》, 里面介紹了 SimpleDateFormat 如何處理日期/時間,以及如何保證線程安全,及其介紹了在 Java 8 中的處...

    Rango 評論0 收藏0
  • Java8實戰(zhàn)》-第四章讀書筆記(引入流Stream)

    摘要:內(nèi)部迭代與使用迭代器顯式迭代的集合不同,流的迭代操作是在背后進(jìn)行的。流只能遍歷一次請注意,和迭代器類似,流只能遍歷一次。 流(Stream) 流是什么 流是Java API的新成員,它允許你以聲明性方式處理數(shù)據(jù)集合(通過查詢語句來表達(dá),而不是臨時編寫一個實現(xiàn))。就現(xiàn)在來說,你可以把它們看成遍歷數(shù)據(jù)集的高級迭代器。此外,流還可以透明地并行處理,你無需寫任何多線程代碼了!我會在后面的筆記中...

    _ivan 評論0 收藏0
  • java 8 實戰(zhàn)讀書筆記 -第十章 用Optional取代null

    摘要:但返回的是一個類型的對象,這意味著操作的結(jié)果是一個類型的對象。反之,如果對象存在,這次調(diào)用就會將其作為函數(shù)的輸入,并按照與方法的約定返回一個對象。 一、Optional 類入門 Java 8中引入了一個新的類java.util.Optional。變量存在時,Optional類只是對類簡單封裝。變量不存在時,缺失的值會被建模成一個空的Optional對象,由方法Optional.empt...

    時飛 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<