天天看點

java8的新時間與日期的API

新的時間和日期API

在Java 8之前,所有關于時間和日期的API都存在各種使用方面的缺陷,主要有:

  • Java的

    java.util.Date

    java.util.Calendar

    類易用性差,不支援時區,而且他們都不是線程安全的;
  • 用于格式化日期的類

    DateFormat

    被放在

    java.text

    包中,它是一個抽象類,是以我們需要執行個體化一個

    SimpleDateFormat

    對象來處理日期格式化,并且

    DateFormat

    也是非線程安全,這意味着如果你在多線程程式中調用同一個

    DateFormat

    對象,會得到意想不到的結果。
  • 對日期的計算方式繁瑣,而且容易出錯,因為月份是從0開始的,從

    Calendar

    中擷取的月份需要加一才能表示目前月份。

LocalDate,LocalTime

初始化:

LocalDate ld = LocalDate.of(2018,9,9);

LocalTime lt = LocalTime.of(12,12,12);

擷取目前時間:

ld = LocalDate.now();

lt = LocalTime.now();

檢視詳情

int year = ld.getYear();

Month month = ld.getMonth();

int day = ld.getDayOfMonth();

DayOfWeek weekday = ld.getDayOfWeek();

int hour = lt.getHour();

int minute = lt.getMinute();

int second = lt.getSecond();

LocalDateTime

初始化

LocalDate ld = LocalDate.of(2018,9,9);

LocalTime lt = LocalTime.of(12,12,12);

LocalDateTime ldt = ld.atTime(lt);

LocalDateTime ldt1 = lt.atDate(ld);

localDateTime => localDate/localTime

ld = ldt.toLocalDate

lt = ldt.toLocalTime

parse

String => LocalDateTime

String s = “2013-01-02 12:22:22”;

DateTimeFormatter df = DateTimeFormatter.ofPattern(“yyyy-MM-dd HH:mm:ss”);

LocalDateTime ldt = LocalDateTime.parse(s,df);

String => LocalDate/LocalTime

String sdate = “2013-01-02”;

String stime = “22:22:22”;

LocalDate ld = LocalDate.parse(sdate);

LocalTime lt = LocalTime.parse(stime);

Instant

Instant

用于表示一個時間戳,它與我們常使用的

System.currentTimeMillis()

有些類似,不過Instant可以精确到納秒(Nano-Second),

System.currentTimeMillis()

方法隻精确到毫秒(Milli-Second)。如果檢視

Instant

源碼,發現它的内部使用了兩個常量,seconds表示從1970-01-01 00:00:00開始到現在的秒數,nanos表示納秒部分(nanos的值不會超過999,999,999)。

Instant

除了使用

now()

方法建立外,還可以通過

ofEpochSecond

方法建立:

Instant instant = Instant.ofEpochSecond(120, 100000);

ofEpochSecond()

方法的第一個參數為秒,第二個參數為納秒,上面的代碼表示從1970-01-01 00:00:00開始後兩分鐘的10萬納秒的時刻

Duration

Duration

的内部實作與

Instant

類似,也是包含兩部分:seconds表示秒,nanos表示納秒。兩者的差別是

Instant

用于表示一個時間戳(或者說是一個時間點),而

Duration

表示一個時間段,是以

Duration

類中不包含

now()

靜态方法。可以通過

Duration.between()

方法建立

Duration

對象:

LocalDateTime from = LocalDateTime.of(2017, Month.JANUARY, 5, 10, 7, 0); // 2017-01-05 10:07:00

LocalDateTime to = LocalDateTime.of(2017, Month.FEBRUARY, 5, 10, 7, 0); // 2017-02-05 10:07:00

Duration duration = Duration.between(from, to); // 表示從 2017-01-05 10:07:00 到 2017-02-05 10:07:00 這段時間

long days = duration.toDays(); // 這段時間的總天數

long hours = duration.toHours(); // 這段時間的小時數

long minutes = duration.toMinutes(); // 這段時間的分鐘數

long seconds = duration.getSeconds(); // 這段時間的秒數

long milliSeconds = duration.toMillis(); // 這段時間的毫秒數

long nanoSeconds = duration.toNanos(); // 這段時間的納秒數

Duration

對象還可以通過

of()

方法建立,該方法接受一個時間段長度,和一個時間機關作為參數:

Duration duration1 = Duration.of(5, ChronoUnit.DAYS); // 5天

Duration duration2 = Duration.of(1000, ChronoUnit.MILLIS); // 1000毫秒

Period

Period

在概念上和

Duration

類似,差別在于

Period

是以年月日來衡量一個時間段,比如2年3個月6天:

Period period = Period.of(2, 3, 6);

Period

對象也可以通過

between()

方法建立,值得注意的是,由于

Period

是以年月日衡量時間段,是以

between()

方法隻能接收

LocalDate

類型的參數:

Period period2 = Period.between(LocalDate.of(2017, 1, 5),LocalDate.of(2017, 2, 5));

Period

對象可以獲得時間段的長度:

int dayP2 = period2.getDays();

int monthP2 = period2.getMonths();

int yearP2 = period2.getYears()

注意,

Period

獲得的時間段長度不是總的長度,如:

Period period2 = Period.between(LocalDate.of(2017, 1, 5),LocalDate.of(2017, 2, 5));

