以前操作时间都是使用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);
}