Java8新特性之——新日期时间 API

一、简介

在旧版的 Java 中,日期时间 API 存在很多问题:线程不安全、命名不清晰不统一、时区处理麻烦

所以在 Java 8 中提供了新的日期时间 API,我们重点学习下 LocalDateLocalTimeLocalDateTime三个类

  • LocalDate年月日格式时间类型
  • LocalTime时分秒格式时间类型
  • LocalDateTime年月日时分秒格式时间类型

二、方法介绍

LocalDateLocalTimeLocalDateTime 三个类提供的方法可以分为以下几类:

  • 创建:now(),of(),parse()
  • 修改:with(),plus(),minus()
  • 比较:until(),compareTo(),isAfter(),isBefore(),isEqual()
  • 获取:getYear()、getMonth()、getMonthValue()、getDayOfMonth()、getDayOfYear()、getDayOfWeek()、getHour()、getMinute()、getSecond()、getNano()
  • 格式化:format()
  • 相互转换:atStartOfDay()、atTime()、atDate()、toLocalDate()、toLocalTime()

创建:now(),of(),parse()

now():获取当前时间

//------------------------- LocalDate -------------------------

//当前日期
LocalDate localDate = LocalDate.now();
//某个时区的当前日期
LocalDate localDate2 = localDate.now(ZoneId.of("America/Chicago"));
System.out.println(localDate);//2023-08-28
System.out.println(localDate2);//2023-08-28

//------------------------- LocalTime -------------------------

//当前时间
LocalTime localTime = LocalTime.now();
//某个时区的当前时间
LocalTime localTime2 = LocalTime.now(ZoneId.of("America/Chicago"));
System.out.println(localTime);//11:22:11.394
System.out.println(localTime2);//01:07:50.024

//------------------------- LocalDateTime -------------------------

//当前日期+时间
LocalDateTime localDateTime = LocalDateTime.now();
//某个时区的当前日期+时间
LocalDateTime localDateTime2 = LocalDateTime.now(ZoneId.of("America/Chicago"));
System.out.println(localDateTime);//2023-08-28T11:22:11.394
System.out.println(localDateTime2);//2023-08-28T01:07:50.024

of():获取指定时间

//------------------------- LocalDate -------------------------

//年月日
LocalDate localDate = LocalDate.of(2023, 8, 30);
System.out.println(localDate);//2023-08-30

//------------------------- LocalTime -------------------------

//时分
LocalTime localTime = LocalTime.of(13, 55);
//时分秒
LocalTime localTime2 = LocalTime.of(13, 55, 56);
//时分秒纳秒(1毫秒=1000000 纳秒)
LocalTime localTime3 = LocalTime.of(13, 55, 56, 553000000);
System.out.println(localTime);//13:55
System.out.println(localTime2);//13:55:56
System.out.println(localTime3);//13:55:56.553

//------------------------- LocalDateTime -------------------------

//年月日时分
LocalDateTime localDateTime = LocalDateTime.of(2023, 8, 30, 13, 55);
//年月日时分秒
LocalDateTime localDateTime2 = LocalDateTime.of(2023, 8, 30, 13, 55, 56);
//年月日时分秒毫秒(1毫秒=1000000 纳秒)
LocalDateTime localDateTime3 = LocalDateTime.of(2023, 8, 30, 13, 55, 56, 553000000);
//传入 LocalDate + LocalTime
LocalDateTime localDateTime4 = LocalDateTime.of(localDate, localTime);
System.out.println(localDateTime);//2023-08-30T13:55
System.out.println(localDateTime2);//2023-08-30T13:55:56
System.out.println(localDateTime3);//2023-08-30T13:55:56.553
System.out.println(localDateTime4);//2023-08-30T13:55

parse():格式化,字符串转日期时间

//------------------------- LocalDate -------------------------

//格式化时间
LocalDate localDate = LocalDate.parse("2023-08-29");
//格式化时间,传入格式
LocalDate localDate2 = LocalDate.parse("2023/08/29", DateTimeFormatter.ofPattern("yyyy/MM/dd"));
System.out.println(localDate);//2023-08-28
System.out.println(localDate2);//2023-08-29

