java8新特性LocalDate、LocalTime、LocalDateTime的学习
以前操作时间都是使用SimpleDateFormat类改变Date的时间格式,使用Calendar类操作时间。但是SimpleDateFormat是线程不安全的,源码如下:
1 private StringBuffer format(Date date, StringBuffer toAppendTo, 2 FieldDelegate delegate) { 3 // Convert input date to time field list 4 calendar.setTime(date); 5 6 boolean useDateFormatSymbols = useDateFormatSymbols(); 7 8 for (int i = 0; i < compiledPattern.length; ) { 9 int tag = compiledPattern[i] >>> 8; 10 int count = compiledPattern[i++] & 0xff; 11 if (count == 255) { 12 count = compiledPattern[i++] << 16; 13 count |= compiledPattern[i++]; 14 } 15 16 switch (tag) { 17 case TAG_QUOTE_ASCII_CHAR: 18 toAppendTo.append((char)count); 19 break; 20 21 case TAG_QUOTE_CHARS: 22 toAppendTo.append(compiledPattern, i, count); 23 i += count; 24 break; 25 26 default: 27 subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols); 28 break; 29 } 30 } 31 return toAppendTo; 32 }
calendar是共享变量,并且这个共享变量没有做线程安全控制。当多个线程同时使用相同的SimpleDateFormat对象调用format方法时,多个线程会同时调用calendar.setTime方法,可能一个线程刚设置好time值另外的一个线程马上把设置的time值给修改了导致返回的格式化时间可能是错误的。
所以JAVA8推出了LocalDate、LocalTime、LocalDateTime是线程安全、简易、高可靠的时间包。源码如下
-
LocalDate 获取年月日
1 @Test 2 public void localDataTest(){ 3 //创建LocalDate获取当前年月日 4 LocalDate now = LocalDate.now(); 5 System.out.println("当前时间:" + now); 6 //构造指定的年月日 7 LocalDate localDate = LocalDate.of(2020, 11, 24); 8 System.out.println("当前指定时间:" + localDate); 9 int year = now.getYear(); 10 System.out.println("当前年year:" + year); 11 int year1 = now.get(ChronoField.YEAR); 12 System.out.println("当前年year1:" + year1); 13 Month month = now.getMonth(); 14 System.out.println("当前月month:" + month); 15 int month1 = now.get(ChronoField.MONTH_OF_YEAR); 16 System.out.println("当前月month1:" + month1); 17 int day = now.getDayOfMonth(); 18 System.out.println("当前天day:" + day); 19 int day1 = now.get(ChronoField.DAY_OF_MONTH); 20 System.out.println("当前天day1:" + day1); 21 DayOfWeek dayOfWeek = now.getDayOfWeek(); 22 System.out.println("当前星期几dayOfWeek:" + dayOfWeek); 23 int dayOfWeek1 = now.get(ChronoField.DAY_OF_WEEK); 24 System.out.println("当前星期几dayOfWeek1:" + dayOfWeek1); 25 }
-
LocalTime 获取时分秒
1 @Test 2 public void localTimeTest(){ 3 //创建LocalTime获取当前时分秒 4 LocalTime now = LocalTime.now(); 5 System.out.println("当前时间:" + now); 6 LocalTime localTime = LocalTime.of(13, 51, 10); 7 System.out.println("指定时间:" + localTime); 8 int hour = now.getHour(); 9 System.out.println("当前小时数hour:"+ hour); 10 int hour1 = now.get(ChronoField.HOUR_OF_DAY); 11 System.out.println("当前小时数hour1:"+ hour1); 12 int minute = now.getMinute(); 13 System.out.println("当前分钟数minute:"+ minute); 14 int minute1 = now.get(ChronoField.MINUTE_OF_DAY); 15 System.out.println("当前分钟数minute1:"+ minute1); 16 int second = now.getSecond(); 17 System.out.println("当前秒数second:"+ second); 18 int second1 = now.get(ChronoField.SECOND_OF_MINUTE); 19 System.out.println("当前秒数second1:"+ second1); 20 }
-
LocalDateTime 获取年月日时分秒,相当于LocalDate+LocalTime,可与LocalDate、LocalTime相互转换
1 @Test 2 public void localDataTimeTest(){ 3 //创建localDateTime获取当前时间时分秒 4 LocalDateTime localDateTime = LocalDateTime.now(); 5 System.out.println("当前时间:" + localDateTime); 6 LocalDateTime localDateTime1 = LocalDateTime.of(2020, Month.SEPTEMBER, 10, 14, 46, 56); 7 System.out.println("指定时间:" + localDateTime1); 8 LocalDateTime of = LocalDateTime.of(LocalDate.now(), LocalTime.now()); 9 System.out.println("当前时间1:" + of); 10 LocalDateTime localDateTime2 = LocalDate.now().atTime(LocalTime.now()); 11 System.out.println("当前时间2:" + localDateTime2); 12 LocalDateTime localDateTime3 = LocalTime.now().atDate(LocalDate.now()); 13 System.out.println("当前时间3:" + localDateTime3); 14 LocalDate localDate = localDateTime.toLocalDate(); 15 System.out.println("当前年月日:" + localDate); 16 LocalTime localTime = localDateTime.toLocalTime(); 17 System.out.println("当前时分秒:" + localTime); 18 //时间格式转换成yyyy-MM-dd HH:mm:ss 19 String timeStr1=LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); 20 String timeStr2=LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS")); 21 System.out.println("当前时间为:"+timeStr1); 22 System.out.println("当前时间为:"+timeStr2); 23 }
-
Period 时间长度类 Period表示以年、月、日衡量的时长,通过Period增加、减少年月日
1 @Test 2 public void periodTest(){ 3 //创建localDateTime获取当前年月日时分秒 4 LocalDateTime localDateTime = LocalDateTime.now(); 5 //创建Period对象,设置一年 6 Period period = Period.ofYears(1); 7 //增加一年 8 LocalDate localDate = localDateTime.toLocalDate().plus(period); 9 System.out.println("增加一年后的时间:" + localDate); 10 Period period1 = Period.ofYears(-1); 11 //减少一年 12 LocalDate localDate1 = localDateTime.toLocalDate().plus(period1); 13 System.out.println("减少一年后的时间:" + localDate1); 14 //创建Period对象,设置一月 15 Period period2 = Period.ofMonths(1); 16 //增加一个月 17 LocalDate localDate2 = localDateTime.toLocalDate().plus(period2); 18 System.out.println("增加一个月后的时间:" + localDate2); 19 //创建Period对象,设置一周 20 Period period3 = Period.ofWeeks(1); 21 //增加一周 22 LocalDate localDate3 = localDateTime.toLocalDate().plus(period3); 23 System.out.println("增加一周后的时间:" + localDate3); 24 //创建Period对象,设置一天 25 Period period4 = Period.ofDays(1); 26 //增加一天 27 LocalDate localDate4 = localDateTime.toLocalDate().plus(period4); 28 System.out.println("增加一天后的时间:" + localDate4); 29 }
-
Duration 时间长度类 Duration表示以时、分、秒衡量的时长,通过Duration增加、减少时分秒
1 @Test 2 public void durationTest(){ 3 //创建localDateTime获取当前时间时分秒 4 LocalDateTime localDateTime = LocalDateTime.now(); 5 //创建Duration对象,设置1天 6 Duration duration = Duration.ofDays(1); 7 //增加一天 8 LocalTime localTime = localDateTime.toLocalTime().plus(duration); 9 System.out.println("增加一天后时间:" + localTime); 10 //创建Duration对象,设置一小时 11 Duration duration1 = Duration.ofHours(-1); 12 //减少一天 13 LocalTime localTime1 = localDateTime.toLocalTime().plus(duration1); 14 System.out.println("增加一天后时间:" + localTime1); 15 //创建Duration对象,设置一小时 16 Duration duration2 = Duration.ofHours(1); 17 //增加一小时 18 LocalTime localTime2 = localDateTime.toLocalTime().plus(duration2); 19 System.out.println("增加一小时后时间:" + localTime2); 20 //创建Duration对象,设置一分钟 21 Duration duration3 = Duration.ofMinutes(1); 22 //增加一分钟 23 LocalTime localTime3 = localDateTime.toLocalTime().plus(duration3); 24 System.out.println("增加一分钟后时间:" + localTime3); 25 //创建Duration对象,设置十秒钟 26 Duration duration4 = Duration.ofSeconds(10); 27 //增加十秒钟 28 LocalTime localTime4 = localDateTime.toLocalTime().plus(duration4); 29 System.out.println("增加十秒钟后时间:" + localTime4); 30 //创建Duration对象,设置一百毫秒 31 Duration duration5 = Duration.ofMillis(100); 32 //增加一百毫秒 33 LocalTime localTime5 = localDateTime.toLocalTime().plus(duration5); 34 System.out.println("增加一百毫秒后时间:" + localTime5); 35 }
-
ZonedDateTime 时区处理类 可以设置时区,用法和LocalDataTime基本相同
@Test public void zonedDateTimeTest(){ ZoneId zoneId = ZoneId.of("UTC+1"); //设置指定时间、时区 ZonedDateTime zonedDateTime = ZonedDateTime.of(2020, 11, 24, 15, 29, 53, 1026, zoneId); //获取今天是今年第几天 int dayOfYear = zonedDateTime.getDayOfYear(); System.out.println("今天是今年第"+dayOfYear+"天"); //获取今天是这月第几天 int dayOfMonth = zonedDateTime.getDayOfMonth(); System.out.println("今天是这月第"+dayOfMonth+"天"); //获取今天是这周第几天 int dayOfWeek = zonedDateTime.getDayOfWeek().get(ChronoField.DAY_OF_WEEK); System.out.println("今天是这周第"+dayOfWeek+"天"); //增加一年 ZonedDateTime zonedDateTime1 = zonedDateTime.plusYears(1); System.out.println("增加一年后的时间:"+zonedDateTime1); //减少一年 ZonedDateTime zonedDateTime2 = zonedDateTime.minusYears(1); System.out.println("减少一年后的时间:"+zonedDateTime2); }