记录日常开发中的常用的日期转换代码,算是一篇Java 8时间API使用实操的简短总结文。
使用TemporalAdjusters工具类。
TemporalAdjusters.firstDayOfYear()
:将月份和日期调整至1月1日TemporalAdjusters.lastDayOfYear()
:将月份和日期调整至12月31日TemporalAdjusters.firstDayOfMonth()
:将月份调整至当月的第一天(1)TemporalAdjusters.lastDayOfMonth()
:将月份调整至当月的最后一天(28-31)TemporalAdjusters.firstDayOfNextMonth()
:将月份和日期调整为下个月的第一天TemporalAdjusters.firstDayOfNextYear()
:将年份和日期调整为下一年的第一天
LocalDate.now().with(TemporalAdjusters.firstDayOfYear()) // 2023-01-01
OffsetDateTime.now().with(TemporalAdjusters.firstDayOfYear()); // 2023-01-01T11:55:26.268+08:00
ZonedDateTime.now().with(TemporalAdjusters.lastDayOfYear()); // 2023-12-31T11:55:26.267+08:00[Asia/Shanghai]
或者通过TemporalAdjuster的实现类,比如使用MonthDay
来调整
LocalDate with = LocalDate.now().with(MonthDay.of(1, 1)); // 2023-01-01
LocalDateTime.now().with(MonthDay.of(12, 31)); // 2023-12-31T11:56:06.902
// 等价于
LocalDateTime adjustInto = (LocalDateTime) MonthDay.of(12, 31).adjustInto(LocalDateTime.now()); // 2023-12-31T11:56:06.914
同使用TemporalAdjusters
OffsetDateTime.now().with(TemporalAdjusters.firstDayOfMonth()); // 2023-09-01T11:57:27.108+08:00
ZonedDateTime.now().with(TemporalAdjusters.lastDayOfMonth()); // 2023-09-30T11:57:27.118+08:00[Asia/Shanghai]
LocalDateTime.now().with(TemporalAdjusters.lastDayOfMonth()); // 2023-09-30T11:57:27.119
LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()); // 2023-09-30
因为月末是一个浮动值(28-31),需要根据是否是闰年,是年份的第几个月来最终确认月末值,手工实现比较麻烦。不过Java8中有很多类可以帮我们实现这一功能。
比如使用YearMonth
自带的月初计算,YearMonth
支持从所有带有年月的TemporalAccessor
类转换,LocalDateTime、ZonedDateTime、OffsetDateTime等类都能通过YearMonth.from
方法转换为YearMonth。
YearMonth yearMonth = YearMonth.from(LocalDate.parse("2023-02-02"));
LocalDate startOfMonth = yearMonth.atDay(1); // 2023-02-01
LocalDate endOfMonth = yearMonth.atEndOfMonth(); // 2023-02-28
boolean leapYear = yearMonth.isLeapYear(); // false
要在原时间上修改月初月末的话,需要再转换一次时间:
LocalDateTime now = LocalDateTime.now(); // 2023-09-22T13:40:41.960
LocalDateTime endOfMonth = now.with(YearMonth.from(now).atEndOfMonth()); // 2023-09-30T13:40:41.960
日初日末也没那么花俏了,值都是固定不变的,日初就是00:00:00.000,日末就是23:59:59.999。
能将时间转为这个值的方法有如下几个
LocalDate.atStartOfDay()
方法,不过只有转换日初,没有转换日末的LocalDateTime startOfDay = LocalDateTime.now().toLocalDate().atStartOfDay();
LocalDateTime startOfDay1 = LocalDate.now().atStartOfDay();
LocalDate.atTime()
设置具体时间,LocalDateTime、ZonedDateTime、OffsetDateTime、LocalDate等类都支持该操作。LocalDateTime min = LocalDate.now().atTime(LocalTime.MIN); // 2023-09-22T00:00 | min = 00:00
LocalDateTime max = LocalDate.now().atTime(LocalTime.MAX); // 2023-09-22T23:59:59.999999999 | max = 23:59:59.999999999
// 当然也可以这样
LocalDateTime with = LocalDateTime.now().with(LocalTime.MIN);
// 这样
LocalDateTime atDate = LocalTime.MAX.atDate(LocalDate.now());
// 甚至可以直接设置时间,不过不推荐这样,不够优雅
LocalDateTime.now().with(LocalTime.of(0, 0, 0));
LocalDateTime.now().with(LocalTime.of(23, 59, 59));
写完这一篇,jdk8的文章近期应该不会再写了。接下来就要在实际开发中用到jdk11了,更新版本开搞!