Java8簡明學習之新時間日期API

  因爲歷史緣由,在以前的版本里不管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實戰》

相關文章
相關標籤/搜索