在Java8以前,在Java開發過程當中,若是要操做時間,是使用Date這個類,在Java8中新增了LocalTime、LocalDate和LocalDateTime,日期和時間的處理變得更加方便和容易。用了一段時間,剛開始每次用的時候都要上網查一波才能找到要的答案,後來認真看一下官網的API,發現也不是那麼難理解,如今可以經過本身的理解找到本身想要的表達式,在這裏作個小小的學習總結。java
既然Date類已經存在了那麼多年,爲何要花那麼大的精力去作這個改動?收益是什麼呢?程序員
首先,由於Date類真的很難用,有不少過於Geek的設計,好比月份是從0開始,0是一月,11是十二月。好吧,我已經知道程序員是從0開始計數了,可是每次用的時候都要作各類轉換,特別是跟其餘輸出端有交互的時候,改錯一個地方就凌亂了。在新的APIjava.time
裏,這些都用常量表示了,不會用錯,代碼看起來也更加清晰。安全
在業務代碼中,每每有不少種需求,獲取某一天的0點,獲取下一天的中午時間,將當前時間往前或者日後移動幾天,等等這類的需求,這些功能使用Date類配合Calendar要寫好多代碼,代碼簡潔性也不夠好。多線程
另一個,Date裏面的不少方法都棄用了,若是新的項目還敢用這些類,那就是給本身埋坑了,仍是趁早改了爲好。工具
舊的時間類java.util.Date
和格式化類SimpleDateFormatter
都是可變類,不是線程安全的,在多線程環境下對共享變量Date進行操做時,須要本身保證線程安全。而新的時間APILocalTime
和LocalDate
和格式化類DateTimeFormatter
都是final類(不可變)且是線程安全的。學習
基於上面的這些緣由,就沒有理由不使用新的時間API了。spa
從一個用着習慣了不少年的工具切換到新的工具老是很不習慣,過程是痛苦的,可是結果是美好的。線程
在新的時間API裏,有LocalTime
、LocalDate
、LocalDateTime
三個類,LocalTime
只處理時間,沒法包含日期,LocalDate
只處理日期,沒法包含時間,只有LocalDateTime
能同時處理日期和時間。設計
若是理解了三個類的區別,那麼在使用上,須要根據具體狀況來處理,下面看看比較常遇到的場景。code
只取日期,年月日。
獲取今天的日期
LocalDate today = LocalDate.now();// 2020-05-20
使用年月日構造一個日期
LocalDate valentineDay = LocalDate.of(2020, 5, 20); // 月份和日期是從1開始
指定對象,獲取年、月、日、星期幾
int year = localDate.getYear(); Month month = localDate.getMonth(); int day = localDate.getDayOfMonth(); DayOfWeek dayOfWeek = localDate.getDayOfWeek();
或者
int year = localDate.get(ChronoField.YEAR); int month = localDate.get(ChronoField.MONTH_OF_YEAR); int day = localDate.get(ChronoField.DAY_OF_MONTH); int dayOfWeek = localDate.get(ChronoField.DAY_OF_WEEK);
獲取時間,只會取幾點幾分幾秒。
初始化時間對象
LocalTime localTime = LocalTime.now();
使用時分秒構造一個對象
LocalTime localTime = LocalTime.of(12, 0, 0);
指定對象,獲取時分秒
LocalTime localTime = LocalTime.now(); int hour = localTime.getHour(); int minute = localTime.getMinute(); int second = localTime.getSecond(); int hour = localTime.get(ChronoField.HOUR_OF_DAY); int minute = localTime.get(ChronoField.MINUTE_OF_HOUR); int second = localTime.get(ChronoField.SECOND_OF_MINUTE);
獲取日期+時間,年月日+時分秒,含義等於LocalDate+LocalTime
建立時間對象
LocalDateTime localDateTime = LocalDateTime.now();
使用LocalDate結合LocalTime構造時間對象
LocalDateTime localDateTime = LocalDateTime.of(localData, localTime); LocalDateTime localDateTime = localDate.atTime(localTime); LocalDateTime localDateTime = localTime.atDate(localDate);
經過LocalDateTime獲取LocalDate和LocalTime
LocalDate localDate = localDateTime.toLocalDate(); LocalTime localDate = localDateTime.toLocalTime();
這個類是表示時間軸上的某一個時刻的時間點。從1970-01-01 00:00:00這個時間開始計算,主要用於獲取時間戳,與System.currentTimeMillis()
(精確到毫秒)相似,可是Instant類能夠精確到納秒。
建立Instant對象
Instant instant = Instant.now();
使用時間戳建立Instant對象
Instant instant = Instant.ofEpochSecond(100, 100000);
獲取秒數和毫秒
instant.getEpochSecond(); instant.getEpochMill();
介紹了這幾個類的基本API後,再經過實現某些具體的需求來加深印象。
// 獲取當前時間對象->設置時->轉換成時間戳 public static long getCurrentSeconds() { return Instant.now().atZone(ZoneOffset.of("+8")).toEpochSecond(); }
// 使用日期和時間構造日期時間對象->指定時區轉換成時間戳 public static long getTodayStartTime() { return LocalDateTime.of(LocalDate.now(), LocalTime.MIN).toEpochSecond(ZoneOffset.of("+8")); } public static long getTodayEndTime() { return LocalDateTime.of(LocalDate.now(), LocalTime.MAX).toEpochSecond(ZoneOffset.of("+8")); }
// 使用日期和時間構造日期時間對象->修改日期->指定時區轉換成時間戳 public static long getYesterdayStartTime() { return LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(1).toEpochSecond(ZoneOffset.of("+8")); }
// 使用時間戳構造日期時間對象->修改日期->指定時區轉換成時間戳 public static long getDayStartTime(long ) { return LocalDateTime.of(LocalDate.now(), LocalTime.MIN).minusDays(1).toEpochSecond(ZoneOffset.of("+8")); }
public static boolean isFirstDayOfMonth(String ymd) { LocalDate localDate = LocalDate.parse(ymd, DateTimeFormatter.ofPattern("yyyyMMdd")); return localDate.equals(localDate.withDayOfMonth(1)); }
Java新的時間API很強大,這裏只能舉幾個本身遇到比較多的場景給你們介紹,所講的只是最基礎最皮毛的東西,要熟練的掌握全部的細節,仍是須要去看看API或源碼的實現,而後在平時具體的需求場景中慢慢積累。
原創文章,文筆有限,才疏學淺,文中如有不正之處,萬望告知。
若是本文對你有幫助,請點個贊吧,謝謝
更多精彩內容,請關注我的公衆號。