LocalDateTime、LocalDate、LocalTime

1. localDateTime对比Date

  • 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天以后的时间时,对应逻辑及API处理复杂。

2. LocalDate

只获取年月日数据

2.1 创建

// LocalDate 定义常亮
public static final int MIN_VALUE = -999_999_999;
public static final int MAX_VALUE = 999_999_999;
public static final LocalDate MIN = LocalDate.of(Year.MIN_VALUE, 1, 1);
public static final LocalDate MAX = LocalDate.of(Year.MAX_VALUE, 12, 31);
// 支持最大日期
LocalDate MAX = LocalDate.of(Year.MAX_VALUE, 12, 31);
System.out.println("MAX:" + MAX); // +999999999-12-31
// 支持最小日期
LocalDate MIN = LocalDate.of(Year.MIN_VALUE, 01, 01);
System.out.println("MAX:" + MIN); // -999999999-01-01
// 获取当前日期
LocalDate nowDate = LocalDate.now();
System.out.println("date:" + nowDate); // 2020-11-20
// 日期创建
LocalDate date = LocalDate.parse("2020-11-20");
System.out.println("date:" + date); // 2020-11-20
LocalDate date1 = LocalDate.of(2020, 11, 20);
System.out.println("date1:" + date1); // 2020-11-20

2.2 获取年月日

// 获取当前日期的年
int year = date.getYear();
System.out.println("year:" + year); // 2020
// 获当前日期所在月
System.out.println("month1:" + date.getMonthValue()); // 11
System.out.println("month2:" + date.getMonth()); // november
// 获取当前日期是周几
DayOfWeek day1 = date.getDayOfWeek();
System.out.println("day1:" + day1); // friday
System.out.println("day1:" + day1.getValue()); // 5
// 获取当前日期是一月中几号
int day2 = date.getDayOfMonth();
System.out.println("day2:" + day2); // 20
// 获取当前日期是一年中第几天
int day3 = date.atStartOfDay().getDayOfYear();
System.out.println("day3:" + day3); // 325
// 转换为LocalDateTime,以最早时间 00:00:00
LocalDateTime day4 = date.atStartOfDay();
System.out.println("date4:" + day4); // 2020-11-20T00:00
// 获取当前日期是所在世纪的第几天
Long day5 = date.toEpochDay();
System.out.println("date5:" + day5); // 18586
// 获取本地日期标准
System.out.println("result:" + date2.getChronology()); // ISO

2.3 比较大小

LocalDate date1 = LocalDate.parse("2020-11-20");
LocalDate date2 = LocalDate.parse("2020-11-25");
LocalDate date3 = LocalDate.parse("2020-11-25");
// 比较大小
System.out.println("result1:" + date1.compareTo(date2)); // -5
System.out.println("result2:" + date2.compareTo(date1)); // 5
System.out.println("result3:" + date2.compareTo(date3)); // 0
System.out.println("result1:" + date1.isAfter(date2)); // false
System.out.println("result2:" + date2.isAfter(date1)); // true
System.out.println("result3:" + date2.isAfter(date3)); // false
System.out.println("result1:" + date1.isBefore(date2)); // true
System.out.println("result2:" + date2.isBefore(date1)); // false
System.out.println("result3:" + date2.isBefore(date3)); // false
System.out.println("result1:" + date1.equals(date2)); // false
System.out.println("result2:" + date2.equals(date1)); // false
System.out.println("result3:" + date2.equals(date3)); // true

2.4 加减

LocalDate date1 = LocalDate.parse("2020-11-20");
// 加一天
System.out.println("result1: " + date1.plusDays(1)); // 2020-11-21
Period period1 = Period.of(0, 0, 1);
System.out.println("period1: " + period1); // P1D
System.out.println("result1: " + date1.plus(period1)); // 2020-11-21
// 加一周
System.out.println("result2: " + date1.plusWeeks(1)); // 2020-11-27
Period period2 = Period.ofWeeks(1);
System.out.println("period2: " + period2); // P7D
System.out.println("result2: " + date1.plus(period2)); // 2020-11-27
// 加一月
System.out.println("result3: " + date1.plusMonths(1)); // 2020-12-20
Period period3 = Period.ofMonths(1);
System.out.println("period3: " + period3); // P1M
System.out.println("result3: " + date1.plus(period3)); // 2020-12-20
// 加一年
System.out.println("result4: " + date1.plusYears(1)); // 2021-11-20
Period period4 = Period.ofYears(1);
System.out.println("period4: " + period4); // P1Y
System.out.println("result4: " + date1.plus(period4)); // 2021-11-20
// 减一天
System.out.println("result1: " + date1.minusDays(1)); // 2020-11-19
Period period1 = Period.of(0, 0, 1);
System.out.println("period1: " + period1); // P1D
System.out.println("result1: " + date1.minus(period1)); // 2020-11-19
// 减一周
System.out.println("result2: " + date1.minusWeeks(1)); // 2020-11-13
Period period2 = Period.ofWeeks(1);
System.out.println("period2: " + period2); // P7D
System.out.println("result2: " + date1.minus(period2)); // 2020-11-13
// 减一月
System.out.println("result3: " + date1.minusMonths(1)); // 2020-10-20
Period period3 = Period.ofMonths(1);
System.out.println("period3: " + period3); // P1M
System.out.println("result3: " + date1.minus(period3)); // 2020-10-20
// 减一年
System.out.println("result4: " + date1.minusYears(1)); // 2019-11-20
Period period4 = Period.ofYears(1);
System.out.println("period4: " + period4); // P1Y
System.out.println("result4: " + date1.minus(period4)); // 2019-11-20

