新款時間日期API已上線

歷史

   早期,Java 對時間和日期的使用每每重度依賴 java.util.Datejava.util.Calendar。 惋惜的是,這2個api 自己不夠健壯,有相似線程不安全等諸多問題,因而乎2000年左右,市面上出現了不少用於處理時間類的框架,如Joda-Time。 在Java 8 時代 官方爲JDK開發新的時間/日期API的進程:JSR-310,啓動了。因而就出現了新一套健壯的API。java

 

Roadmap

新的API

Java 8  中 新的API 包括了 5個包linux

  • java.time數據庫

  • java.time.chronoapi

  • java.time.format安全

  • java.time.temporal服務器

  • java.time.zone框架

    java.time 是基礎包,裏面包含了 時間 日期的 基礎類 如  LocalDate, LocalTime等工具

    java.time.chrono  有點像linux 的守護進程 chronyd  用來訪問不一樣的時間服務器。spa

    java.time.format 顧名思義用來格式化和轉換日期時間線程

    java.time.temporal 可能也想不出好名字吧,裏面都是些底層擴展類

    java.time.zone 用來對各時區的支持

 

1. 時間線

     Java8中 引入了時間線的概念,時間是接二連三,抽象成一條線,線上的點表示某一時刻。

一班來講,這個設定主要是面對機器的,不用關心具體的年月日時分秒,內部以秒或者納秒錶示。

1.1 時間點 Instant

      時間點是表示時間的某時某刻的,相對的它是時間線上的一點。

java.time包經過值類型Instant提供機器視圖。

Instant表示時間線上的一點,而不須要任何上下文信息(時區,年份)

概念上講,它只是簡單的表示自1970年1月1日0時0分0秒(UTC)開始的秒數。

由於java.time包是基於納秒計算的,因此Instant的精度能夠達到納秒級。

Instant start = Instant.now()
Instant end = Instant.now()

 

1.2 Period

    Period表示以年、月、日衡量的時長。例如,「3年2個月零6天」。表示的是一段時間 以日月年爲單位.

在日期的操做中 能夠做爲參數來做爲日期的加減運算。

Period period = Period.now()

1.3 Duration

    Duration表示以秒和納秒爲基準的時長。例如,「23.6秒」。Duration表示的是一段時間 以 分十秒爲單位. 在時間的操做中 能夠做爲參數 來做爲時間的加減運算。

Duration duration = Duration.()System..println(duration)System..println(duration.getSeconds())

 

--------------------------TBD-----------------------

 

2. 不變模式  Immutable

    新的API 提倡採用不變模式,雖然時間是一直在變化的,某事某刻的表示它是固定的,哪怕對日期進行加減,操做以後的日期則表示新的時刻。

   因此Java時間相關的API,在原始時間對象上 作相應的加減操做,原來的日期對象不變,會產生一個新的對象。

3. 本地時間

3.1 本地日期 LocalDate

 LocalDate 是新API 中 最基礎也是最重要的類, 它是一個 不可變的類(final 修飾),本地日期只是一個術語,用來表示一個具體日期,不一樣地區的日期可能不一樣 故採用 local 這個術語,其實它是時區無關的,這個類沒有包含任什麼時候區信息,就簡單的認爲一個日期便可。

3.1.1 日期的建立

   日期的建立 採用了工廠方法的模式,全部的建立方法都是私有的,經常使用的是調用對外開放的方法of 來生成一個 日期實例

LocalDate localDate = LocalDate.of(int year, Month month, int dayOfMonth);
LocalDate localDate = LocalDate.of(int year, int month, int dayOfMonth);

 

3.1.2 日期的經常使用方法 - 讀

 

    LocalDate 的toString方法 默認返回的日期格式  採用 ISO-8601標準日期  即   YYYY-MM-DD

System.out.println(localDate); //2016-02-18

   LocalDate 還提供了其餘不少經常使用方法來得到日期的相關值

System.out.println(localDate.getMonth());       // Month FEBRUARY 當前月
System.out.println(localDate.getMonthValue());  // int  1 當前月的數值

