因爲歷史緣由,在以前的版本里不管Date仍是Calendar都很是難用,尤爲在涉及到日期計算方面,並且其中日期轉換的類DateForamt仍是非線程安全的。
也正由於難用,通常項目裏面都引入第三方的類庫操做時間,例如Joda-Time和apache-lang包的DateUtils類。
基於上述種種緣由,Java8新增了java.time包,其中包含了新的處理時間的類來解決上述問題。java
1.主要類:apache
LocalDate、LocalTime、 Instant、 Duration 以及 Period安全
LocalDate和LocalTime及LocalDateTimespa
eg:線程
@Test public void test8time() { // LocalDate // 建立LocalDate LocalDate localDate1 = LocalDate.of(2018, 7, 26); LocalDate localDate2 = LocalDate.now(); LocalDate localDate3 = LocalDate.parse("2014-03-18"); System.out.println(localDate1 + " " + localDate2 + " " + localDate3); int year = localDate1.getYear(); Month month = localDate1.getMonth(); int day = localDate1.getDayOfMonth(); DayOfWeek dow = localDate1.getDayOfWeek(); int len = localDate1.lengthOfMonth(); // 是否閏年 boolean leap = localDate1.isLeapYear(); System.out.println(year); System.out.println(month); System.out.println(day); System.out.println(dow); System.out.println(len); System.out.println(leap); // 經過傳遞 TemporalField 來換取時間 相似於工廠模式 // ChronoField此枚舉實現了TemporalField接口 int fieldYear = localDate1.get(ChronoField.YEAR); int fieldMonth = localDate1.get(ChronoField.MONTH_OF_YEAR); int fieldDay = localDate1.get(ChronoField.DAY_OF_MONTH); System.out.println(fieldYear); System.out.println(fieldMonth); System.out.println(fieldDay); // LocalTime // 建立LocalTime LocalTime time = LocalTime.of(11, 10, 20); LocalTime time1 = LocalTime.now(); LocalTime time2 = LocalTime.parse("11:10:20"); System.out.println(time + " " + time1 + " " + time2); System.out.println(String.join(" ", time.toString(), time1.toString(), time2.toString())); int hour = time.getHour(); int minute = time.getMinute(); int second = time.getSecond(); System.out.println(hour); System.out.println(minute); System.out.println(second); int fieldHour = time.get(ChronoField.HOUR_OF_DAY); int fieldMinute = time.get(ChronoField.MINUTE_OF_HOUR); int fieldSecond = time.get(ChronoField.SECOND_OF_MINUTE); System.out.println(fieldHour); System.out.println(fieldMinute); System.out.println(fieldSecond); // 合併時間 建立LocalDateTime LocalDateTime ldt = LocalDateTime.of(localDate1, time); System.out.println(ldt); LocalDateTime ldt1 = LocalDateTime.now(); System.out.println(ldt1); LocalDate ld = ldt1.toLocalDate(); LocalTime lt = ldt1.toLocalTime(); System.out.println(ld); System.out.println(lt); }
Instantcode
@Test public void testInstant() { // Instant 是以Unix元年時間開始所經歷的秒數進行計算 Instant instant = Instant.ofEpochSecond(1); System.out.println(instant); Instant instant1 = Instant.now(); System.out.println(instant1); }
Duration和Period
Duration類主要用於以秒和納秒衡量時間的長短。
Period類主要以年、月或者日的方式衡量時間長短。orm
@Test public void testDp() { LocalTime time1 = LocalTime.now(); LocalTime time2 = LocalTime.now(); LocalDateTime dateTime1 = LocalDateTime.now(); LocalDateTime dateTime2 = LocalDateTime.now(); Instant instant1 = Instant.now(); Instant instant2 = Instant.now(); Duration d1 = Duration.between(time1, time2); Duration d2 = Duration.between(dateTime1, dateTime2); Duration d3 = Duration.between(instant1, instant2); System.out.println(d1); System.out.println(d2); System.out.println(d3); // 建立 Duration threeMinutes = Duration.ofMinutes(3); Duration threeMinutes1 = Duration.of(3, ChronoUnit.MINUTES); Period tenDays = Period.ofDays(10); Period threeWeeks = Period.ofWeeks(3); Period twoYearsSixMonthsOneDay = Period.of(2, 6, 1); System.out.println(threeMinutes); System.out.println(threeMinutes1); System.out.println(tenDays); System.out.println(threeWeeks); System.out.println(twoYearsSixMonthsOneDay); }
2.對日期的操做對象
eg:blog
@Test public void operaTime() { // 直接操做 LocalDate date1 = LocalDate.of(2018, 7, 26); LocalDate date2 = date1.withYear(2017); LocalDate date3 = date2.withDayOfMonth(25); LocalDate date4 = date3.with(ChronoField.MONTH_OF_YEAR, 4); LocalDate date5 = date1.withYear(2017).withMonth(4).withDayOfMonth(25); System.out.println(date4); System.out.println(date5); // 相對操做 LocalDate date6 = LocalDate.of(2018, 7, 26); LocalDate date7 = date6.plusWeeks(1); LocalDate date8 = date7.minusYears(3); LocalDate date9 = date8.plus(6, ChronoUnit.MONTHS); LocalDate date10 = date6.plusWeeks(1).minusYears(3).plusMonths(6); System.out.println(date9); System.out.println(date10); // 使用 TemporalAdjuster 操做日期 LocalDate date11 = LocalDate.now().with(lastDayOfMonth()); System.out.println(date11); }
TemporalAdjuster接口裏面的靜態方法
dayOfWeekInMonth 建立一個新的日期,它的值爲同一個月中每一週的第幾天
firstDayOfMonth 建立一個新的日期,它的值爲當月的第一天
firstDayOfNextMonth 建立一個新的日期,它的值爲下月的第一天
firstDayOfNextYear 建立一個新的日期,它的值爲明年的第一天
firstDayOfYear 建立一個新的日期,它的值爲當年的第一天
firstInMonth 建立一個新的日期,它的值爲同一個月中,第一個符合星期幾要求的值
lastDayOfMonth 建立一個新的日期,它的值爲當月的最後一天
lastDayOfNextMonth 建立一個新的日期,它的值爲下月的最後一天
lastDayOfNextYear 建立一個新的日期,它的值爲明年的最後一天
lastDayOfYear 建立一個新的日期,它的值爲今年的最後一天
lastInMonth 建立一個新的日期,它的值爲同一個月中,最後一個符合星期幾要求的值
next/previous 建立一個新的日期,並將其值設定爲日期調整後或者調整前,第一個符合指定星期幾要求的日期
nextOrSame/previousOrSame 建立一個新的日期,並將其值設定爲日期調整後或者調整前,第一個符合指定星期幾要求的日期,若是該日期已經符合要求,直接返回該對象接口
對日期的解析DateTimeFormatter
eg:
@Test public void testFormat() { LocalDate ld = LocalDate.now(); String ld1 = ld.format(DateTimeFormatter.BASIC_ISO_DATE); System.out.println(ld1); LocalDate ld2 = LocalDate.parse("20180726", DateTimeFormatter.BASIC_ISO_DATE); System.out.println(ld2); LocalDateTime ld3 = LocalDateTime.now(); ZoneId bjZone = ZoneId.of("Asia/Shanghai"); // ZoneId zoneId = TimeZone.getDefault().toZoneId(); ZonedDateTime adt = ld.atStartOfDay(bjZone); ZonedDateTime adt1 = ld3.atZone(bjZone); Instant instant = Instant.now(); ZonedDateTime adt2 = instant.atZone(bjZone); System.out.println(adt); System.out.println(adt1); System.out.println(adt2); }
3.Date, LocalDate, LocalDateTime和Instant之間的相互轉換
Date類新增了from和toInstant兩個方法實現和Instant之間的互轉,在經過Instant這個橋樑轉換成LocalDate和LocalDateTime。
@Test public void testDate2Local() { // Date轉成LocalDateTime和LocalDate Date date = new Date(); Instant instant = date.toInstant(); ZoneId zone = ZoneId.systemDefault(); LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zone); LocalDate localDate = localDateTime.toLocalDate(); System.out.println(localDate); System.out.println(localDateTime); // LocalDate和LocalDateTime轉成Date LocalDateTime localDateTime1 = LocalDateTime.now(); ZonedDateTime zonedDateTime = localDateTime1.atZone(ZoneId.systemDefault()); Instant instant1 = zonedDateTime.toInstant(); Date date1 = Date.from(instant1); System.out.println(date1); LocalDate localDate1 = LocalDate.now(); LocalDateTime localDateTime2 = localDate1.atStartOfDay(); ZonedDateTime zonedDateTime1 = localDateTime2.atZone(ZoneId.systemDefault()); Instant instant2 = zonedDateTime1.toInstant(); Date date2 = Date.from(instant2); System.out.println(date2); }
總結:
新的API是時間處理變的簡單,也解決了線程安全的問題,但願你們都能慢慢轉過來。
參考:
《Java8實戰》