jdk8新特性之八日期時間API

引言

java 8通過發(fā)布新的Date-Time API進一步加強對日期與時間的處理显设。在舊版的java中,日期時間APi存在諸多問題。java 8引入的新的一系列API,對時間日期處理提供了更好的支持邓梅,清楚的定義了時間日期的一些概念,比如說九默,瞬時時間(Instant),持續(xù)時間(duration)震放,日期(date),時間(time),時區(qū)(time-zone)以及時間段(Period)驼修。同時殿遂,借鑒了Joda庫的一些優(yōu)點诈铛,比如將人和機器對時間日期的理解區(qū)分開的。

java8新特性

  1. jdk8新特性之一Lambda表達式
  2. jdk8新特性之二方法引用
  3. jdk8新特性之三函數(shù)式接口
  4. jdk8新特性之四默認方法
  5. jdk8新特性之五Stream API
  6. jdk8新特性之六Optional類
  7. jdk8新特性之七Nashorn JavaScript
  8. jdk8新特性之八日期時間API
  9. jdk8新特性之九Base64

舊版日期時間API的問題

  • 非線程安全:java.uttil.Date 是非線程安全的墨礁,所有的日期類都是可變的幢竹,這是java日期類最大的問題之一。
  • 設計很差:java的日期/時間類的定義并不一致恩静,在java.util和java.sql的包中毒有日期類焕毫,此外用于格式化和解析的類在java.text包中定義。java.util.Date同時包含日期和時間驶乾,而java.sql.Date僅包含日期邑飒,將其納入java.sql包并不合理。另外這兩個類都有相同提高的名字级乐,這本身就是一個非常糟糕的設計疙咸。
  • 時區(qū)處理麻煩:日期類并不提供國際化,沒有時區(qū)支持风科,因此java引入了java.util.Caleandar和java.util.TimeZone類撒轮,但他們同樣存在上述所有的問題。

新日期時間API

java8在java.time包下提供了很多新的API贼穆。以下為兩個比較重要的API:

  • Local(本地):簡化了日期時間的處理题山,沒有時區(qū)的問題。
  • Zoned(時區(qū)):通過制定的時區(qū)處理日期時間故痊。
    具體的API:
  • LocalDate:存儲不包含時間的日期顶瞳,比如2020-01-11⊙旅郏可以用來存儲生日浊仆,周年紀念日,入職日期等豫领。
  • LocalTime:存儲不包含日期的時間,比如11:07:03.580舔琅。

LocalDate-日期

只存儲年月日等恐。格式:2020-01-11

創(chuàng)建LocalDate對象

//獲取當前日期
LocalDate currDate=LocalDate.now();
System.out.println("當前日期:"+currDate);
//指定日期
LocalDate noeDay=LocalDate.of(2020, 1, 11);
System.out.println("當前日期:"+noeDay);
//通過字符串指定日期
LocalDate towDay=LocalDate.parse("2020-01-11");
System.out.println("當前日期:"+towDay);

運行結果輸出:

當前日期:2020-01-11
當前日期:2020-01-11
當前日期:2020-01-11

獲取年月日周

// 年
int year = currDate.getYear();
// 月
int month = currDate.getMonthValue();
// 一月的第幾天
int day = currDate.getDayOfMonth();
// 一周的第幾天
int week = currDate.getDayOfWeek().getValue();
System.out.printf("%d年%d月%d日,星期%d%n", year, month, day, week);

運行結果輸出:

2020年1月11日备蚓,星期6

比較兩個日期是否相同

LocalDate重寫了equals方法课蔬,讓日期的比較也變得簡單了。

LocalDate date1  = LocalDate.parse("2020-01-11");
LocalDate date2  = LocalDate.parse("2020-01-11");
System.out.println("比較兩個日期是否相同:"+date1.equals(date2));

運行結果輸出:

比較兩個日期是否相同:true

日期前后比較

//isBefore在之前
boolean isBefore=LocalDate.parse("2020-01-11").isBefore(LocalDate.parse("2020-01-10"));
//isAfter在之后
boolean isAfter=LocalDate.parse("2020-01-11").isAfter(LocalDate.parse("2020-01-10"));

日期加減

System.out.println("當前時間"+LocalDate.now());
System.out.println("當前時間加1天"+LocalDate.now().plusDays(1));
System.out.println("當前時間加1月"+LocalDate.now().plusMonths(1));
System.out.println("當前時間加1年"+LocalDate.now().plusYears(1));

