一篇文章弄懂Java8中的時間處理

前言

java8借鑒瞭第三方日期庫joda很多的優點

java.time包

類名 描述
Instant 時間戳
Duration 持續時間,時間差
LocalDate 隻包含日期,比如:2020-05-20
LocalTime 隻包含時間,比如:13:14:00
LocalDateTime 包含日期和時間,比如:2020-05-20 13:14:00
Period 時間段
ZoneOffset 時區偏移量,比如:+8:00
ZonedDateTime 帶時區的時間
Clock 時鐘,比如獲取目前美國紐約的時間

java.time.format包

類名 描述
DateTimeFormatter 時間格式化

Java8提供瞭全新的時間處理框架,這裡就可以完全丟棄之前的Date、Calendar瞭。

具體的API的使用都是比較簡單的。這裡就不展開介紹瞭。

這裡主要介紹下一些主要的類

LocalDateTime

我們一般常用的就是這個瞭,用這個來表示日期時間。如LocalDateTime.now()就可以基於當前默認時區得到當前的日期時間。

由於全球有好多時區,同一個日期時間,在不同的時區,反映到時間軸上是不同的。

LocalDateTime類型的日期時間是沒包含時區,所以它不能對應到時間軸上。說的直白點就是LocalDateTime不能轉換成自 1970-01-01T00:00:00Z 紀元以來的毫秒數

ZonedDateTime

ZonedDateTime可以理解就是在LocalDateTime的基礎上添加上時區,所以它是可以反映到時間軸上的。

下面用夏令時舉個例子來看看LocalDateTime和LocalDateTime的區別。

夏令時是什麼這裡就不展開瞭,具體可以網上查下。看看我國1986開始的夏令時。

簡單來說就是在夏令時開始的時候,將時鐘向後撥1個小時。對應我國1986年開始的夏令時的做法,就是在每年四月中旬的第一個星期日當時鐘到達凌晨2點時,直接將時鐘撥到凌晨3點。也就是凌晨1點和凌晨3點之間之差1個小時。

由於1986年是開始實施的,所以1986年的夏令時是1986年5月4日開始的。

我們看看1987年的夏令時開始

根據我國當時的夏令時政策,1987年應該是1987年4月12日開始的。具體來說就是在1987-04-12 01:00:00 過一個小時後,時間應該是1987-04-12 03:00:00

        LocalDateTime localDateTime = LocalDateTime.of(1987, 4, 12, 1, 0, 0, 0);
        System.out.println(localDateTime);
        System.out.println(localDateTime.plusHours(1));

執行上面的代碼就可以看到當1987-04-12 01:00:00增加1小時後,時間是1987-04-12 02:00:00。

這個也好理解,因為LocalDateTime並沒有包含時區,1987-04-12 02:00:00這個夏令時隻是中國的,並不是全球統一的,如果1987-04-12 02:00:00將直接變成1987-04-12 03:00:00放到中國以外的其他國傢就是錯誤的。

        ZonedDateTime zonedDateTime = ZonedDateTime.of(1987, 4, 12, 1, 0, 0, 0, ZoneId.systemDefault());
        System.out.println(zonedDateTime);
        System.out.println(zonedDateTime.plusHours(1));

執行上面的代碼可以看到當1987-04-12 01:00:00增加1小時後,時間變成瞭是1987-04-12 03:00:00。這個也就能說明問題瞭。

同時從打印結果也能看到時區自動從+08:00[Asia/Shanghai]變成瞭+09:00[Asia/Shanghai]

Instant

Instant表示時間軸上的一個瞬時時間,簡單來說就是表示自 1970-01-01T00:00:00Z 紀元以來的秒數、毫秒數等等

ZonedDateTime和Instant都能對應到時間軸上,所以它們兩個是可以相互轉化的。

        Instant instant = zonedDateTime.toInstant();
        ZonedDateTime zonedDateTime1 = instant.atZone(zonedDateTime.getZone());

其他一些常用的各種類型之間轉化的API

        //ZonedDateTime 轉  Instant
        Instant instant = ZonedDateTime.now().toInstant();

 
        //獲取UTC毫秒數
        long epochMilli = instant.toEpochMilli();
        

        //Instant 轉  ZonedDateTime
        ZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());

        //字符串 轉  ZonedDateTime
        ZonedDateTime zonedDateTime2 = ZonedDateTime.parse(zonedDateTime.toString());

        //基於UTC 偏移的毫秒數
        int totalSeconds = zonedDateTime.getOffset().getTotalSeconds();

        //Instant 轉  LocalDateTime
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

        //LocalDateTime 轉  ZonedDateTime
        ZonedDateTime zonedDateTime1 = localDateTime.atZone(ZoneId.systemDefault());


        ZoneRules zoneRules = ZoneId.systemDefault().getRules();

        //判斷是否是夏令時時間
        boolean daylightSavings = zoneRules.isDaylightSavings(instant);


        Calendar calendar = Calendar.getInstance(TimeZone.getDefault());
        //Calendar 轉 Instant
        Instant instant1 = calendar.toInstant();

        //Calendar  轉   ZonedDateTime
        Calendar now = Calendar.getInstance();
        ZonedDateTime zdt = ZonedDateTime.ofInstant(now.toInstant(), ZoneId.systemDefault()));

        //Date 轉 Instant
        Date date = new Date();
        Instant inst = date.toInstant();

        // Instant 轉 Date
        Date newDate = Date.from(inst);

        //GregorianCalendar 轉 ZonedDateTime
        GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
        TimeZone tz = cal.getTimeZone();
        ZonedDateTime zdt1 = cal.toZonedDateTime();
        
        //ZonedDateTime 轉 GregorianCalendar
        GregorianCalendar newCal = GregorianCalendar.from(zdt1);

        LocalDateTime ldt = zdt.toLocalDateTime();
        LocalDate date2 = zdt.toLocalDate();
        LocalTime time2 = zdt.toLocalTime();

更詳細的資料,還是看官方的文檔吧。https://docs.oracle.com/javase/tutorial/datetime/index.html

總結

到此這篇關於Java8中時間處理的文章就介紹到這瞭,更多相關Java8時間處理內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: