早期,Java 對時間和日期的使用每每重度依賴 java.util.Date和java.util.Calendar。 惋惜的是,這2個api 自己不夠健壯,有相似線程不安全等諸多問題,因而乎2000年左右,市面上出現了不少用於處理時間類的框架,如Joda-Time。 在Java 8 時代 官方爲JDK開發新的時間/日期API的進程:JSR-310,啓動了。因而就出現了新一套健壯的API。java
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 用來對各時區的支持
Java8中 引入了時間線的概念,時間是接二連三,抽象成一條線,線上的點表示某一時刻。
一班來講,這個設定主要是面對機器的,不用關心具體的年月日時分秒,內部以秒或者納秒錶示。
時間點是表示時間的某時某刻的,相對的它是時間線上的一點。
java.time包經過值類型Instant提供機器視圖。
Instant表示時間線上的一點,而不須要任何上下文信息(時區,年份)
概念上講,它只是簡單的表示自1970年1月1日0時0分0秒(UTC)開始的秒數。
由於java.time包是基於納秒計算的,因此Instant的精度能夠達到納秒級。
Instant start = Instant.now() Instant end = Instant.now()
Period表示以年、月、日衡量的時長。例如,「3年2個月零6天」。表示的是一段時間 以日月年爲單位.
在日期的操做中 能夠做爲參數來做爲日期的加減運算。
Period period = Period.now()
Duration表示以秒和納秒爲基準的時長。例如,「23.6秒」。Duration表示的是一段時間 以 分十秒爲單位. 在時間的操做中 能夠做爲參數 來做爲時間的加減運算。
Duration duration = Duration.()System..println(duration)System..println(duration.getSeconds())
--------------------------TBD-----------------------
新的API 提倡採用不變模式,雖然時間是一直在變化的,某事某刻的表示它是固定的,哪怕對日期進行加減,操做以後的日期則表示新的時刻。
因此Java時間相關的API,在原始時間對象上 作相應的加減操做,原來的日期對象不變,會產生一個新的對象。
LocalDate 是新API 中 最基礎也是最重要的類, 它是一個 不可變的類(final 修飾),本地日期只是一個術語,用來表示一個具體日期,不一樣地區的日期可能不一樣 故採用 local 這個術語,其實它是時區無關的,這個類沒有包含任什麼時候區信息,就簡單的認爲一個日期便可。
日期的建立 採用了工廠方法的模式,全部的建立方法都是私有的,經常使用的是調用對外開放的方法of 來生成一個 日期實例
LocalDate localDate = LocalDate.of(int year, Month month, int dayOfMonth); LocalDate localDate = LocalDate.of(int year, int month, int dayOfMonth);
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 當前月共有多少天
LocalDate 是一個不可變的類,它的每一次操做 都會伴隨生成一個新類
localDate.withYear() localDate.plusMonths() localDate.minusDays())
LocalDate 也提供了一些屬性判斷的功能
localDate.isLeapYear(); // true (是閏年)
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);
TBD
-------------------------------------Example TBD------------------------------
時區 Zone
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);
Java 8 中 java.time.format 中 圍繞 DateTimeFormatter 構建了時間的解析與轉換。Java 8 默認的時間顯示格式是,ISO 8601標準格式。
採用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);
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'.
除了以前介紹的一些預約義格式之外,還能夠輸出一些自定義的時間格式。採用字符串匹配模式
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
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'
時間日期相關類自帶一個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
時間的解析和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
最新JDBC映射將把數據庫的日期類型和Java 8的新類型關聯起來:
SQL -> Java -------------------------- date -> LocalDate time -> LocalTime timestamp -> LocalDateTime