運行結果輸出:

當前時間2020-01-11
當前時間加1天2020-01-12
當前時間加1月2020-02-11
當前時間加1年2021-01-11

LocalTime-時間

存儲不包含日期的時間郊尝,比如11:07:03.580二跋。

LocalTime和LocalDate類似,區(qū)別在于LocalDate不包含具體時間流昏,而LocalTime包含具體時間扎即。同樣可以使用now吞获、of或parse方法來獲得對象。

LocalTime time = LocalTime.now();
LocalTime time2 =LocalTime.of(11, 7,3);
LocalTime time3 =LocalTime.parse("11:07:03");

LocalDate類似它也擁有isBefore谚鄙、isAfter各拷、獲取時間單元等方法,就不再贅述闷营。

需要注意的是烤黍,LocalTime獲得的時間格式為:11:41:58.904。也就是傻盟,HH:mm:ss.nnn速蕊,這里nnn是納秒。

還有一個在實戰(zhàn)中查詢日期區(qū)間時我們經(jīng)常定義的“23:59:59.99”常量再也不用自己定義了娘赴。

//最大時間23:59:59.999999999
LocalTime maxTime =LocalTime.MAX;
//最小時間00:00
LocalTime minTime =LocalTime.MIN;

LocalDateTime-日期和時間的組合

LocalDateTime表示日期和時間組合互例。同樣可以使用now、of或parse方法來獲得對象筝闹。

LocalDateTime datetime=LocalDateTime.now();
LocalDateTime datetime2=LocalDateTime.of(2020, 1,11,11,54,30);
LocalDateTime datetime3=LocalDateTime.parse("2020-01-11T12:35");

也可以調用LocalDate的atTime()方法或LocalTime的atDate()方法將LocalDate或LocalTime合并成一個LocalDateTime媳叨。

LocalDateTime datetime4=LocalDate.now().atTime(LocalTime.now());
LocalDateTime datetime5=LocalTime.now().atDate(LocalDate.now());

LocalDateTime與LocalDate和LocalTime之間可以相互轉化。其他日期增減等操作與上面的類似关顷。

Instant-時間戳

用于“時間戳”的運算糊秆。它是以Unix元年(傳統(tǒng)的設定為UTC時區(qū)1970年1月1日午夜時分)開始所經(jīng)歷的描述進行運算。

// 默認獲取UTC時區(qū)
Instant instant=Instant.now();
System.out.println("當前時間(UTC時區(qū)):"+instant);
System.out.println("獲取時間戳:"+instant.toEpochMilli());
        
// 偏移量運算
OffsetDateTime offsetDateTime =instant.atOffset(ZoneOffset.ofHours(8));
System.out.println("當前時間:"+offsetDateTime);
        
// 以Unix元年為起點议双,進行偏移量運算
Instant instant2 = Instant.ofEpochSecond(60);
System.out.println(instant2);

運行結果輸出為:

當前時間(UTC時區(qū)):2020-01-11T05:55:35.493Z
獲取時間戳:1578722135493
當前時間:2020-01-11T13:55:35.493+08:00
1970-01-01T00:01:00Z

Duration-獲取時間段

Duration的內部實現(xiàn)與Instant類似痘番,但Duration表示時間段,通過between方法創(chuàng)建平痰。

LocalDateTime from = LocalDateTime.now();
LocalDateTime to = LocalDateTime.now().plusDays(1);
Duration duration=Duration.between(from, to);
        
//總天數(shù)
long days=duration.toDays();
//小時
long hours=duration.toHours();
//分鐘
long millis=duration.toMillis();
//秒數(shù)
long seconds=duration.getSeconds();
//毫秒數(shù)
long minutes=duration.toMinutes();
//納秒數(shù)
long nanos=duration.toNanos();
System.out.println("天數(shù)"+days);
System.out.println("小時"+hours);
System.out.println("分鐘"+millis);
System.out.println("秒數(shù)"+seconds);
System.out.println("毫秒數(shù)"+minutes);
System.out.println("納秒數(shù)"+nanos);

運行結果輸出:

天數(shù)1
小時24
分鐘86400000
秒數(shù)86400
毫秒數(shù)1440
納秒數(shù)86400000000000

Duration對象還可以通過of()方法創(chuàng)建汞舱,該方法參數(shù)為時間段長度和時間單位。