//------------------------- LocalTime -------------------------

//格式化时间
LocalTime localTime = LocalTime.parse("14:33:33");
//格式化时间,传入格式
LocalTime localTime2 = LocalTime.parse("14:33:33.543", DateTimeFormatter.ofPattern("HH:mm:ss.SSS"));
System.out.println(localTime);//14:33:33
System.out.println(localTime2);//14:33:33.543

//------------------------- LocalDateTime -------------------------

//格式化日期时间
LocalDateTime localDateTime = LocalDateTime.parse("2023-08-29T14:33:33");
//格式化日期时间,传入格式
LocalDateTime localDateTime2 = LocalDateTime.parse("2023-08-29 14:33:33", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(localDateTime);//2023-08-29T14:33:33
System.out.println(localDateTime2);//2023-08-29T14:33:33

修改:with(),plus(),minus()

每次修改都是创建新对象,不会影响原本的值

with():修改日期时间

//------------------------- LocalDate -------------------------

LocalDate localDate = LocalDate.of(2023, 8, 28);

//修改为当月第一天
LocalDate firstDayOfMonth = localDate.with(TemporalAdjusters.firstDayOfMonth());
System.out.println(firstDayOfMonth);//2023-08-01
//修改为上一个周四
LocalDate firstDayOfNextMonth = localDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.THURSDAY));
System.out.println(firstDayOfNextMonth);//2023-08-24
//修改为20号
LocalDate dayOfMonth = localDate.with(ChronoField.DAY_OF_MONTH, 20);
System.out.println(dayOfMonth);//2023-08-20

//修改年份为2024年
LocalDate localDate2 = localDate.withYear(2024);
System.out.println(localDate2);//2024-08-28
//修改月份为9月
LocalDate localDate3 = localDate.withMonth(9);
System.out.println(localDate3);//2023-09-28
//修改为20号
LocalDate localDate4 = localDate.withDayOfMonth(20);
System.out.println(localDate4);//2023-08-20
//修改为当年第200天
LocalDate localDate5 = localDate.withDayOfYear(200);
System.out.println(localDate5);//2023-07-19

//------------------------- LocalTime -------------------------

LocalTime localTime = LocalTime.parse("14:33:33");

//修改为10点
LocalTime localTime2 = localTime.withHour(10);
System.out.println(localTime2);//10:33:33
//修改为第33分钟
LocalTime localTime3 = localTime.withMinute(33);
System.out.println(localTime3);//14:33:33
//修改为第22秒
LocalTime localTime4 = localTime.withSecond(22);
System.out.println(localTime4);//14:33:22
//修改纳秒
LocalTime localTime5 = localTime.withNano(543000000);
System.out.println(localTime5);//14:33:33.543

//------------------------- LocalDateTime -------------------------

//with(TemporalAdjusters)的用法可以参考LocalDate
//with的用法相当于是LocalDate和LocalTime的结合

with(TemporalAdjuster):修改为特定的一个日期:如本月第一天,本周一等

这个方法在日常开发中用处比较大,特地拉出来记录一下, TemporalAdjusters 的静态方法返回都是这个TemporalAdjuster 类型,这是一个函数接口,内部封装的 Lambda 表达式,里面其实是 with()plus() 等方法组合使用,可以学习下,封装自己的日期工具类可以用的上,下面看下它自带的几个方法,适用于 LocalDateLocalDateTime,这里只拿 LocalDate 举例

LocalDate localDate = LocalDate.of(2023, 8, 28);

