整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          老大,你為什么在代碼中要求我們使用LocalDate

          老大,你為什么在代碼中要求我們使用LocalDateTime而不是Date?

          者:何甜甜在嗎 來源:http://1t.click/a7Gm

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

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

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

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

          # 為什么需要LocalDate、LocalTime、LocalDateTime

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

          Tue Sep 10 09:34:04 CST 2019

          2.使用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)方法里主要完成了

          a、重置日期對象cal的屬性值

          b、使用calb中中屬性設置cal

          c、返回設置好的cal對象

          但是這三步不是原子操作

          多線程并發如何保證線程安全 - 避免線程之間共享一個SimpleDateFormat對象,每個線程使用時都創建一次SimpleDateFormat對象=> 創建和銷毀對象的開銷大 - 對使用format和parse方法的地方進行加鎖=> 線程阻塞性能差 - 使用ThreadLocal保證每個線程最多只創建一次SimpleDateFormat對象=> 較好的方法

          1.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.getSecond;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

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

          SpringBoot中應用LocalDateTime

          將LocalDateTime字段以時間戳的方式返回給前端 添加日期轉化類

          public class LocalDateTimeConverter extends JsonSerializer<LocalDateTime> {
          @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;

          對前端傳入的日期進行格式化 在LocalDateTime字段上添加@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")注解即可,如下:

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

          ———— e n d ————

          微服務、高并發、JVM調優、面試專欄20 大進階架構師專題請關注公眾號Java進階架構師后在菜單欄查看

          者:何甜甜在嗎
          https://juejin.im/post/5d7787625188252388753eae


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

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

          • 為什么需要LocalDate、LocalTime、LocalDateTime【java8新提供的類】;
          • java8新的時間API的使用方式,包括創建、格式化、解析、計算、修改。

          為什么需要LocalDate、LocalTime、LocalDateTime

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

          Tue Sep 10 09:34:04 CST 2019

          2.使用SimpleDateFormat對時間進行格式化,但SimpleDateFormat是線程不安全的SimpleDateFormat的format方法最終調用代碼:

          calendar是共享變量,并且這個共享變量沒有做線程安全控制。

          當多個線程同時使用相同的SimpleDateFormat對象【如用static修飾的SimpleDateFormat】調用format方法時,多個線程會同時調用calendar.setTime方法,可能一個線程剛設置好time值

          另外的一個線程馬上把設置的time值給修改了導致返回的格式化時間可能是錯誤的。

          在多并發情況下使用SimpleDateFormat需格外注意 SimpleDateFormat除了format是線程不安全以外,parse方法也是線程不安全的。

          parse方法實際調用alb.establish(calendar).getTime()方法來解析,alb.establish(calendar)方法里主要完成了

          a、重置日期對象cal的屬性值b、使用calb中中屬性設置calc、返回設置好的cal對象

          但是這三步不是原子操作

          多線程并發如何保證線程安全 - 避免線程之間共享一個SimpleDateFormat對象,每個線程使用時都創建一次SimpleDateFormat對象=> 創建和銷毀對象的開銷大 - 對使用format和parse方法的地方進行加鎖=> 線程阻塞性能差 - 使用ThreadLocal保證每個線程最多只創建一次SimpleDateFormat對象=> 較好的方法

          1.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.getSecond();  
          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修改某些值

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

          還可以修改月、日

          時間計算

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

          LocalDate localDate=LocalDate.now();  
          LocalDate localDate1=localDate.with(firstDayOfYear());比如通過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

          SpringBoot中應用LocalDateTime

          將LocalDateTime字段以時間戳的方式返回給前端添加日期轉化類

          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;

          對前端傳入的日期進行格式化 在LocalDateTime字段上添加@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")注解即可,如下:

          頭條創作挑戰賽#

          在Java中,LocalDateTime類用于處理日期和時間,它提供了一種不依賴于時區的表示方式。以下是一些常見的LocalDateTime的使用方法:

          創建LocalDateTime對象

          LocalDateTime now=LocalDateTime.now(); //獲取當前日期和時間。
          LocalDateTime specificDateTime=LocalDateTime.of(2023,5,26,10,30,0); //指定日期和時間創建對象
          LocalDateTime parsedDateTime=LocalDateTime.parse("2023-05-26T10:30:00");//從字符串解析日期和時間

          獲取日期和時間的各個部分

          //獲取年份
          int year=dateTime.getYear();
          //獲取月份
          Month month=dateTime.getMonth();
          //獲取日期
          int day=dateTime.getDayOfMonth();
          //獲取小時
          int hour=dateTime.getHour();
          //獲取分鐘
          int minute=dateTime.getMinute();
          //獲取秒數
          int second=dateTime.getSecond();

          修改日期和時間的部分

          //修改年份
          LocalDateTime modifiedDateTime=dateTime.withYear(2024);
          //增加小時
          LocalDateTime addedHourDateTime=dateTime.plusHours(2);
          //減少天數
          LocalDateTime subtractedDaysDateTime=dateTime.minusDays(1);

          格式化日期和時間為字符串

          String formattedDateTime=dateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));

          比較兩個日期和時間

          // 比較第一個日期時間是否在第二個之前
          boolean isBefore=dateTime1.isBefore(dateTime2);
          //比較第一個日期時間是否在第二個之后
          boolean isAfter=dateTime1.isAfter(dateTime2);
          //比較兩個日期時間是否相等
          boolean isEqual=dateTime1.isEqual(dateTime2);

          LocalDateTime獲取當天0點時間

          //可以將時分秒和納秒都設為0
          LocalDateTime todayStart=LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);

          LocalDateTime獲取當天星期

          //使用Java8中的LocalDateTime類和Java8中的DayOfWeek枚舉來獲取當天星期
          LocalDateTime now=LocalDateTime.now();
          DayOfWeek dayOfWeek=now.getDayOfWeek();
          System.out.println("今天星期"+dayOfWeek.getValue());

          LocalDateTime獲取當天開始時間和當天結束時間


          主站蜘蛛池模板: 亚洲一区日韩高清中文字幕亚洲| 国产一区二区不卡在线播放| 国产99精品一区二区三区免费 | 国产丝袜无码一区二区视频| 无码AV天堂一区二区三区| 亚洲精品无码一区二区| 国产亚洲综合一区柠檬导航 | 99久久精品国产免看国产一区 | 亚洲啪啪综合AV一区| 北岛玲在线一区二区| 无码人妻一区二区三区免费 | 国产乱码精品一区二区三| 日韩在线视频不卡一区二区三区 | 综合无码一区二区三区四区五区 | 国产精品无码一区二区在线| 亚洲日本精品一区二区| 中文无码精品一区二区三区| 在线不卡一区二区三区日韩| 亚洲一区二区三区成人网站| av无码免费一区二区三区| 日产亚洲一区二区三区| 91视频一区二区| 中文无码一区二区不卡αv| 精品无码日韩一区二区三区不卡| 日韩一区二区久久久久久| 亚洲av无码一区二区三区网站 | 久久影院亚洲一区| 久久国产高清一区二区三区| 亚洲国模精品一区| 国内国外日产一区二区| 免费视频精品一区二区三区| 无码人妻品一区二区三区精99| 国产免费一区二区三区在线观看| 色偷偷一区二区无码视频| 91亚洲一区二区在线观看不卡| 亚洲熟妇无码一区二区三区导航| 无码一区二区三区免费视频| 免费人人潮人人爽一区二区| 丝袜无码一区二区三区| 久久国产精品一区免费下载| 国产一区在线mmai|