在 JDK 8 以前,Java 語言爲咱們提供了兩個類用於操做時間,它們分別是:java.util.Date 和 java.util.Calendar,但在 JDK 8 的時候爲了解決舊時間操做類的一些缺陷,提供了幾個新的類,用於操做時間和日期,它們分別是:LocalTime、LocalDateTime、Instant,都位於 java.time 包下。前端
時間的操做在咱們平常的開發中常常見到,好比,業務數據都要記錄建立時間和修改時間,並要把這些時間格式化以後顯示到前端頁面,再好比咱們須要計算業務數據的時間間隔等,都離不開對時間的操做,那如何正確而優雅地使用時間?這就是咱們接下來要討論的話題。java
格林威治(又譯格林尼治)是英國倫敦南郊原格林威治天文臺的所在地,它是世界計算時間和地球經度的起點,國際經度會議 1884 年在美國華盛頓召開,會上經過協議,以通過格林威治天文臺的經線爲零度經線(即本初子午線),做爲地球經度的起點,並以格林威治爲「世界時區」的起點。面試
格林威治時間被定義爲世界時間,就是 0 時區,北京是東八區。也就是說格林威治時間的 1 日 0 點,對應到北京的時間就是 1 日 8 點。sql
時間戳是指格林威治時間 1970-01-01 00:00:00(北京時間 1970-01-01 08:00:00)起至如今的總秒數。安全
Date date = new Date(); System.out.println(date); Calendar calendar = Calendar.getInstance(); Date time = calendar.getTime(); System.out.println(time);
long ts = new Date().getTime(); System.out.println(ts); long ts2 = System.currentTimeMillis(); System.out.println(ts2); long ts3 = Calendar.getInstance().getTimeInMillis(); System.out.println(ts3);
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(sf.format(new Date())); // output:2019-08-16 21:46:22
SimpleDateFormat 構造參數的含義,請參考如下表格信息:多線程
**字符** **含義** **示例** y 年 yyyy-1996 M 月 MM-07 d 月中的天數 dd-02 D 年中的天數 121 E 星期幾 星期四 H 小時數(0-23) HH-23 h 小時數(1-12) hh-11 m 分鐘數 mm-02 s 秒數 ss-03 Z 時區 +0800
使用示例:函數
注意事項:在多線程下 SimpleDateFormat 是非線程安全的,所以在使用 SimpleDateFormat 時要注意這個問題。在多線程下,若是使用不當,可能會形成結果不對或內存泄漏等問題。性能
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // String 轉 Date String str = "2019-10-10 10:10:10"; System.out.println(sf.parse(str)); //時間戳的字符串 轉 Date String tsString = "1556788591462"; // import java.sql Timestamp ts = new Timestamp(Long.parseLong(tsString)); // 時間戳的字符串轉 Date System.out.println(sf.format(ts));
注意事項:當使用 SimpleDateFormat.parse() 方法進行時間轉換的時候,SimpleDateFormat 的構造函數必須和待轉換字符串格式一致。編碼
Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.DATE, -1); System.out.println(calendar.getTime());
JDK 8 對時間操做新增了三個類:LocalDateTime、LocalDate、LocalTime。spa
線程安全性
值得一提的是 JDK 8 中新增的這三個時間相關的類,都是線程安全的,這極大地下降了多線程下代碼開發的風險。
// 獲取日期 LocalDate localDate = LocalDate.now(); System.out.println(localDate); // output:2019-08-16 // 獲取時間 LocalTime localTime = LocalTime.now(); System.out.println(localTime); // output:21:09:13.708 // 獲取日期和時間 LocalDateTime localDateTime = LocalDateTime.now(); System.out.println(localDateTime); // output:2019-08-16T21:09:13.708
long milli = Instant.now().toEpochMilli(); // 獲取當前時間戳(精確到毫秒) long second = Instant.now().getEpochSecond(); // 獲取當前時間戳(精確到秒) System.out.println(milli); // output:1565932435792 System.out.println(second); // output:1565932435
// 時間格式化① DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String timeFormat = dateTimeFormatter.format(LocalDateTime.now()); System.out.println(timeFormat); // output:2019-08-16 21:15:43 // 時間格式化② String timeFormat2 = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); System.out.println(timeFormat2); // output:2019-08-16 21:17:48
String timeStr = "2019-10-10 06:06:06"; LocalDateTime dateTime = LocalDateTime.parse(timeStr,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); System.out.println(dateTime);
LocalDateTime today = LocalDateTime.now(); LocalDateTime yesterday = today.plusDays(-1); System.out.println(yesterday);
答:獲取當前時間常見的方式有如下三種:
答:如下爲獲取昨天此刻時間的兩種方式:
// 獲取昨天此刻的時間(JDK 8 之前) Calendar c = Calendar.getInstance(); c.add(Calendar.DATE,-1); System.out.println(c.getTime()); // 獲取昨天此刻的時間(JDK 8) LocalDateTime todayTime = LocalDateTime.now(); System.out.println(todayTime.plusDays(-1));
答:如下爲獲取本月最後一天的兩種方式:
// 獲取本月的最後一天(JDK 8 之前) Calendar ca = Calendar.getInstance(); ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH)); System.out.println(ca.getTime()); // 獲取本月的最後一天(JDK 8) LocalDate today = LocalDate.now(); System.out.println(today.with(TemporalAdjusters.lastDayOfMonth()));
答:如下爲獲取當前時間戳的幾種方式:
其中,第四種和第五種方式是 JDK 8 才新加的。
答:JDK 8 中能夠使用 Duration 類來優雅地計算兩個時間的相隔時間,代碼以下:
LocalDateTime dt1 = LocalDateTime.now(); LocalDateTime dt2 = dt1.plusSeconds(60); Duration duration = Duration.between(dt1, dt2); System.out.println(duration.getSeconds()); // output:60
答:JDK 8 中能夠使用 Period 類來優雅地計算兩個日期的相隔日期,代碼以下:
LocalDate d1 = LocalDate.now(); LocalDate d2 = d1.plusDays(2); Period period = Period.between(d1, d2); System.out.println(period.getDays()); //output:2
答:SimpleDateFormat 是非線程安全的。由於查看 SimpleDateFormat 的源碼能夠得知,全部的格式化和解析,都須要經過一箇中間對象進行轉換,這個中間對象就是 Calendar,這樣的話就形成非線程安全。試想一下當咱們有多個線程操做同一個 Calendar 的時候後來的線程會覆蓋先來線程的數據,那最後其實返回的是後來線程的數據,所以 SimpleDateFormat 就成爲了非線程的了。
答:保證 SimpleDateFormat 線程安全的方式以下:
答:JDK 8 中的優勢具體有如下幾個優勢,以下:
答:時間比較有如下三種方式:
JDK 8 以前使用 java.util.Date 和 java.util.Calendar 來操做時間,它們有兩個很明顯的缺點,第一,非線程安全;第二,API 調用不方便。JDK 8 新增了幾個時間操做類 java.time 包下的 LocalDateTime、LocalDate、LocalTime、Duration(計算相隔時間)、Period(計算相隔日期)和 DateTimeFormatter,提供了多線程下的線程安全和易用性,讓咱們能夠更好的操做時間。
_
歡迎關注個人公衆號,回覆關鍵字「Java」 ,將會有大禮相送!!! 祝各位面試成功!!!