引言
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新特性
- jdk8新特性之一Lambda表達式
- jdk8新特性之二方法引用
- jdk8新特性之三函數(shù)式接口
- jdk8新特性之四默認方法
- jdk8新特性之五Stream API
- jdk8新特性之六Optional類
- jdk8新特性之七Nashorn JavaScript
- jdk8新特性之八日期時間API
- 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/