3. LocalTime

只获取时分秒

3.1 创建

LocalTime time1 = LocalTime.parse("12:13:14");
LocalTime time2 = LocalTime.parse("12:13:14");
LocalTime time3 = LocalTime.parse("13:13:13");
System.out.println("time1: " + time1); // 12:13:14
System.out.println("time2: " + time2); // 12:13:14
System.out.println("time3: " + time3); // 13:13:13

LocalTime time4 = LocalTime.now();
LocalTime time5 = LocalTime.of(12,13);
LocalTime time6 = LocalTime.of(12,13, 13);
LocalTime time7 = LocalTime.of(12,13, 13, 100);
LocalTime time8 = LocalTime.ofNanoOfDay(1000000000);
LocalTime time9 = LocalTime.ofSecondOfDay(86399); // 0 - 86399范围内的值
LocalTime time10 = LocalTime.MAX;
LocalTime time11 = LocalTime.MIN;
LocalTime time12 = LocalTime.MIDNIGHT;
LocalTime time13 = LocalTime.NOON;

System.out.println("time4:" + time4); // 09:46:14.690
System.out.println("time5:" + time5); // 12:13
System.out.println("time6:" + time6); // 12:13:13
System.out.println("time7:" + time7); // 12:13:13.000000100
System.out.println("time8:" + time8); // 00:00:01
System.out.println("time9:" + time9); // 23:59:59
System.out.println("time10:" + time10); // 23:59:59.999999999
System.out.println("time11:" + time11); // 00:00
System.out.println("time12:" + time12); // 00:00
System.out.println("time13:" + time13); // 12:00

3.2 获取时分秒

// 获取小时
System.out.println("time4: " + time1.getHour()); // 12
// 获取分钟
System.out.println("time5: " + time1.getMinute()); // 13
// 获取秒
System.out.println("time6: " + time1.getSecond()); // 14
// 获取纳秒
System.out.println("time7: " + time1.getNano()); // 14

3.3 比较大小

System.out.println("result1:" + time1.compareTo(time2)); // 0
System.out.println("result2:" + time2.compareTo(time3)); // -1
System.out.println("result3:" + time3.compareTo(time2)); // 1
System.out.println("result4:" + time1.isAfter(time2)); // false
System.out.println("result5:" + time2.isAfter(time1)); // false
System.out.println("result6:" + time2.isAfter(time3)); // false
System.out.println("result7:" + time1.isBefore(time2)); // false
System.out.println("result8:" + time2.isBefore(time1)); // false
System.out.println("result9:" + time2.isBefore(time3)); // true
System.out.println("result10:" + time1.equals(time2)); // true
System.out.println("result11:" + time2.equals(time1)); // true
System.out.println("result12:" + time2.equals(time3)); // false

3.4 加减

// 加一小时
System.out.println("check1: " + time1.plusHours(1)); // 13:13:14
// 加一分钟
System.out.println("check2: " + time1.plusMinutes(1)); // 12:14:14
// 加一秒
System.out.println("check3: " + time1.plusSeconds(1)); // 12:13:15
// 加一纳秒   1s = 1000ms(毫秒) = 1000000us(微秒) = 1000000000ns(纳秒)
System.out.println("check4: " + time1.plusNanos(1000*1000*1000)); // 12:13:15
// 减一小时
System.out.println("check5: " + time1.minusHours(1)); // 11:13:14
// 减一秒
System.out.println("check6: " + time1.minusMinutes(1)); // 12:12:14
// 减一秒
System.out.println("check7: " + time1.minusSeconds(1)); // 12:13:13
// 减一纳秒
System.out.println("check8: " + time1.minusNanos(1)); // 12:13:13.999999999