//当月第一天
LocalDate firstDayOfMonth = localDate.with(TemporalAdjusters.firstDayOfMonth());
System.out.println(firstDayOfMonth);//2023-08-01
//当月最后一天
LocalDate lastDayOfMonth = localDate.with(TemporalAdjusters.lastDayOfMonth());
System.out.println(lastDayOfMonth);//2023-08-31
//下月第一天
LocalDate firstDayOfNextMonth = localDate.with(TemporalAdjusters.firstDayOfNextMonth());
System.out.println(firstDayOfNextMonth);//2023-09-01
//当年第一天
LocalDate firstDayOfYear = localDate.with(TemporalAdjusters.firstDayOfYear());
System.out.println(firstDayOfYear);//2023-01-01
//当年最后一天
LocalDate lastDayOfYear = localDate.with(TemporalAdjusters.lastDayOfYear());
System.out.println(lastDayOfYear);//2023-12-31
//明年第一天
LocalDate firstDayOfNextYear = localDate.with(TemporalAdjusters.firstDayOfNextYear());
System.out.println(firstDayOfNextYear);//2024-01-01
//本月第一个星期x,本月第一个星期一
LocalDate firstInMonth = localDate.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
System.out.println(firstInMonth);//2023-08-07
//本月最后一个星期x,本月最后一个星期一
LocalDate lastInMonth = localDate.with(TemporalAdjusters.lastInMonth(DayOfWeek.MONDAY));
System.out.println(lastInMonth);//2023-08-28
//本月第x个星期x,本月第2个星期一
LocalDate dayOfWeekInMonth = localDate.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.MONDAY));
System.out.println(dayOfWeekInMonth);//2023-08-14
//下一个星期x(不包含指定日期),下一个星期一
LocalDate next = localDate.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
System.out.println(next);//2023-08-31
//下一个星期x(包含指定日期),下一个星期一
LocalDate nextOrSame = localDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.MONDAY));
System.out.println(nextOrSame);//2023-08-28
//上一个星期x(不包含指定日期),上一个星期一
LocalDate previous = localDate.with(TemporalAdjusters.previous(DayOfWeek.MONDAY));
System.out.println(previous);//2023-08-21
//上一个星期x(包含指定日期),上一个星期一
LocalDate previousOrSame = localDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY));
System.out.println(previousOrSame);//2023-08-28

plus():增加

//------------------------- LocalDate -------------------------

LocalDate localDate = LocalDate.of(2023, 8, 28);
System.out.println(localDate);//2023-08-28
//加1年
LocalDate localDate2 = localDate.plusYears(1);
System.out.println(localDate2);//2024-08-28
//加2个月
LocalDate localDate3 = localDate.plusMonths(2);
System.out.println(localDate3);//2023-10-28
//加3周
LocalDate localDate4 = localDate.plusWeeks(3);
System.out.println(localDate4);//2023-09-18
//加10天
LocalDate localDate5 = localDate.plusDays(10);
System.out.println(localDate5);//2023-09-07

//------------------------- LocalTime -------------------------

LocalTime localTime = LocalTime.parse("14:33:33");
System.out.println(localTime);//14:33:33
//加1小时
LocalTime localTime2 = localTime.plusHours(1);
System.out.println(localTime2);//15:33:33
//加2分钟
LocalTime localTime3 = localTime.plusMinutes(2);
System.out.println(localTime3);//14:35:33
//加3秒
LocalTime localTime4 = localTime.plusSeconds(3);
System.out.println(localTime4);//14:33:36

//------------------------- LocalDateTime -------------------------

//用法相当于是LocalDate和LocalTime的结合

虽然传参传负数可以达到和减少一样的效果,但是因为单一职责原则,还是推荐使用 minus 方法减少

minus():减少

//------------------------- LocalDate -------------------------

LocalDate localDate = LocalDate.of(2023, 8, 28);
System.out.println(localDate);//2023-08-28

//减1年
LocalDate localDate2 = localDate.minusYears(1);
System.out.println(localDate2);//2022-08-28
//减2个月
LocalDate localDate3 = localDate.minusMonths(2);
System.out.println(localDate3);//2023-06-28
//减3周
LocalDate localDate4 = localDate.minusWeeks(3);
System.out.println(localDate4);//2023-08-07
//减10天
LocalDate localDate5 = localDate.minusDays(10);
System.out.println(localDate5);//2023-08-18

//------------------------- LocalTime -------------------------

LocalTime localTime = LocalTime.parse("14:33:33");
System.out.println(localTime);//14:33:33
//减1小时
LocalTime localTime2 = localTime.minusHours(1);
System.out.println(localTime2);//13:33:33
//减2分钟
LocalTime localTime3 = localTime.minusMinutes(2);
System.out.println(localTime3);//14:31:33
//减3秒
LocalTime localTime4 = localTime.minusSeconds(3);
System.out.println(localTime4);//14:33:30

