Java 8 推出了全新的日期時間API,在教程中咱們將經過一些簡單的實例來學習如何使用新API。java
Java處理日期、日曆和時間的方式一直爲社區所詬病,將 java.util.Date設定爲可變類型,以及SimpleDateFormat的非線程安全使其應用很是受限。整理了一份Java面試寶典完整版PDF面試
新API基於ISO標準日曆系統,java.time包下的全部類都是不可變類型並且線程安全。安全
示例1:Java 8中獲取今天的日期ide
Java 8 中的 LocalDate 用於表示當天日期。和java.util.Date不一樣,它只有日期,不包含時間。當你僅須要表示日期時就用這個類。工具
package com.shxt.demo02; import java.time.LocalDate; public class Demo01 { public static void main(String[] args) { LocalDate today = LocalDate.now(); System.out.println("今天的日期:"+today); } }
package com.shxt.demo02; import java.time.LocalDate; public class Demo02 { public static void main(String[] args) { LocalDate today = LocalDate.now(); int year = today.getYear(); int month = today.getMonthValue(); int day = today.getDayOfMonth(); System.out.println("year:"+year); System.out.println("month:"+month); System.out.println("day:"+day); } }
咱們經過靜態工廠方法now()很是容易地建立了當天日期,你還能夠調用另外一個有用的工廠方法LocalDate.of()建立任意日期, 該方法須要傳入年、月、日作參數,返回對應的LocalDate實例。這個方法的好處是沒再犯老API的設計錯誤,好比年度起始於1900,月份是從0開 始等等。單元測試
package com.shxt.demo02; import java.time.LocalDate; public class Demo03 { public static void main(String[] args) { LocalDate date = LocalDate.of(2018,2,6); System.out.println("自定義日期:"+date); } }
package com.shxt.demo02; import java.time.LocalDate; public class Demo04 { public static void main(String[] args) { LocalDate date1 = LocalDate.now(); LocalDate date2 = LocalDate.of(2018,2,5); if(date1.equals(date2)){ System.out.println("時間相等"); }else{ System.out.println("時間不等"); } } }
package com.shxt.demo02; import java.time.LocalDate; import java.time.MonthDay; public class Demo05 { public static void main(String[] args) { LocalDate date1 = LocalDate.now(); LocalDate date2 = LocalDate.of(2018,2,6); MonthDay birthday = MonthDay.of(date2.getMonth(),date2.getDayOfMonth()); MonthDay currentMonthDay = MonthDay.from(date1); if(currentMonthDay.equals(birthday)){ System.out.println("是你的生日"); }else{ System.out.println("你的生日尚未到"); } } }
只要當天的日期和生日匹配,不管是哪一年都會打印出祝賀信息。你能夠把程序整合進系統時鐘,看看生日時是否會受到提醒,或者寫一個單元測試來檢測代碼是否運行正確。學習
package com.shxt.demo02; import java.time.LocalTime; public class Demo06 { public static void main(String[] args) { LocalTime time = LocalTime.now(); System.out.println("獲取當前的時間,不含有日期:"+time); } }
能夠看到當前時間就只包含時間信息,沒有日期測試
經過增長小時、分、秒來計算未來的時間很常見。Java 8除了不變類型和線程安全的好處以外,還提供了更好的plusHours()方法替換add(),而且是兼容的。注意,這些方法返回一個全新的LocalTime實例,因爲其不可變性,返回後必定要用變量賦值。this
package com.shxt.demo02; import java.time.LocalTime; public class Demo07 { public static void main(String[] args) { LocalTime time = LocalTime.now(); LocalTime newTime = time.plusHours(3); System.out.println("三個小時後的時間爲:"+newTime); } }
和上個例子計算3小時之後的時間相似,這個例子會計算一週後的日期。LocalDate日期不包含時間信息,它的plus()方法用來增長天、周、月,ChronoUnit類聲明瞭這些時間單位。因爲LocalDate也是不變類型,返回後必定要用變量賦值。線程
package com.shxt.demo02; import java.time.LocalDate; import java.time.temporal.ChronoUnit; public class Demo08 { public static void main(String[] args) { LocalDate today = LocalDate.now(); System.out.println("今天的日期爲:"+today); LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS); System.out.println("一週後的日期爲:"+nextWeek); } }
能夠看到新日期離當天日期是7天,也就是一週。你能夠用一樣的方法增長1個月、1年、1小時、1分鐘甚至一個世紀,更多選項能夠查看Java 8 API中的ChronoUnit類
利用minus()方法計算一年前的日期
package com.shxt.demo02; import java.time.LocalDate; import java.time.temporal.ChronoUnit; public class Demo09 { public static void main(String[] args) { LocalDate today = LocalDate.now(); LocalDate previousYear = today.minus(1, ChronoUnit.YEARS); System.out.println("一年前的日期 : " + previousYear); LocalDate nextYear = today.plus(1, ChronoUnit.YEARS); System.out.println("一年後的日期:"+nextYear); } }
Java 8增長了一個Clock時鐘類用於獲取當時的時間戳,或當前時區下的日期時間信息。之前用到System.currentTimeInMillis()和TimeZone.getDefault()的地方均可用Clock替換。
package com.shxt.demo02; import java.time.Clock; public class Demo10 { public static void main(String[] args) { // Returns the current time based on your system clock and set to UTC. Clock clock = Clock.systemUTC(); System.out.println("Clock : " + clock.millis()); // Returns time based on system clock zone Clock defaultClock = Clock.systemDefaultZone(); System.out.println("Clock : " + defaultClock.millis()); } }
另外一個工做中常見的操做就是如何判斷給定的一個日期是大於某天仍是小於某天?在Java 8中,LocalDate類有兩類方法isBefore()和isAfter()用於比較日期。調用isBefore()方法時,若是給定日期小於當前日期則返回true。
package com.shxt.demo02; import java.time.LocalDate; import java.time.temporal.ChronoUnit; public class Demo11 { public static void main(String[] args) { LocalDate today = LocalDate.now(); LocalDate tomorrow = LocalDate.of(2018,2,6); if(tomorrow.isAfter(today)){ System.out.println("以後的日期:"+tomorrow); } LocalDate yesterday = today.minus(1, ChronoUnit.DAYS); if(yesterday.isBefore(today)){ System.out.println("以前的日期:"+yesterday); } } }
Java 8不只分離了日期和時間,也把時區分離出來了。如今有一系列單獨的類如ZoneId來處理特定時區,ZoneDateTime類來表示某時區下的時間。這在Java 8之前都是 GregorianCalendar類來作的。下面這個例子展現瞭如何把本時區的時間轉換成另外一個時區的時間。
package com.shxt.demo02; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZonedDateTime; public class Demo12 { public static void main(String[] args) { // Date and time with timezone in Java 8 ZoneId 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); } }
與 MonthDay檢查重複事件的例子類似,YearMonth是另外一個組合類,用於表示信用卡到期日、FD到期日、期貨期權到期日等。還能夠用這個類獲得 當月共有多少天,YearMonth實例的lengthOfMonth()方法能夠返回當月的天數,在判斷2月有28天仍是29天時很是有用。
package com.shxt.demo02; import java.time.*; public class Demo13 { public static void main(String[] args) { YearMonth currentYearMonth = YearMonth.now(); System.out.printf("Days in month year %s: %d%n", currentYearMonth, currentYearMonth.lengthOfMonth()); YearMonth creditCardExpiry = YearMonth.of(2019, Month.FEBRUARY); System.out.printf("Your credit card expires on %s %n", creditCardExpiry); } }
package com.shxt.demo02; import java.time.LocalDate; public class Demo14 { public static void main(String[] args) { LocalDate today = LocalDate.now(); if(today.isLeapYear()){ System.out.println("This year is Leap year"); }else { System.out.println("2018 is not a Leap year"); } } }
有一個常見日期操做是計算兩個日期之間的天數、週數或月數。在Java 8中能夠用java.time.Period類來作計算。
下面這個例子中,咱們計算了當天和未來某一天之間的月數。
package com.shxt.demo02; import java.time.LocalDate; import java.time.Period; public class Demo15 { public static void main(String[] args) { LocalDate today = LocalDate.now(); LocalDate java8Release = LocalDate.of(2018, 12, 14); Period periodToNextJavaRelease = Period.between(today, java8Release); System.out.println("Months left between today and Java 8 release : " + periodToNextJavaRelease.getMonths() ); } }
Instant類有一個靜態工廠方法now()會返回當前的時間戳,以下所示:
package com.shxt.demo02; import java.time.Instant; public class Demo16 { public static void main(String[] args) { Instant timestamp = Instant.now(); System.out.println("What is value of this instant " + timestamp.toEpochMilli()); } }
時間戳信息裏同時包含了日期和時間,這和java.util.Date很像。實際上Instant類確實等同於 Java 8以前的Date類,你可使用Date類和Instant類各自的轉換方法互相轉換,例如:Date.from(Instant) 將Instant轉換成java.util.Date,Date.toInstant()則是將Date類轉換成Instant類。整理了一份Java面試寶典完整版PDF
package com.shxt.demo02; import java.time.LocalDate; import java.time.format.DateTimeFormatter; public class Demo17 { public static void main(String[] args) { String dayAfterTommorrow = "20180205"; LocalDate formatted = LocalDate.parse(dayAfterTommorrow, DateTimeFormatter.BASIC_ISO_DATE); System.out.println(dayAfterTommorrow+" 格式化後的日期爲: "+formatted); } }
package com.shxt.demo02; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class Demo18 { public static void main(String[] args) { LocalDateTime date = LocalDateTime.now(); DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); //日期轉字符串 String str = date.format(format1); System.out.println("日期轉換爲字符串:"+str); DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); //字符串轉日期 LocalDate date2 = LocalDate.parse(str,format2); System.out.println("日期類型:"+date2); } }