// 7天
Duration duration1 = Duration.of(7, ChronoUnit.DAYS);
// 60秒
Duration duration2 = Duration.of(60, ChronoUnit.SECONDS);

Period-獲取日期段

Period與Duration類似宗雇,獲取一個時間段昂芜,只不過單位為年月日,也可以通過of方法和between方法創(chuàng)建赔蒲,between方法接收的參數(shù)為LocalDate泌神。

Period period=Period.of(2020, 1, 11);
Period period1 = Period.between(LocalDate.now(), LocalDate.now().plusYears(1));

ZonedDateTime-創(chuàng)建時區(qū)時間

ZonedDateTime類,用于處理帶時區(qū)的日期和時間舞虱。ZoneId表示不同的時區(qū)欢际。大約有40不同的時區(qū)。

Set<String> allZoneIds=ZoneId.getAvailableZoneIds();

創(chuàng)建時區(qū):

ZoneId zoneId=ZoneId.of("Asia/Shanghai");

把LocalDateTime轉換成特定的時區(qū):

ZonedDateTime zonedDateTime=ZonedDateTime.of(LocalDateTime.now(), zoneId);

獲取當前時區(qū):

//獲取當前時區(qū)
ZoneId z=ZoneId.systemDefault();

獲取日期時間:

ZonedDateTime dd = ZonedDateTime.now();
ZonedDateTime date1 = ZonedDateTime.parse("2015-12-03T10:15:30+05:30[Asia/Shanghai]");

時間日期格式化

Java8對日期的格式化操作非常簡單矾兜,首先看到上面的類大多都提供了parse方法损趋,可以直接通過解析字符串得到對應的對象。

而日期和時間的格式化可通過LocalDateTime的format方法進行格式化椅寺。

LocalDateTime dateTime=LocalDateTime.now();
String str=dateTime.format(DateTimeFormatter.ISO_DATE_TIME);
System.out.println(str);
str = dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(str);

可以使用DateTimeFormatter預置的格式浑槽,也可以通過DateTimeFormatter.ofPattern方法來指定格式蒋失。

關于阿丹博客
以上內容,純屬一家之言括荡,因個人能力有限高镐,難免有疏漏和錯誤之處,如發(fā)現(xiàn) bug 或者有更好的 >建議畸冲,歡迎留言批評指正嫉髓,不吝感激。
下面阿丹的個人博客邑闲,記錄所有學習和工作中的博文算行,歡迎大家前去逛逛。
個人博客:http://www.adanblog.com/
GitHub:https://github.com/adanblog/

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末苫耸,一起剝皮案震驚了整個濱河市州邢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌褪子,老刑警劉巖量淌,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異嫌褪,居然都是意外死亡呀枢,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門笼痛,熙熙樓的掌柜王于貴愁眉苦臉地迎上來裙秋,“玉大人,你說我怎么就攤上這事缨伊≌蹋” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵刻坊,是天一觀的道長枷恕。 經(jīng)常有香客問我,道長紧唱,這世上最難降的妖魔是什么活尊? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮漏益,結果婚禮上,老公的妹妹穿的比我還像新娘深胳。我一直安慰自己绰疤,他們只是感情好,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布舞终。 她就那樣靜靜地躺著轻庆,像睡著了一般癣猾。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上余爆,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天纷宇,我揣著相機與錄音,去河邊找鬼蛾方。 笑死像捶,一個胖子當著我的面吹牛,可吹牛的內容都是我干的桩砰。 我是一名探鬼主播拓春,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼亚隅!你這毒婦竟也來了硼莽?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤煮纵,失蹤者是張志新(化名)和其女友劉穎懂鸵,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體行疏,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡匆光,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了隘擎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片殴穴。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖货葬,靈堂內的尸體忽然破棺而出采幌,到底是詐尸還是另有隱情,我是刑警寧澤震桶,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布休傍,位于F島的核電站,受9級特大地震影響蹲姐,放射性物質發(fā)生泄漏磨取。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一柴墩、第九天 我趴在偏房一處隱蔽的房頂上張望忙厌。 院中可真熱鬧,春花似錦江咳、人聲如沸逢净。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽爹土。三九已至甥雕,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間胀茵,已是汗流浹背社露。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留琼娘,地道東北人峭弟。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像轨奄,于是被迫代替她去往敵國和親孟害。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內容