System.out.println(localDate.getDayOfMonth());  // int 18 當前月第X天
System.out.println(localDate.getDayOfWeek());   // DayOfWeek  Monday 當前周的天
System.out.println(localDate.getDayOfYear());   // int 49 當前年的第X天

System.out.println(localDate.getYear());        // int 2016 當前年

System.out.println(localDate.lengthOfYear());   // int 366 當前年共有多少天
System.out.println(localDate.lengthOfMonth());  // int 29  當前月共有多少天

3.1.3 日期的經常使用方法 - 操做

LocalDate 是一個不可變的類,它的每一次操做 都會伴隨生成一個新類

localDate.withYear()
localDate.plusMonths()
localDate.minusDays())

3.1.4 日期的經常使用方法 - 屬性判斷

LocalDate 也提供了一些屬性判斷的功能

 localDate.isLeapYear(); // true (是閏年)

 

3.2 本地時間 LocalTime

    LocalTime 的用法和 LocalDate 相似一樣與與時區無關,  它的默認格式也是採用 ISO-8601 格式爲 HH:mm:ss

時間的建立

LocalTime localTime = LocalTime.of(int hour, int minute, int second);
LocalTime localTime = LocalTime.of(int hour, int minute, int second, int nanoOfSecond)
LocalTime localTime = LocalTime.of(int hour, int minute);

例子:

LocalTime localTime = LocalTime.of(17,10,58);

3.3 本地日期時間的組合 LocalDateTime

TBD

 

-------------------------------------Example TBD------------------------------

 

4 時區時間

時區 Zone

5 時間工具

5.1 時間計算器 ChrononUnit

ChronoUnit類可用於在單個時間單位內測量一段時間,例如天數或秒。

LocalDate startDate = LocalDate.of(1993, Month.OCTOBER, 19);
System.out.println("開始時間  : " + startDate);

LocalDate endDate = LocalDate.of(2017, Month.JUNE, 16);
System.out.println("結束時間 : " + endDate);

long daysDiff = ChronoUnit.DAYS.between(startDate, endDate);
System.out.println("兩天之間的差在天數   : " + daysDiff);

5.2 格式轉換器 DateTimeFormatter

    Java 8 中 java.time.format 中 圍繞  DateTimeFormatter 構建了時間的解析與轉換。Java 8 默認的時間顯示格式是,ISO 8601標準格式。

5.2.1 使用格式轉換器

採用DateTimeFormatter.format() 方法進行格式化輸出。

首先須要實例化一個具體對應的時間格式轉換器。

如要格式化LocalDate 則須要實例化一個針對LocalDate的轉換器

須要注意的是轉化器與日期時間對象要一一對應切不可 

LocalDate對象 用DateTimeFormatter.ofLocalDateTime.

這樣會拋出UnsupportedTemporalyException.

在實例化一個轉換器 須要傳遞一個格式參數,Java8提供了 預約義的格式和自定義聲明

DateTimeFormatter shortDateTime = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);
DateTimeFormatter shortDateTime = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM);
DateTimeFormatter shortDateTime = DateTimeFormatter.ofLocalizedTime(FormatStyle.MEDIUM);

5.2.1.1 預約格式 FormatStyle

FormatSyle 是一個枚舉類,它包括了Full,LONG,MEDIUM,SHORT幾種常規的格式。

FormatStyle.FULL  // 'Tuesday, April 12, 1952 AD' or '3:30:42pm PST'.
FormatStyle.LONG // 'January 12, 1952'
FormatStyle.MEDIUM // 'Jan 12, 1952'.
FormatStyle.SHORT //'12.13.52' or '3:30pm'.

5.2.1.2 自定義格式 Pattern

除了以前介紹的一些預約義格式之外,還能夠輸出一些自定義的時間格式。採用字符串匹配模式

DateTimeFormatter f = DateTimeFormatter.ofPattern("MMMM dd, yyyy, hh:mm");

規則:

通常採用如下規則
 * MMMM 對應月份
   M outputs 1, 
   MM outputs 01, 
   MMM outputs Jan,
   MMMM outputs January.

 * dd,DD 對應天數
 * YYYY,YY,yyyy,yy 對應年份
 * HH 對應 24小時制的 小時
 * hh 對應 12小時制的 小時
 * mm 對應 分鐘
 * ss 對應 秒
 * SS 對應 毫秒

