程式設計師,你還在使用Date嘛?建議你使用LocalDateTime哦

分享阿里 P8 高階架構師吐血總結的 《Java 核心知識體系&面試資料.pdf》

據說是阿里 P8 級高階架構師吐血總結的一份 Java 核心知識。pdf, 內容覆蓋很廣,Java 核心基礎、Java 多執行緒、高併發、Spring、微服務、Netty 與 RPC、Zookeeper、Kafka、RabbitMQ、Habase、設計模式、負載均衡、分散式快取、Hadoop、Spark、Storm、雲計算等。

另外,附送 100G 學習、面試影片文件喲~

獲取方式:【

關注 + 轉發

】後,

私信

我,回覆關鍵字【

資源

】,即可

免費無套路獲取

哦~

以下是資源的部分目錄以及內容截圖:

程式設計師,你還在使用Date嘛?建議你使用LocalDateTime哦

程式設計師,你還在使用Date嘛?建議你使用LocalDateTime哦

程式設計師,你還在使用Date嘛?建議你使用LocalDateTime哦

程式設計師,你還在使用Date嘛?建議你使用LocalDateTime哦

程式設計師,你還在使用Date嘛?建議你使用LocalDateTime哦

重要的事再說一遍,獲取方式:【

關注 + 轉發

】後,

私信

我,回覆關鍵字【

資源

】,即可

免費無套路獲取

哦~

正文開始

在專案開發過程中經常遇到時間處理,但是你真的用對了嗎,理解阿里巴巴開發手冊中禁用static修飾SimpleDateFormat嗎

透過閱讀本篇文章你將瞭解到:

為什麼需要LocalDate、LocalTime、LocalDateTime【java8新提供的類】

java8新的時間API的使用方式,包括建立、格式化、解析、計算、修改

為什麼需要LocalDate、LocalTime、LocalDateTime

Date如果不格式化,打印出的日期可讀性差

Tue Sep 10 09:34:04 CST 2019複製程式碼

使用SimpleDateFormat對時間進行格式化,但SimpleDateFormat是執行緒不安全的 SimpleDateFormat的format方法最終呼叫程式碼:

private StringBuffer format(Date date, StringBuffer toAppendTo, FieldDelegate delegate) { // Convert input date to time field list calendar。setTime(date); boolean useDateFormatSymbols = useDateFormatSymbols(); for (int i = 0; i < compiledPattern。length; ) { int tag = compiledPattern[i] >>> 8; int count = compiledPattern[i++] & 0xff; if (count == 255) { count = compiledPattern[i++] << 16; count |= compiledPattern[i++]; } switch (tag) { case TAG_QUOTE_ASCII_CHAR: toAppendTo。append((char)count); break; case TAG_QUOTE_CHARS: toAppendTo。append(compiledPattern, i, count); i += count; break; default: subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols); break; } } return toAppendTo; }複製程式碼

calendar是共享變數,並且這個共享變數沒有做執行緒安全控制。當多個執行緒同時使用

相同的SimpleDateFormat物件

【如用static修飾的SimpleDateFormat】呼叫format方法時,多個執行緒會同時呼叫calendar。setTime方法,可能一個執行緒剛設定好time值另外的一個執行緒馬上把設定的time值給修改了導致返回的格式化時間可能是錯誤的。在多併發情況下使用SimpleDateFormat需格外注意 SimpleDateFormat除了format是執行緒不安全以外,parse方法也是執行緒不安全的。parse方法實際呼叫alb。establish(calendar)。getTime()方法來解析,alb。establish(calendar)方法裡主要完成了

重置日期物件cal的屬性值

使用calb中中屬性設定cal

返回設定好的cal物件

但是這三步不是原子操作

多執行緒併發如何保證執行緒安全 - 避免執行緒之間共享一個SimpleDateFormat物件,每個執行緒使用時都建立一次SimpleDateFormat物件 => 建立和銷燬物件的開銷大 - 對使用format和parse方法的地方進行加鎖 => 執行緒阻塞效能差 - 使用ThreadLocal保證每個執行緒最多隻建立一次SimpleDateFormat物件 => 較好的方法

Date對時間處理比較麻煩,比如想獲取某年、某月、某星期,以及n天以後的時間,如果用Date來處理的話真是太難了,你可能會說Date類不是有getYear、getMonth這些方法嗎,獲取年月日很Easy,但都被棄用了啊

Come On 一起使用java8全新的日期和時間API

LocalDate

只會獲取年月日

建立LocalDate

//獲取當前年月日LocalDate localDate = LocalDate。now();//構造指定的年月日LocalDate localDate1 = LocalDate。of(2019, 9, 10);複製程式碼

獲取年、月、日、星期幾

int year = localDate。getYear();int year1 = localDate。get(ChronoField。YEAR);Month month = localDate。getMonth();int month1 = localDate。get(ChronoField。MONTH_OF_YEAR);int day = localDate。getDayOfMonth();int day1 = localDate。get(ChronoField。DAY_OF_MONTH);DayOfWeek dayOfWeek = localDate。getDayOfWeek();int dayOfWeek1 = localDate。get(ChronoField。DAY_OF_WEEK);複製程式碼

LocalTime

只會獲取幾點幾分幾秒

建立LocalTime

LocalTime localTime = LocalTime。of(13, 51, 10); LocalTime localTime1 = LocalTime。now();複製程式碼

獲取時分秒

//獲取小時int hour = localTime。getHour();int hour1 = localTime。get(ChronoField。HOUR_OF_DAY);//獲取分int minute = localTime。getMinute();int minute1 = localTime。get(ChronoField。MINUTE_OF_HOUR);//獲取秒int second = localTime。getMinute();int second1 = localTime。get(ChronoField。SECOND_OF_MINUTE);複製程式碼

LocalDateTime

獲取年月日時分秒,等於LocalDate+LocalTime

建立LocalDateTime

LocalDateTime localDateTime = LocalDateTime。now();LocalDateTime localDateTime1 = LocalDateTime。of(2019, Month。SEPTEMBER, 10, 14, 46, 56);LocalDateTime localDateTime2 = LocalDateTime。of(localDate, localTime);LocalDateTime localDateTime3 = localDate。atTime(localTime);LocalDateTime localDateTime4 = localTime。atDate(localDate);複製程式碼

獲取LocalDate

LocalDate localDate2 = localDateTime。toLocalDate();複製程式碼

獲取LocalTime

LocalTime localTime2 = localDateTime。toLocalTime();複製程式碼

Instant

獲取秒數

建立Instant物件

Instant instant = Instant。now();複製程式碼

獲取秒數

long currentSecond = instant。getEpochSecond();複製程式碼

獲取毫秒數

long currentMilli = instant。toEpochMilli();複製程式碼

個人覺得如果只是為了獲取秒數或者毫秒數,使用System。currentTimeMillis()來得更為方便

修改LocalDate、LocalTime、LocalDateTime、Instant

LocalDate、LocalTime、LocalDateTime、Instant為

不可變物件

,修改這些物件物件會

返回一個副本

增加、減少年數、月數、天數等 以LocalDateTime為例

LocalDateTime localDateTime = LocalDateTime。of(2019, Month。SEPTEMBER, 10, 14, 46, 56);//增加一年localDateTime = localDateTime。plusYears(1);localDateTime = localDateTime。plus(1, ChronoUnit。YEARS);//減少一個月localDateTime = localDateTime。minusMonths(1);localDateTime = localDateTime。minus(1, ChronoUnit。MONTHS); 複製程式碼

透過with修改某些值

//修改年為2019localDateTime = localDateTime。withYear(2020);//修改為2022localDateTime = localDateTime。with(ChronoField。YEAR, 2022);複製程式碼

還可以修改月、日

時間計算

比如有些時候想知道這個月的最後一天是幾號、下個週末是幾號,透過提供的時間和日期API可以很快得到答案

LocalDate localDate = LocalDate。now();LocalDate localDate1 = localDate。with(firstDayOfYear());複製程式碼

比如透過firstDayOfYear()返回了當前日期的第一天日期,還有很多方法這裡不在舉例說明

格式化時間

LocalDate localDate = LocalDate。of(2019, 9, 10);String s1 = localDate。format(DateTimeFormatter。BASIC_ISO_DATE);String s2 = localDate。format(DateTimeFormatter。ISO_LOCAL_DATE);//自定義格式化DateTimeFormatter dateTimeFormatter = DateTimeFormatter。ofPattern(“dd/MM/yyyy”);String s3 = localDate。format(dateTimeFormatter);複製程式碼

DateTimeFormatter預設提供了多種格式化方式,如果預設提供的不能滿足要求,可以透過DateTimeFormatter的ofPattern方法建立自定義格式化方式

解析時間

LocalDate localDate1 = LocalDate。parse(“20190910”, DateTimeFormatter。BASIC_ISO_DATE);LocalDate localDate2 = LocalDate。parse(“2019-09-10”, DateTimeFormatter。ISO_LOCAL_DATE);複製程式碼

和SimpleDateFormat相比,DateTimeFormatter是執行緒安全的

小結

LocalDateTime:Date有的我都有,Date沒有的我也有,日期選擇請Pick Me

作者:何甜甜在嗎