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

文章目录

一、简介

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

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

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

二、方法介绍

LocalDate、LocalTime、LocalDateTime 三个类提供的方法可以分为以下几类:

  • 创建: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():获取当前时间

java 复制代码
//------------------------- 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():获取指定时间

java 复制代码
//------------------------- 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():格式化,字符串转日期时间

java 复制代码
//------------------------- 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():修改日期时间

java 复制代码
//------------------------- 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() 等方法组合使用,可以学习下,封装自己的日期工具类可以用的上,下面看下它自带的几个方法,适用于 LocalDate 和 LocalDateTime,这里只拿 LocalDate 举例

java 复制代码
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():增加

java 复制代码
//------------------------- 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():减少

java 复制代码
//------------------------- 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():间隔

java 复制代码
//------------------------- 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():比较先后

java 复制代码
//------------------------- 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() ...

java 复制代码
//------------------------- 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()

java 复制代码
//------------------------- 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()

java 复制代码
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

java 复制代码
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

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

LocalDateTime 转 Date

java 复制代码
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

java 复制代码
Date date = new Date();
LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
System.out.println(localDateTime);//2023-08-29T15:29:53.225
相关推荐
code2cat1 小时前
【随笔】MCP资源更新订阅:通知到达以后,Agent怎样刷新旧资料
java·后端·开发工具·ai agent·mcp
福兮说1 小时前
URL 编码的七个坑:c++ 传到后端变空格、%25 套娃、截断 emoji 直接报错
开发语言·前端·javascript·node.js·url
小的时候可菜了1 小时前
JS 异步的本质:从单线程到 thenable(一条进化链)
开发语言·前端·javascript
可乐鸡翅yeah_2 小时前
hls.js 配置 loadStartPosition,点播起始播放位置踩坑
开发语言·javascript·网络协议·ecmascript·m3u8在线
一只旭宝2 小时前
C++ 后端开发面试题整理
java·c++·面试
sunshine22 girl2 小时前
Java学习五 面向对象高级5 内部类3-静态内部类和局部内部类(了解)
java·学习
en.en..2 小时前
Linux 进程退出exit(函数)
java·开发语言·算法
李游Leo2 小时前
HarmonyOS 7 TaskPool + Node-API + zstd:Native 批量压缩任务的主线程隔离、进度回传与资源收口【鸿蒙心迹】
java·华为·harmonyos
Cx330❀2 小时前
【Qt 进阶指南】详解 Qt 常用标准对话框与主窗口组件架构
开发语言·qt·ui·性能优化·架构·图形渲染
Light Gao2 小时前
Encoder 与 Decoder 详解:从 Embedding 到 Seq2Seq 的完整数据流
java·开发语言·embedding