int day = period2.getDays(); // day=0

時區

參考

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalUnit;

public class LocalDateAndTime {
    public static void main(String[] args) throws Exception {
        LocalDate ld = LocalDate.of(2019,3,10);
        LocalTime lt = LocalTime.of(11,12,12);
        int year = ld.getYear();
        System.out.println("年:" + year);
        Month month = ld.getMonth();
        System.out.println("月:" + month);
        int day = ld.getDayOfMonth();
        System.out.println("日" + day);
        DayOfWeek weekday = ld.getDayOfWeek();
        System.out.println("周" + weekday);
        int hour = lt.getHour();
        System.out.println("小時" + hour);
        int minute = lt.getMinute();
        System.out.println("分鐘" + minute);
        int second = lt.getSecond();
        System.out.println("秒" + second);
        System.out.println(ld);
        System.out.println(lt);

        String sdate = "2013-01-02";
        String stime = "22:22:22";
        ld = LocalDate.parse(sdate);
        lt = LocalTime.parse(stime);
        System.out.println(ld);
        System.out.println(lt);
        ld = LocalDate.now();
        lt = LocalTime.now();
        System.out.println(ld);
        System.out.println(lt);
        System.out.println("=========");



        String s = "2013-01-02 12:22:22";
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime ldt = LocalDateTime.parse(s,df);
        System.out.println(ldt);
        ldt = lt.atDate(ld);
        System.out.println(ldt);
        ldt = ld.atTime(lt);
        System.out.println(ldt);

        ld = ldt.toLocalDate();
        lt = ldt.toLocalTime();
        System.out.println(ld);
        System.out.println(lt);
        System.out.println("=========");



        LocalDate hd = LocalDate.of(2019,3,10);
        System.out.println(ld == hd);
        System.out.println(ld.equals(hd));
        LocalDateTime ss = ld.atStartOfDay();
        System.out.println(ld);
        System.out.println(ld.withMonth(1));
        System.out.println(ld.withDayOfMonth(1));

        LocalDate md = LocalDate.now();
        System.out.println(ld);
        System.out.println(md);
        Long i = ld.toEpochDay()-md.toEpochDay()+1;
        Long j = hd.toEpochDay()-ld.toEpochDay();
        System.out.println(i);
        System.out.println(j);
        System.out.println((double)i/j*3);
        System.out.println(Math.floor((double)i/j*3));
        System.out.println(Math.ceil((double)i/j*3));
        System.out.println("=========");



        LocalDateTime from = LocalDateTime.of(2017, Month.JANUARY, 5, 10, 7, 0);    // 2017-01-05 10:07:00
        LocalDateTime to = LocalDateTime.of(2017, Month.FEBRUARY, 5, 10, 7, 0);     // 2017-02-05 10:07:00
        Duration duration = Duration.between(from, to);     // 表示從 2017-01-05 10:07:00 到 2017-02-05 10:07:00 這段時間

        long days = duration.toDays();              // 這段時間的總天數
        System.out.println("天數" + days);
        long hours = duration.toHours();            // 這段時間的小時數
        System.out.println("小時數" + hours);
        long minutes = duration.toMinutes();        // 這段時間的分鐘數
        System.out.println("分鐘數" + minutes);
        long seconds = duration.getSeconds();       // 這段時間的秒數
        System.out.println("秒數" + seconds);
        long milliSeconds = duration.toMillis();    // 這段時間的毫秒數
        System.out.println("毫秒數" + milliSeconds);
        long nanoSeconds = duration.toNanos();      // 這段時間的納秒數
        System.out.println("納秒數" + nanoSeconds);

        Duration duration1 = Duration.of(5, ChronoUnit.DAYS);       // 5天
        long days1 = duration1.toDays();              // 這段時間的總天數
        System.out.println("天數1:" + days1);
        Duration duration2 = Duration.of(1000, ChronoUnit.MILLIS);  // 1000毫秒
        long milliSeconds2 = duration2.toMillis();    // 這段時間的毫秒數
        System.out.println("毫秒數2:" + milliSeconds2);
        System.out.println("=========");


        Period period = Period.of(2, 3, 6);
        int dayP1 = period.getDays();
        int monthP1 = period.getMonths();
        int yearP1 = period.getYears();
        System.out.println("Period Days:" + dayP1 + ", Months:" + monthP1 + ", Years:" + yearP1);
        // 2017-01-05 到 2017-02-05 這段時間
        Period period2 = Period.between(LocalDate.of(2017, 1, 5),LocalDate.of(2017, 2, 5));
        int dayP2 = period2.getDays();
        int monthP2 = period2.getMonths();
        int yearP2 = period2.getYears();
        System.out.println("Period2 Days:" + dayP2 + ", Months:" + monthP2 + ", Years:" + yearP2);
        period2 = Period.between(LocalDate.of(2017, 1, 4),LocalDate.of(2020, 3, 5));
        dayP2 = period2.getDays();
        monthP2 = period2.getMonths();
        yearP2 = period2.getYears();
        System.out.println("Period2 Days:" + dayP2 + ", Months:" + monthP2 + ", Years:" + yearP2);
        System.out.println("Period獲得的時間段長度不是總的長度,比如獲得的天數,與月份和年份無關");
        System.out.println("=========");

    }
}