文章为本人原创,创作不易,如果对您有帮助,点赞收藏加关注。
jdk8的time包出来已经好多年了,可是很多小伙伴平时不怎么用,用的时候就需要再去看文档。
本文会将time包常用的类与可能使用到的情况记录下来,大家可以随时查看。
这篇文章只会包含无时区的日期时间处理。
表示日期时间的类Instant年月日时分秒毫秒时区,协调世界时,转成其它时间类需要本地时区
LocalDateTime年月日时分秒毫秒
LocalDate年月日
LocalTime时分秒毫秒
Year年
YearMonth年月
MonthDay月日注意:新增的日期时间类都是不可变的
获取
获取当前日期时间
// 2020-03-25T13:18:51.052775200ZSystem.out.println(Instant.now());
// 2020-03-25T21:18:51.064769800System.out.println(LocalDateTime.now());
// 2020-03-25System.out.println(LocalDate.now());
// 21:18:51.064769800System.out.println(LocalTime.now());
// 2020System.out.println(Year.now());
// 2020-03System.out.println(YearMonth.now());
// --03-25System.out.println(MonthDay.now());
获取指定日期时间
// 2020-03-25T21:44:32LocalDateTime.of(2020, 3, 25, 21, 44, 32);
// 2020-03-25LocalDate.of(2020, 3, 25);
// 21:44:32LocalTime.of(21, 44, 32);
// 2020Year.of(2020);
// 2020-03YearMonth.of(2020, 3);
// --03-25MonthDay.of(3, 25);
获取相邻的日期时间
指定日期
// 指定日期 2019-02-09LocalDate localDate = LocalDate.of(2019, 2, 9);
// 这个月的第一天 2019-02-01localDate.with(TemporalAdjusters.firstDayOfMonth());
// 这个月的最后一天 2019-02-28localDate.with(TemporalAdjusters.lastDayOfMonth());
// 下个月的第一天 2019-03-01localDate.with(TemporalAdjusters.firstDayOfNextMonth());
// 这一年的第一天 2019-01-01localDate.with(TemporalAdjusters.firstDayOfYear());
// 这一年的最后一天 2019-12-31localDate.with(TemporalAdjusters.lastDayOfYear());
// 下一年的第一天 2020-01-01localDate.with(TemporalAdjusters.firstDayOfNextYear());
// 这个月的第一个星期一 2019-02-04localDate.with(TemporalAdjusters.firstInMonth(DayOfWeek.MONDAY));
// 这个月的最后一个星期一 2019-02-25localDate.with(TemporalAdjusters.lastInMonth(DayOfWeek.MONDAY));
// 这个月的第二个星期一 2019-02-11localDate.with(TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.MONDAY));
// 这个月的倒数第二个星期一 2019-02-18localDate.with(TemporalAdjusters.dayOfWeekInMonth(-2, DayOfWeek.MONDAY));
// 下一个星期六 2019-02-16localDate.with(TemporalAdjusters.next(DayOfWeek.SATURDAY));
// 下一个星期六,可以是当天 2019-02-09localDate.with(TemporalAdjusters.nextOrSame(DayOfWeek.SATURDAY));
// 上一个星期六 2019-02-02localDate.with(TemporalAdjusters.previous(DayOfWeek.SATURDAY));
// 上一个星期六,可以是当天 2019-02-09localDate.with(TemporalAdjusters.previousOrSame(DayOfWeek.SATURDAY));
自定义
可以利用Temporal.with方法与ChronoField枚举获取各种日期
// 下个月的最后一天 2019-03-31localDate.with(temporal -> {
Temporal nextMonths = temporal.plus(1, MONTHS);
return nextMonths.with(DAY_OF_MONTH, nextMonths.range(DAY_OF_MONTH).getMaximum());
});
指定日期时间
// 指定日期时间LocalDateTime localDateTime = LocalDateTime.of(2020, 3, 25, 21, 44, 32);
// 这一天的开始时间localDateTime.toLocalDate().atStartOfDay();
// 这一天的开始时间localDateTime.toLocalDate().atTime(LocalTime.MAX);
// 30小时后localDateTime.plusHours(30);
// 30分钟后localDateTime.plusMinutes(30);
转换
// Date InstantInstant instant = new Date().toInstant();
Date date = Date.from(Instant.now());
// Instant LocalDateTime,当前时区LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.now(), ZoneId.systemDefault());
Instant instant = LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant();
// Date LocalDateTimeLocalDateTime localDateTime = LocalDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault());
Date date = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());
// LocalDateTime LocalDateLocalDate localDate = LocalDateTime.now().toLocalDate();
LocalDateTime localDateTime = LocalDate.now().atStartOfDay();
// LocalDateTime LocalTimeLocalTime localTime = LocalDateTime.now().toLocalTime();
LocalDateTime localDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.now());Date与LocalDateTime之间的转换需要通过Instant
LocalDate无法直接转为LocalDateTime,这里将时间设为一天的开始时间
LocalTime无法直接转为LocalDateTime,这里将日期设为当天
格式化
先看看自带的DateTimeFormatter格式化:
// 指定日期时间ZonedDateTime zonedDateTime = ZonedDateTime.now();
// ISO_LOCAL_DATE 2020-03-25DateTimeFormatter.ISO_LOCAL_DATE.format(zonedDateTime);
// ISO_OFFSET_DATE 2020-03-25+08:00DateTimeFormatter.ISO_OFFSET_DATE.format(zonedDateTime);
// ISO_DATE 2020-03-25+08:00DateTimeFormatter.ISO_DATE.format(zonedDateTime);
// ISO_LOCAL_TIME 22:22:55.6747072DateTimeFormatter.ISO_LOCAL_TIME.format(zonedDateTime);
// ISO_OFFSET_TIME 22:22:55.6747072+08:00DateTimeFormatter.ISO_OFFSET_TIME.format(zonedDateTime);
// ISO_TIME 22:22:55.6747072+08:00DateTimeFormatter.ISO_TIME.format(zonedDateTime);
// ISO_LOCAL_DATE_TIME 2020-03-25T22:22:55.6747072DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(zonedDateTime);
// ISO_OFFSET_DATE_TIME 2020-03-25T22:22:55.6747072+08:00DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(zonedDateTime);
// ISO_ZONED_DATE_TIME 2020-03-25T22:22:55.6747072+08:00[Asia/Shanghai]DateTimeFormatter.ISO_ZONED_DATE_TIME.format(zonedDateTime);
// ISO_DATE_TIME 2020-03-25T22:22:55.6747072+08:00[Asia/Shanghai]DateTimeFormatter.ISO_DATE_TIME.format(zonedDateTime);
// ISO_ORDINAL_DATE 2020-085+08:00DateTimeFormatter.ISO_ORDINAL_DATE.format(zonedDateTime);
// ISO_WEEK_DATE 2020-W13-3+08:00DateTimeFormatter.ISO_WEEK_DATE.format(zonedDateTime);
// ISO_INSTANT 2020-03-25T14:22:55.674707200ZDateTimeFormatter.ISO_INSTANT.format(zonedDateTime);
// BASIC_ISO_DATE 20200325+0800DateTimeFormatter.BASIC_ISO_DATE.format(zonedDateTime);
// RFC_1123_DATE_TIME Wed, 25 Mar 2020 22:22:55 +0800DateTimeFormatter.RFC_1123_DATE_TIME.format(zonedDateTime);
自定义DateTimeFormatter,建议设置为常量:
// 指定日期时间ZonedDateTime zonedDateTime = ZonedDateTime.now();
// 2020-03-25 22:29:33DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(zonedDateTime);
// 2020-03-25 等同于DateTimeFormatter.ISO_LOCAL_DATEDateTimeFormatter.ofPattern("yyyy-MM-dd").format(zonedDateTime);
// 2020年03月25日 22时29分33秒DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH时mm分ss秒").format(zonedDateTime);
// 2020年03月25日DateTimeFormatter.ofPattern("yyyy年MM月dd日").format(zonedDateTime);
// 2020-03DateTimeFormatter.ofPattern("yyyy-MM").format(zonedDateTime);
// 2020年03月DateTimeFormatter.ofPattern("yyyy年MM月").format(zonedDateTime);
// 20200325DateTimeFormatter.ofPattern("yyyyMMdd").format(zonedDateTime);
// 202003DateTimeFormatter.ofPattern("yyyyMM").format(zonedDateTime);
解析
调用DateTimeFormatter解析:
// 2020-03-25LocalDate.parse("2020年03月25日", dateTimeFormatter);
// 2020-03-25LocalDate.from(dateTimeFormatter.parse("2020年03月25日"));
// 2020-03-25dateTimeFormatter.parse("2020年03月25日", LocalDate::from);注意:如果传入的日期文本不包含时间,则无法转为带有时间的类型,日期同理。
比较
LocalDateTime localDateTime1 = LocalDateTime.of(2020, 3, 25, 6, 44, 32);
LocalDateTime localDateTime2 = LocalDateTime.now();
// 是否为同一天 truelocalDateTime1.toLocalDate().equals(localDateTime2.toLocalDate());
// localDateTime1是否在localDateTime2之前 truelocalDateTime1.isBefore(localDateTime2);
// localDateTime1是否在localDateTime2之后 falselocalDateTime1.isAfter(localDateTime2);
间隔
Period
获取两个日期时间,表面上的间隔,比如2011年2月1日,和2021年8月11日,日相差了10天,月相差6月,而且只能比较LocalDate,当然这个类实际上表示是表面上年月日的偏移。
LocalDate localDate1 = LocalDate.of(2020, 1, 15);
LocalDate localDate2 = LocalDate.now();
Period period = Period.between(localDate1, localDate2);
// 10System.out.println(period.getDays());
// 2System.out.println(period.getMonths());
Duration
与Period相比,Duration能得到相差的实际天数、小时数等,但没有年、月。实际上,它是一个基于时间的量,表示一段连续的时间。
LocalDateTime localDateTime1 = LocalDateTime.of(2020, 1, 15, 8, 21, 12);
LocalDateTime localDateTime2 = LocalDateTime.now();
Duration between = Duration.between(localDateTime1, localDateTime2);
// 70System.out.println(between.toDays());
// 1694System.out.println(between.toHours());
ChronoUnit
与前两个相比,这个才是真正比较日期时间间隔的方式。
LocalDateTime localDateTime1 = LocalDateTime.of(2020, 1, 15, 8, 21, 12);
LocalDateTime localDateTime2 = LocalDateTime.now();
// 0localDateTime1.until(localDateTime2, ChronoUnit.YEARS);
// 2localDateTime1.until(localDateTime2, ChronoUnit.MONTHS);
// 70localDateTime1.until(localDateTime2, ChronoUnit.DAYS);
// 1694localDateTime1.until(localDateTime2, ChronoUnit.HOURS);
// 101678localDateTime1.until(localDateTime2, ChronoUnit.MINUTES);
// 6100682localDateTime1.until(localDateTime2, ChronoUnit.SECONDS);
// 或 ChronoUnit.YEARS.between(localDateTime1, localDateTime2)
获取一段连续的日期或时间
获取近十个月的连续年月YearMonth
// [2012-09, 2013-07, 2014-05, 2015-03, 2016-01, 2016-11, 2017-09, 2018-07, 2019-05, 2020-03]Stream.iterate(YearMonth.now(), yearMonth -> yearMonth.plusMonths(-10))
.limit(10)
.sorted(Comparator.comparing(YearMonth::getYear).thenComparing(YearMonth::getMonthValue))
.collect(Collectors.toList());