4. LocalDateTime

获取年月日时分秒

4.1创建

LocalDateTime dateTime1 = LocalDateTime.parse("2020-10-10T12:13:14");
LocalDateTime dateTime2 = LocalDateTime.parse("2020-10-10 12:13:14", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime dateTime3 = LocalDateTime.parse("2020-10-10T13:13:13");
LocalDateTime dateTime4 = LocalDateTime.now();
LocalDate date = LocalDate.parse("2020-11-11");
LocalTime time = LocalTime.parse("12:13:14");
LocalDateTime dateTime5 = LocalDateTime.of(date,time);
LocalDateTime dateTime6 = LocalDateTime.of(2012,10, 13, 12, 13);
LocalDateTime dateTime7 = LocalDateTime.of(2012,10, 13, 12, 13, 15);
LocalDateTime dateTime8 = LocalDateTime.of(2012, Month.NOVEMBER,13, 12, 13, 14);
Instant instant = new Date().toInstant();
ZoneId zoneId = ZoneId.systemDefault();
LocalDateTime dateTime9 = LocalDateTime.ofInstant(instant, zoneId);
LocalDateTime dateTime10 = instant.atZone(zoneId).toLocalDateTime();
LocalDateTime dateTime11 = LocalDateTime.MIN;
LocalDateTime dateTime12 = LocalDateTime.MAX;

System.out.println("dateTime1:" + dateTime1); // 2020-10-10T12:13:14
System.out.println("dateTime2:" + dateTime2); // 2020-10-10T12:13:14
System.out.println("dateTime3:" + dateTime3); // 2020-10-10T13:13:13
System.out.println("dateTime4:" + dateTime4); // 2020-11-24T11:04:39.764
System.out.println("dateTime5:" + dateTime5); // 2020-11-11T12:13:14
System.out.println("dateTime6:" + dateTime6); // 2012-10-13T12:13
System.out.println("dateTime7:" + dateTime7); // 2012-10-13T12:13:15
System.out.println("dateTime8:" + dateTime8); // 2012-11-13T12:13:14
System.out.println("dateTime9:" + dateTime9); // 2020-11-24T11:04:39.765
System.out.println("dateTime10:" + dateTime10); // 2020-11-24T11:04:39.765
System.out.println("dateTime11:" + dateTime11); // -999999999-01-01T00:00
System.out.println("dateTime12:" + dateTime12); // +999999999-12-31T23:59:59.999999999

4.2 获取年月日时分秒

// 获取年
System.out.println("result1:" + dateTime1.getYear()); // 2020
// 获取英文月
System.out.println("result2:" + dateTime1.getMonth()); // OCTOBER
// 获取数字月
System.out.println("result3:" + dateTime1.getMonthValue()); // 10
// 获取一年第几天
System.out.println("result4:" + dateTime1.getDayOfYear()); // 284
// 获取几号
System.out.println("result5:" + dateTime1.getDayOfMonth()); // 10
// 获取周几
System.out.println("result6:" + dateTime1.getDayOfWeek()); // SATURDAY
// 获取小时
System.out.println("result7:" + dateTime1.getHour()); // 12
// 获取分钟
System.out.println("result8:" + dateTime1.getMinute()); // 13
// 获取秒
System.out.println("result9:" + dateTime1.getSecond()); // 14
// 获取纳秒
System.out.println("result10:" + dateTime1.getNano()); // 0
// 获取毫秒
System.out.println("result11:" + dateTime1.toEpochSecond(ZoneOffset.of("+8"))); // 1602303194
System.out.println("result12:" + dateTime1.toInstant(ZoneOffset.of("+8")).toEpochMilli()); // 1602303194000
// 获取2022当前日期时间
System.out.println("result17:" + dateTime1.withYear(2022)); // 2022-10-10T12:13:14
// 获取当前日期时间所在年的第55天所在的日期时间
System.out.println("result18:" + dateTime1.withDayOfYear(55)); // 2020-02-24T12:13:14
// 获取当前日期时间所在月的12号所在的日期时间
System.out.println("result19:" + dateTime1.withDayOfMonth(12)); // 2020-10-12T12:13:14
// 获取当前日期时间所在天的第13个小时所在的日期时间
System.out.println("result20:" + dateTime1.withHour(13)); // 2020-10-10T13:13:14
// 获取当前日期时间所在小时的第13分钟所在的日期时间
System.out.println("result21:" + dateTime1.withMinute(13)); // 2020-10-10T12:13:14
// 获取当前日期时间所在分钟的第13秒所在的日期时间
System.out.println("result22:" + dateTime1.withSecond(13)); // 2020-10-10T12:13:13
// 获取当前日期时间所在秒的第13纳秒时所在的日期时间
System.out.println("result23:" + dateTime1.withNano(13)); // 2020-10-10T12:13:14.000000013

4.3 比较大小

System.out.println("result1:" + dateTime1.compareTo(dateTime2)); // 0
System.out.println("result2:" + dateTime2.compareTo(dateTime3)); // -1
System.out.println("result3:" + dateTime3.compareTo(dateTime2)); // 1
System.out.println("result4:" + dateTime1.isAfter(dateTime2)); // false
System.out.println("result5:" + dateTime2.isAfter(dateTime1)); // false
System.out.println("result6:" + dateTime2.isAfter(dateTime3)); // false
System.out.println("result7:" + dateTime1.isBefore(dateTime2)); // false
System.out.println("result8:" + dateTime2.isBefore(dateTime1)); // false
System.out.println("result9:" + dateTime2.isBefore(dateTime3)); // true
System.out.println("result10:" + dateTime1.equals(dateTime2)); // true
System.out.println("result11:" + dateTime2.equals(dateTime1)); // true
System.out.println("result12:" + dateTime2.equals(dateTime3)); // false

4.4加减

// 加一年
System.out.println("result1:" + dateTime1.plusYears(1)); // 2021-10-10T12:13:14
// 加一月
System.out.println("result2:" + dateTime1.plusMonths(1)); // 2020-11-10T12:13:14
// 加一周
System.out.println("result3:" + dateTime1.plusWeeks(1)); // 2020-10-17T12:13:14
// 加一天
System.out.println("result4:" + dateTime1.plusDays(1)); // 2020-10-11T12:13:14
// 加一小时
System.out.println("result5:" + dateTime1.plusHours(1)); // 2020-10-10T13:13:14
// 加一分钟
System.out.println("result6:" + dateTime1.plusMinutes(1)); // 2020-10-10T12:14:14
// 加一秒
System.out.println("result7:" + dateTime1.plusSeconds(1)); // 2020-10-10T12:13:15
// 加一纳秒
System.out.println("result8:" + dateTime1.plusNanos(1)); // 2020-10-10T12:13:14.000000001
// 减一年
System.out.println("result9:" + dateTime1.minusYears(1)); // 2019-10-10T12:13:14
// 减一月
System.out.println("result10:" + dateTime1.minusMonths(1)); // 2020-09-10T12:13:14
// 减一周
System.out.println("result11:" + dateTime1.minusWeeks(1)); // 2020-10-03T12:13:14
// 减一天
System.out.println("result12:" + dateTime1.minusDays(1)); // 2020-10-09T12:13:14
// 减一小时
System.out.println("result13:" + dateTime1.minusHours(1)); // 2020-10-10T11:13:14
// 减一分钟
System.out.println("result14:" + dateTime1.minusMinutes(1)); // 2020-10-10T12:12:14
// 减一秒
System.out.println("result15:" + dateTime1.minusSeconds(1)); // 2020-10-10T12:13:13
// 减一纳秒
System.out.println("result16:" + dateTime1.minusNanos(1)); // 2020-10-10T12:13:13.999999999

5. LocalTime、LocalDate、LocalDateTime互转

5.1 LocalDateTime转LocaDate

LocalDateTime dateTime = LocalDateTime.parse("2020-10-10T12:13:14");
System.out.println("result1:" + dateTime1.toLocalDate()); // 2020-10-10

5.2 LocalDateTime转LocalTime

LocalDateTime dateTime = LocalDateTime.parse("2020-10-10T12:13:14");
System.out.println("result2:" + dateTime1.toLocalTime()); // 12:13:14

5.3 LocalDate转LocalDateTime

LocalDate date = LocalDate.parse("2020-10-10");
System.out.println("result1:" + date.atStartOfDay()); // 2020-10-10T00:00
System.out.println("result2:" + date.atTime(12, 13)); // 2020-10-10T12:13
System.out.println("result3:" + date.atTime(12, 13, 14)); // 2020-10-10T12:13:14
System.out.println("result4:" + date.atTime(12, 13, 14, 1000)); // 2020-10-10T12:13:14.000001

5.4 LocalDate、LocalTime转LocalDateTime

LocalDate date = LocalDate.parse("2020-10-10");
LocalTime time = LocalTime.parse("12:13:14");
System.out.println("result1:" + date.atTime(time)); // 2020-10-10T12:13:14
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值