此外 還能夠包括 相似 / , : - 等分隔符

DateTimeFormatter f1 = DateTimeFormatter.ofPattern("MMMM dd, yyyy, hh:mm");
System.out.println(dateTime.format(f1)); // January 20, 2020, 01:12
DateTimeFormatter f2 = DateTimeFormatter.ofPattern("MM dd, yyyy, hh:mm");
System.out.println(dateTime.format(f2)); // 01 20, 2020, 01:12

DateTimeFormatter f3 = DateTimeFormatter.ofPattern("MMMM DD, YY, HH:mm");
System.out.println(dateTime.format(f3)); // January 20, 2020, 13:12
DateTimeFormatter f4 = DateTimeFormatter.ofPattern("MMMM dd, yyyy, hh:mm");
System.out.println(dateTime.format(f4)); // January 20, 2020, 01:12

DateTimeFormatter f5 = DateTimeFormatter.ofPattern("MMMM dd, yy, hh:mm:ss");
System.out.println(dateTime.format(f5)); // January 20, 2020, 01:12:34
DateTimeFormatter f6 = DateTimeFormatter.ofPattern("MMMM dd, yyyy, hh:mm:ss:SS");
System.out.println(dateTime.format(f6)); // January 20, 2020, 01:12:00

5.2.1.3 預留對象 DateTimeFormatter.IOS***

Java8 預先定義了一些經常使用格式的轉換器,能夠免去 自定義的麻煩.

DateTimeFormatter 內置了這些對象,能夠直接調用。

DateTimeFormatter.ISO_LOCAL_DATE  //'2011-12-03'
DateTimeFormatter.ISO_OFFSET_DATE //'2011-12-03+01:00'
DateTimeFormatter.ISO_DATE        //'2011-12-03' or '2011-12-03+01:00'
DateTimeFormatter.ISO_LOCAL_TIME  //'10:15' or '10:15:30'
DateTimeFormatter.ISO_OFFSET_TIME //'10:15+01:00' or '10:15:30+01:00'
DateTimeFormatter.ISO_TIME        //'10:15', '10:15:30' or '10:15:30+01:00'
DateTimeFormatter.ISO_LOCAL_DATE_TIME //'2011-12-03T10:15:30'
DateTimeFormatter.ISO_OFFSET_DATE_TIME//'2011-12-03T10:15:30+01:00'
DateTimeFormatter.ISO_ZONED_DATE_TIME //'2011-12-03T10:15:30+01:00'

5.2.2 內置Format方法

    時間日期相關類自帶一個formate(DateTimeFormatter.TYPE)方法,須要傳遞一個格式轉換器,會根據格式轉換器定義的格式作相應的轉換。

//建立本地時間
LocalDate date = LocalDate.of(2020, Month.JANUARY, 20);
LocalTime time = LocalTime.of(11, 12, 34);
LocalDateTime dateTime = LocalDateTime.of(date, time);

date.format(DateTimeFormatter.ISO_LOCAL_DATE)); //2020-01-20
dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)); //2020-01-20T11:12:34
time.format(DateTimeFormatter.ISO_LOCAL_TIME)); //11:12:34

date.format(DateTimeFormatter.ISO_DATE); //2020-01-20
dateTime.format(DateTimeFormatter.ISO_DATE_TIME); //2020-01-20T11:12:34
time.format(DateTimeFormatter.ISO_TIME); //11:12:34

5.3 時間解析器 Parser

 時間的解析和DateTimeFormatter中 ofPatter 結合使用 

配合要解析的字符串對應 時間 就能夠了。

DateTimeFormatter f = DateTimeFormatter.ofPattern("MM dd yyyy");
LocalDate date = LocalDate.parse("01 02 2015", f);
LocalTime time = LocalTime.parse("11:22");
System.out.println(date); // 2015-01-02
System.out.println(time); // 11:22

5.4

6 JDBC 與新日期

最新JDBC映射將把數據庫的日期類型和Java 8的新類型關聯起來:

SQL -> Java
--------------------------
date -> LocalDate
time -> LocalTime
timestamp -> LocalDateTime
相關文章
相關標籤/搜索