Java8日期、时间操作
介绍
Java 8发布了新的 Date-Time API 进一步加强了对日期与时间的处理。
在 Java 8之前,我们习惯使用 Joda-Time 来完成日期时间操作,现 Java 8的日期操作已充分吸收整合了 Joda-Time的优势。
Joda-Time is the de facto standard date and time library for Java prior to Java SE 8. Users are now asked to migrate to
java.time(JSR-310).
Joda-Time 官网也推荐用户向 java.time 迁移。
使用
接下来将挑选工作中常用的类进行介绍并给出常用使用案例,更详细的使用请查阅官方 API 文档。
认面孔
ZoneId:时区 ID ,用来确定 Instant 和 LocalDateTime 互相转换的规则
Instant:用来表示时间线上的一个点(瞬时)
LocalDate:表示没有时区的日期(只含年月日)
LocalTime:表示没有时区的时间(只含时分秒)
LocalDateTime:表示没有时区的日期时间(年月日时分秒)
Clock:用于访问当前时刻、日期、时间,用到时区
Duration:用秒和纳秒表示时间的长短,用于计算两个日期的”时间“间隔
Period:用于计算两个"日期"间隔
案例
日期时间创建
/** 1.LocalDate **/
// 获取当前日期,2021/5/8
LocalDate localDate = LocalDate.now();
// of方法创建日期,2021/5/8
LocalDate localDate1 = LocalDate.of(2021, 5, 8);
/** 2.LocalTime **/
// 获取当前时间 8:00:00
LocalTime localTime = LocalTime.now();
// of方法创建时间,精确到秒 8:00:00
LocalTime localTime1 = LocalTime.of(8, 0, 0);
// of方法创建时间,精确到毫秒 8:00:00
LocalTime localTime2 = LocalTime.of(8, 0, 0, 0);
/** 3.LocalDateTime **/
// 获取当前日期时间,2021-05-08 08:00:00
LocalDateTime localDateTime = LocalDateTime.now();
// 通过LocalDate对象和LocalTime对象组装,2021-05-08 08:00:00
LocalDateTime localDateTime1 = LocalDateTime.of(localDate, localTime);
// 填入年月日时分秒创建,2021-05-08 08:00:00
LocalDateTime localDateTime2 = LocalDateTime.of(2021, 5, 8, 8, 0, 0);
日期时间增减
/** LocalDate **/
LocalDate today = LocalDate.now(); // 2021-01-01
/* plus操作,针对年、月、日的plus */
LocalDate tomorrow = today.plusDays(1L); // 加一天,2021-01-02
LocalDate nextWeek = today.plusWeeks(1L); // 加一周,2021-01-08
LocalDate nextMonth = today.plusMonths(1L); // 加一月,2021-02-01
LocalDate nextYear = today.plusYears(1L); // 加一年,2022-01-01
/* minus操作,不再累述 */
LocalDate yesterday = today.minusDays(1); // 减一天,2019-12-31
/** LocalTime **/
/* plus操作,针对时、分、秒、毫秒的plus */
LocalTime nowTime = LocalTime.now(); // 08:00:00
LocalTime afterOneHour = nowTime.plusHours(1L); // 加一小时,09:00:00
/* minus操作,不再累述 */
LocalTime anHourAgo = nowTime.minusHours(1L); // 减一小时,07:00:00
/** LocalDateTime **/
// 不再累述,可针对年、月、日、时、分、秒、毫秒,进行增减
日期时间比较
快速判断两个日期时间的大小
/** LocalDate为例,LocalDateTime和LocalTime类似 **/
LocalDate today = LocalDate.now(); // 2021-01-01
LocalDate tomorrow = today.plusDays(1L); // 2021-01-02
/* LocalDate自带的比较方法 */
System.out.println(tomorrow.isAfter(today)); // true,tomorrow是否在today之后
System.out.println(tomorrow.isBefore(today)); // false,tomorrow是否在today之前
System.out.println(tomorrow.isEqual(today)); // false,tomorrow是否和today一致
日期时间差获取
获取两个日期时间之间的差值
// 方式一:Period类
LocalDate day1 = LocalDate.of(2020, 5, 1);
LocalDate day2 = LocalDate.of(2021, 5, 10);
Period between = Period.between(day1, day2); // 合计相差 1年0月9天
between.getDays(); // 9
between.getMonths(); // 0
between.getYears(); // 1
// 方式二:ChronoUnit类
LocalDateTime localDateTime1 = LocalDateTime.of(2020,4,1,8,0,0);
LocalDateTime localDateTime2 = LocalDateTime.of(2021,5,2,8,5,5);
System.out.println(ChronoUnit.DAYS.between(localDateTime1, localDateTime2)); // 396天
System.out.println(ChronoUnit.MONTHS.between(localDateTime1, localDateTime2)); // 13月
System.out.println(ChronoUnit.YEARS.between(localDateTime1, localDateTime2)); // 1年
System.out.println(ChronoUnit.HOURS.between(localDateTime1, localDateTime2)); // 9504时
System.out.println(ChronoUnit.MINUTES.between(localDateTime1, localDateTime2)); // 570245分
System.out.println(ChronoUnit.SECONDS.between(localDateTime1, localDateTime2)); // 34214705秒
转型
将贴出各类型之间的转型案例
/* 1.【String 转 LocalDate】 */
// 默认格式转型 yyyy-MM-dd
String todayStr = "2021-04-01";
LocalDate today = LocalDate.parse(todayStr);
// 指定格式化转型 yyyy/MM/dd
String todayStr2 = "2021/04/01";
LocalDate today2 = LocalDate.parse(todayStr2, DateTimeFormatter.ofPattern("yyyy/MM/dd"));
/* 2.【LocalDate 转 String】 */
LocalDate today = LocalDate.now();
today.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) // 2021-04-01
today.format(DateTimeFormatter.ofPattern("yyyyMMdd")) // 20210401
/* 3.【String 转 LocalDateTime】 */
String todayTimeStr = "2021-04-01 08:00:00";
LocalDateTime localDateTime = LocalDateTime.parse(todayStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
/* 4.【LocalDateTime 转 String】 */
localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) // 2021-04-01 08:00:00
/* 5.【Date 转 LocalDate】 */
Date date = new Date();
date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
/* 6.【LocalDate 转 Date】 */
Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant());
/* 7.【Date 转 LocalDateTime】 */
date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
/* 8.【LocalDateTime 转 Date】 */
Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
扩展信息获取
当我们拥有一个 LocalDate 对象后,可能想获取一些延伸信息,如这个日期在本月是第几天等等。
LocalTime localtime = LocalTime.now();
LocalDate localDate = LocalDate.now(); // 2021-05-08
LocalDateTime localDateTime = LocalDateTime.now();
int dayOfMonth = localDate.getDayOfMonth(); // 8,当前日期是本月的第几天
int dayOfWeek = localDate.getDayOfWeek().getValue(); // 6,当前日期是本周的第几天
LocalDate firstDayOfThisMonth = localDate.with(TemporalAdjusters.firstDayOfMonth()); // 2021-05-01,当前日期所在月的第一天
LocalDate lastDayOfThisMonth = localDate.with(TemporalAdjusters.lastDayOfMonth()); // 2021-05-31,当前日期所在月的最后一天