//------------------------- LocalDateTime -------------------------

//用法相当于是LocalDate和LocalTime的结合

虽然传参传负数可以达到和增加一样的效果,但是因为单一职责原则,还是推荐使用 plus 方法增加

比较:until(),compareTo(),isAfter(),isBefore(),isEqual()

until():间隔

//------------------------- LocalDate -------------------------

LocalDate startDate = LocalDate.of(2023, 1, 1);
LocalDate endDate = LocalDate.of(2023, 12, 31);

//间隔几个月
long months = startDate.until(endDate, ChronoUnit.MONTHS);
System.out.println(months);//11
//间隔几天
long days = startDate.until(endDate, ChronoUnit.DAYS);
System.out.println(days);//364

//------------------------- LocalTime -------------------------

LocalTime startTime = LocalTime.of(12, 0, 0);
LocalTime endTime = LocalTime.of(13, 14, 15);

//间隔几分钟
long minutes = startTime.until(endTime, ChronoUnit.MINUTES);
System.out.println(minutes);//74
//间隔几秒
long seconds = startTime.until(endTime, ChronoUnit.SECONDS);
System.out.println(seconds);//4455

//------------------------- LocalDateTime -------------------------

//用法相当于是LocalDate和LocalTime的结合

compareTo(),isAfter(),isBefore(),isEqual():比较先后

//------------------------- LocalDate -------------------------

LocalDate date1 = LocalDate.of(2023, 1, 1);
LocalDate date2= LocalDate.of(2023, 12, 31);

//比较先后,0表示日期一样,负数表示date1早于date2,正数表示date1晚于date2
int compareTo = date1.compareTo(date2);
System.out.println(compareTo);//-11
//比较date1是否早于date2,早于返回true,否则返回false,日期相同也返回false
boolean before = date1.isBefore(date2);
System.out.println(before);//true
//比较date1是否晚于date2,晚于返回true,否则返回false,日期相同也返回false
boolean after = date1.isAfter(date2);
System.out.println(after);//false
//比较两个日期是否相同,相同返回true,否则返回false
boolean equal = date1.isEqual(date2);
System.out.println(equal);//false

//------------------------- LocalTime -------------------------

LocalTime time1 = LocalTime.of(12, 0, 0);
LocalTime time2 = LocalTime.of(13, 14, 15);

//比较先后,0表示时间一样,负数表示time1早于time2,正数表示time1晚于time2
int compareTo2 = time1.compareTo(time2);
System.out.println(compareTo2);//-1
//比较time1是否早于time2,早于返回true,否则返回false,日期相同也返回false
boolean before2 = time1.isBefore(time2);
System.out.println(before2);//true
//比较time1是否晚于time2,晚于返回true,否则返回false,日期相同也返回false
boolean after2 = time1.isAfter(time2);
System.out.println(after2);//false
//LocalTime没有isEqual方法,可以直接使用equals方法
boolean equal2 = time1.equals(time2);
System.out.println(equal2);//false

//------------------------- LocalDateTime -------------------------

//用法相当于是LocalDate和LocalTime的结合

获取:getYear()、getMonth()、getMonthValue()、getDayOfMonth() …

//------------------------- LocalDate -------------------------

LocalDate localDate = LocalDate.of(2023, 8, 28);
//获取年份
System.out.println(localDate.getYear());//2023
//获取月份,枚举类
System.out.println(localDate.getMonth());//AUGUST
//获取月份
System.out.println(localDate.getMonthValue());//8
//获取几号
System.out.println(localDate.getDayOfMonth());//28
//获取一年中第多少填
System.out.println(localDate.getDayOfYear());//240
//获取星期几,枚举类
System.out.println(localDate.getDayOfWeek());//MONDAY

//------------------------- LocalTime -------------------------

LocalTime localTime = LocalTime.parse("14:33:35.543");
//获取小时
System.out.println(localTime.getHour());//14
//获取分钟
System.out.println(localTime.getMinute());//33
//获取秒
System.out.println(localTime.getSecond());//35
//获取纳秒
System.out.println(localTime.getNano());//543000000

//------------------------- LocalDateTime -------------------------

