<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          為什么建議使用你 LocalDateTime ,而不是 Date?

          共 5600字,需瀏覽 12分鐘

           ·

          2020-10-19 02:38

          點(diǎn)擊上方“JAVA”,星標(biāo)公眾號(hào)

          重磅干貨,第一時(shí)間送達(dá)

          來(lái)源:juejin.im/post/5d7787625188252388753eae

          • 為什么需要LocalDate、LocalTime、LocalDateTime

          • Come On 一起使用java8全新的日期和時(shí)間API

          • 小結(jié)

          在項(xiàng)目開發(fā)過程中經(jīng)常遇到時(shí)間處理,但是你真的用對(duì)了嗎,理解阿里巴巴開發(fā)手冊(cè)中禁用static修飾SimpleDateFormat嗎

          通過閱讀本篇文章你將了解到:

          • 為什么需要LocalDateLocalTimeLocalDateTime【java8新提供的類】

          • java8新的時(shí)間API的使用方式,包括創(chuàng)建、格式化、解析、計(jì)算、修改

          為什么需要LocalDate、LocalTime、LocalDateTime

          • Date如果不格式化,打印出的日期可讀性差
          Tue?Sep?10?09:34:04?CST?2019??
          • 使用SimpleDateFormat對(duì)時(shí)間進(jìn)行格式化,但SimpleDateFormat是線程不安全的SimpleDateFormatformat方法最終調(diào)用代碼:
          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?????????????int?tag?=?compiledPattern[i]?>>>?8;??
          ????????????int?count?=?compiledPattern[i++]?&?0xff;??
          ????????????if?(count?==?255)?{??
          ????????????????count?=?compiledPattern[i++]?<????????????????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是共享變量,并且這個(gè)共享變量沒有做線程安全控制。當(dāng)多個(gè)線程同時(shí)使用相同的SimpleDateFormat對(duì)象【如用static修飾的SimpleDateFormat】調(diào)用format方法時(shí),多個(gè)線程會(huì)同時(shí)調(diào)用calendar.setTime方法,可能一個(gè)線程剛設(shè)置好time值另外的一個(gè)線程馬上把設(shè)置的time值給修改了導(dǎo)致返回的格式化時(shí)間可能是錯(cuò)誤的。在多并發(fā)情況下使用SimpleDateFormat需格外注意SimpleDateFormat除了format是線程不安全以外,parse方法也是線程不安全的。parse方法實(shí)際調(diào)用alb.establish(calendar).getTime()方法來(lái)解析,alb.establish(calendar)方法里主要完成了


            1. 重置日期對(duì)象cal的屬性值

            1. 使用calb中中屬性設(shè)置cal

            1. 返回設(shè)置好的cal對(duì)象

          但是這三步不是原子操作

          多線程并發(fā)如何保證線程安全 - 避免線程之間共享一個(gè)SimpleDateFormat對(duì)象,每個(gè)線程使用時(shí)都創(chuàng)建一次SimpleDateFormat對(duì)象 => 創(chuàng)建和銷毀對(duì)象的開銷大 - 對(duì)使用formatparse方法的地方進(jìn)行加鎖 => 線程阻塞性能差 - 使用ThreadLocal保證每個(gè)線程最多只創(chuàng)建一次SimpleDateFormat對(duì)象 => 較好的方法
          • Date對(duì)時(shí)間處理比較麻煩,比如想獲取某年、某月、某星期,以及n天以后的時(shí)間,如果用Date來(lái)處理的話真是太難了,你可能會(huì)說Date類不是有getYeargetMonth這些方法嗎,獲取年月日很Easy,但都被棄用了啊

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

          LocalDate

          只會(huì)獲取年月日

          • 創(chuàng)建LocalDate
          //獲取當(dāng)前年月日??
          LocalDate?localDate?=?LocalDate.now();??
          //構(gòu)造指定的年月日??
          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

          只會(huì)獲取幾點(diǎn)幾分幾秒

          • 創(chuàng)建LocalTime
          ?LocalTime?localTime?=?LocalTime.of(13,?51,?10);??
          ?LocalTime?localTime1?=?LocalTime.now();??
          • 獲取時(shí)分秒
          //獲取小時(shí)??
          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.getSecond();??
          int?second1?=?localTime.get(ChronoField.SECOND_OF_MINUTE);??

          LocalDateTime

          獲取年月日時(shí)分秒,等于LocalDate+LocalTime

          • 創(chuàng)建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

          獲取秒數(shù)

          • 創(chuàng)建Instant對(duì)象
          Instant?instant?=?Instant.now();??
          • 獲取秒數(shù)
          long?currentSecond?=?instant.getEpochSecond();??
          • 獲取毫秒數(shù)
          long?currentMilli?=?instant.toEpochMilli();??

          個(gè)人覺得如果只是為了獲取秒數(shù)或者毫秒數(shù),使用System.currentTimeMillis()來(lái)得更為方便

          修改LocalDate、LocalTime、LocalDateTime、Instant

          LocalDateLocalTimeLocalDateTimeInstant不可變對(duì)象,修改這些對(duì)象對(duì)象會(huì)返回一個(gè)副本

          • 增加、減少年數(shù)、月數(shù)、天數(shù)等 以
          LocalDateTime??

          為例

          LocalDateTime?localDateTime?=?LocalDateTime.of(2019,?Month.SEPTEMBER,?10,??
          ??????????????14,?46,?56);??
          //增加一年??
          localDateTime?=?localDateTime.plusYears(1);??
          localDateTime?=?localDateTime.plus(1,?ChronoUnit.YEARS);??
          //減少一個(gè)月??
          localDateTime?=?localDateTime.minusMonths(1);??
          localDateTime?=?localDateTime.minus(1,?ChronoUnit.MONTHS);??
          • 通過
          with??

          修改某些值

          //修改年為2019??
          localDateTime?=?localDateTime.withYear(2020);??
          //修改為2022??
          localDateTime?=?localDateTime.with(ChronoField.YEAR,?2022);??

          還可以修改月、日

          時(shí)間計(jì)算

          比如有些時(shí)候想知道這個(gè)月的最后一天是幾號(hào)、下個(gè)周末是幾號(hào),通過提供的時(shí)間和日期API可以很快得到答案

          LocalDate?localDate?=?LocalDate.now();??
          LocalDate?localDate1?=?localDate.with(firstDayOfYear());??

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

          格式化時(shí)間

          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默認(rèn)提供了多種格式化方式,如果默認(rèn)提供的不能滿足要求,可以通過DateTimeFormatterofPattern方法創(chuàng)建自定義格式化方式

          解析時(shí)間

          LocalDate?localDate1?=?LocalDate.parse("20190910",?DateTimeFormatter.BASIC_ISO_DATE);??
          LocalDate?localDate2?=?LocalDate.parse("2019-09-10",?DateTimeFormatter.ISO_LOCAL_DATE);??

          SimpleDateFormat相比,DateTimeFormatter是線程安全的

          小結(jié)

          LocalDateTimeDate有的我都有,Date沒有的我也有,日期選擇請(qǐng)Pick Me

          ====================== Update On 2019/09/18 =================

          SpringBoot中應(yīng)用LocalDateTime

          • 將LocalDateTime字段以時(shí)間戳的方式返回給前端 添加日期轉(zhuǎn)化類
          public?class?LocalDateTimeConverter?extends?JsonSerializer?{??

          ????@Override??
          ????public?void?serialize(LocalDateTime?value,?JsonGenerator?gen,?SerializerProvider?serializers)?throws?IOException?{??
          ????gen.writeNumber(value.toInstant(ZoneOffset.of("+8")).toEpochMilli());??
          ????}??
          }??

          并在

          LocalDateTime??

          字段上添加

          @JsonSerialize(using?=?LocalDateTimeConverter.class)??

          注解,如下:

          @JsonSerialize(using?=?LocalDateTimeConverter.class)??
          protected?LocalDateTime?gmtModified;??
          • 將LocalDateTime字段以指定格式化日期的方式返回給前端 在
          LocalDateTime??

          字段上添加

          @JsonFormat(shape=JsonFormat.Shape.STRING,?pattern="yyyy-MM-dd?HH:mm:ss")??

          注解即可,如下:

          @JsonFormat(shape=JsonFormat.Shape.STRING,?pattern="yyyy-MM-dd?HH:mm:ss")??
          protected?LocalDateTime?gmtModified;??
          • 對(duì)前端傳入的日期進(jìn)行格式化 在
          LocalDateTime??

          字段上添加

          @DateTimeFormat(pattern?=?"yyyy-MM-dd?HH:mm:ss")??

          注解即可,如下:

          @DateTimeFormat(pattern?=?"yyyy-MM-dd?HH:mm:ss")??
          protected?LocalDateTime?gmtModified;??

          更多精彩?


          在公眾號(hào)【程序員編程】對(duì)話框輸入以下關(guān)鍵詞
          查看更多優(yōu)質(zhì)內(nèi)容!

          大數(shù)據(jù)?|?Java?|?1024?|?電子書?|?速查表?
          Python進(jìn)階?|?面試?|?手冊(cè)?|?成神?|?思想?|?小程序
          命令行?|?人工智能?|?軟件測(cè)試?|?Web前端?|?Python

          掃碼關(guān)注我們

          獲取更多學(xué)習(xí)資料

          視頻 |?面試 |?技術(shù) | 電子書?

          瀏覽 37
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  东京热黄色录像大全 | 一级黄色视频免费看 | 天天日夜夜 | 91爱福利 | 福利一区在线观看 |