//用法相当于是LocalDate和LocalTime的结合

格式化:format()

//------------------------- LocalDate -------------------------

LocalDate localDate = LocalDate.of(2023, 8, 30);
//第一种方式
String dateStr = localDate.format(DateTimeFormatter.ISO_LOCAL_DATE);
System.out.println(dateStr);//2023-08-30
//第二种方式
String dateStr2 = DateTimeFormatter.ISO_LOCAL_DATE.format(localDate);
System.out.println(dateStr2);//2023-08-30

//------------------------- LocalTime -------------------------

LocalTime localTime = LocalTime.of(13, 55, 56);
//第一种方式
String timeStr = localTime.format(DateTimeFormatter.ISO_LOCAL_TIME);
System.out.println(timeStr);//13:55:56
//第二种方式
String timeStr2 = DateTimeFormatter.ISO_LOCAL_TIME.format(localTime);
System.out.println(timeStr2);//13:55:56

//------------------------- LocalDateTime -------------------------

LocalDateTime localDateTime = LocalDateTime.of(2023, 8, 30, 13, 55, 56);
//第一种方式
String dateTimeStr = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(dateTimeStr);//2023-08-30 13:55:56
//第二种方式
String dateTimeStr2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(localDateTime);
System.out.println(dateTimeStr2);//2023-08-30 13:55:56

转换:atStartOfDay()、atTime()、atDate()、toLocalDate()、toLocalTime()

LocalDate localDate = LocalDate.of(2023, 8, 30);
LocalTime localTime = LocalTime.of(13, 55, 56);
LocalDateTime localDateTime = LocalDateTime.of(2023, 8, 30, 13, 55, 56);

//------------------------- LocalDate转LocalDateTime -------------------------

//使用atStartOfDay方法转当天的0点
LocalDateTime localDateTime1 = localDate.atStartOfDay();
System.out.println(localDateTime1);//2023-08-30T00:00
//使用atTime传入LocalTime拼接日期和时间
LocalDateTime localDateTime2 = localDate.atTime(localTime);
System.out.println(localDateTime2);//2023-08-30T13:55:56
//使用atTime传入时、分拼接日期和时间
LocalDateTime localDateTime3 = localDate.atTime(13, 55);
System.out.println(localDateTime3);//2023-08-30T13:55
//使用atTime传入时、分、秒拼接日期和时间
LocalDateTime localDateTime4 = localDate.atTime(13, 55, 56);
System.out.println(localDateTime4);//2023-08-30T13:55:56
//使用atTime传入时、分、秒、纳秒拼接日期和时间
LocalDateTime localDateTime5 = localDate.atTime(13, 55, 56, 543000000);
System.out.println(localDateTime5);//2023-08-30T13:55:56.543

//------------------------- LocalTime转LocalDateTime -------------------------

//使用atDate传入LocalDate拼接日期和时间
LocalDateTime localDateTime6 = localTime.atDate(localDate);
System.out.println(localDateTime6);//2023-08-30T13:55:56

//------------------------- LocalDateTime转LocalDate、LocalTime -------------------------

//调用toLocalDate方法转LocalDate
LocalDate localDate1 = localDateTime.toLocalDate();
System.out.println(localDate1);//2023-08-30
//调用toLocalTime方法转LocalTime
LocalTime localTime1 = localDateTime.toLocalTime();
System.out.println(localTime1);//13:55:56

三、和 Date 之间转换

LocalDate 转 Date

LocalDate localDate = LocalDate.of(2023, 8, 30);
Date date = Date.from(localDate.atStartOfDay().atZone(ZoneId.systemDefault()).toInstant());
System.out.println(date);//Wed Aug 30 00:00:00 CST 2023

Date 转 LocalDate

Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
System.out.println(localDate);//2023-08-29

LocalDateTime 转 Date

LocalDateTime localDateTime = LocalDateTime.of(2023, 8, 30, 13, 55, 56);
Date date = Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
System.out.println(date);//Wed Aug 30 13:55:56 CST 2023

Date 转 LocalDateTime

Date date = new Date();
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
System.out.println(localDateTime);//2023-08-29T15:29:53.225
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每天进步亿点点的小码农

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值