diff --git a/hutool-core/src/main/java/cn/hutool/core/date/LocalTimeUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/LocalTimeUtil.java
new file mode 100755
index 000000000..1da718811
--- /dev/null
+++ b/hutool-core/src/main/java/cn/hutool/core/date/LocalTimeUtil.java
@@ -0,0 +1,26 @@
+package cn.hutool.core.date;
+
+import java.time.LocalTime;
+
+/**
+ * 针对 {@link LocalTime} 封装的一些工具方法
+ *
+ * @author Looly
+ * @since 6.0.0
+ */
+public class LocalTimeUtil {
+
+ /**
+ * 获取最大时间,提供参数是否将毫秒归零
+ *
+ * - 如果{@code truncateMillisecond}为{@code false},返回时间最大值,为:23:59:59,999
+ * - 如果{@code truncateMillisecond}为{@code true},返回时间最大值,为:23:59:59,000
+ *
+ *
+ * @param truncateMillisecond 是否毫秒归零
+ * @return {@link LocalTime}时间最大值
+ */
+ public static LocalTime max(final boolean truncateMillisecond) {
+ return truncateMillisecond ? LocalTime.of(23, 59, 59) : LocalTime.MAX;
+ }
+}
diff --git a/hutool-core/src/main/java/cn/hutool/core/date/TimeUtil.java b/hutool-core/src/main/java/cn/hutool/core/date/TimeUtil.java
index c99ea1e15..1ce45a357 100644
--- a/hutool-core/src/main/java/cn/hutool/core/date/TimeUtil.java
+++ b/hutool-core/src/main/java/cn/hutool/core/date/TimeUtil.java
@@ -420,16 +420,6 @@ public class TimeUtil extends TemporalAccessorUtil {
return time.with(LocalTime.MIN);
}
- /**
- * 修改为一天的结束时间,例如:2020-02-02 23:59:59,999
- *
- * @param time 日期时间
- * @return 一天的结束时间
- */
- public static LocalDateTime endOfDay(final LocalDateTime time) {
- return endOfDay(time, false);
- }
-
/**
* 修改为一天的结束时间,例如:
*
@@ -443,20 +433,49 @@ public class TimeUtil extends TemporalAccessorUtil {
* @since 5.7.18
*/
public static LocalDateTime endOfDay(final LocalDateTime time, final boolean truncateMillisecond) {
- if (truncateMillisecond) {
- return time.with(LocalTime.of(23, 59, 59));
- }
- return time.with(LocalTime.MAX);
+ return time.with(LocalTimeUtil.max(truncateMillisecond));
+ }
+
+ /**
+ * 修改为本月的开始时间,例如:2020-02-01 00:00:00,000
+ *
+ * @param time 日期时间
+ * @return 一天的开始时间
+ */
+ public static LocalDateTime beginOfMonth(final LocalDateTime time) {
+ return beginOfDay(time).with(TemporalAdjusters.firstDayOfMonth());
}
/**
* 获取给定日期月底的时间
*
- * @param time 日期时间
+ * @param time 日期时间
+ * @param truncateMillisecond 是否毫秒归零
* @return 月底
*/
- public static LocalDateTime endOfMonth(final LocalDateTime time) {
- return time.with(TemporalAdjusters.lastDayOfMonth());
+ public static LocalDateTime endOfMonth(final LocalDateTime time, final boolean truncateMillisecond) {
+ return endOfDay(time, truncateMillisecond).with(TemporalAdjusters.lastDayOfMonth());
+ }
+
+ /**
+ * 修改为本年的开始时间,例如:2020-01-01 00:00:00,000
+ *
+ * @param time 日期时间
+ * @return 一年的开始时间
+ */
+ public static LocalDateTime beginOfYear(final LocalDateTime time) {
+ return beginOfDay(time).with(TemporalAdjusters.firstDayOfYear());
+ }
+
+ /**
+ * 获取给定日期年底的时间
+ *
+ * @param time 日期时间
+ * @param truncateMillisecond 是否毫秒归零
+ * @return 年底
+ */
+ public static LocalDateTime endOfYear(final LocalDateTime time, final boolean truncateMillisecond) {
+ return endOfDay(time, truncateMillisecond).with(TemporalAdjusters.lastDayOfYear());
}
/**
@@ -516,7 +535,7 @@ public class TimeUtil extends TemporalAccessorUtil {
// x>b||a>y 无交集
// 则有交集的逻辑为 !(x>b||a>y)
// 根据德摩根公式,可化简为 x<=b && a<=y 即 realStartTime<=endTime && startTime<=realEndTime
- return realStartTime.compareTo(endTime) <=0 && startTime.compareTo(realEndTime) <= 0;
+ return realStartTime.compareTo(endTime) <= 0 && startTime.compareTo(realEndTime) <= 0;
}
/**
diff --git a/hutool-core/src/test/java/cn/hutool/core/date/TimeUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/date/TimeUtilTest.java
index c03bd0c76..dcb304acc 100644
--- a/hutool-core/src/test/java/cn/hutool/core/date/TimeUtilTest.java
+++ b/hutool-core/src/test/java/cn/hutool/core/date/TimeUtilTest.java
@@ -150,13 +150,49 @@ public class TimeUtilTest {
public void endOfDayTest() {
final LocalDateTime localDateTime = TimeUtil.parseByISO("2020-01-23T12:23:56");
- LocalDateTime endOfDay = TimeUtil.endOfDay(localDateTime);
+ LocalDateTime endOfDay = TimeUtil.endOfDay(localDateTime, false);
Assert.assertEquals("2020-01-23T23:59:59.999999999", endOfDay.toString());
endOfDay = TimeUtil.endOfDay(localDateTime, true);
Assert.assertEquals("2020-01-23T23:59:59", endOfDay.toString());
}
+ @Test
+ public void beginOfMonthTest() {
+ final LocalDateTime localDateTime = TimeUtil.parseByISO("2020-01-23T12:23:56");
+ final LocalDateTime begin = TimeUtil.beginOfMonth(localDateTime);
+ Assert.assertEquals("2020-01-01T00:00", begin.toString());
+ }
+
+ @Test
+ public void endOfMonthTest() {
+ final LocalDateTime localDateTime = TimeUtil.parseByISO("2020-01-23T12:23:56");
+
+ LocalDateTime end = TimeUtil.endOfMonth(localDateTime, false);
+ Assert.assertEquals("2020-01-31T23:59:59.999999999", end.toString());
+
+ end = TimeUtil.endOfMonth(localDateTime, true);
+ Assert.assertEquals("2020-01-31T23:59:59", end.toString());
+ }
+
+ @Test
+ public void beginOfYearTest() {
+ final LocalDateTime localDateTime = TimeUtil.parseByISO("2020-01-23T12:23:56");
+ final LocalDateTime begin = TimeUtil.beginOfMonth(localDateTime);
+ Assert.assertEquals("2020-01-01T00:00", begin.toString());
+ }
+
+ @Test
+ public void endOfYearTest() {
+ final LocalDateTime localDateTime = TimeUtil.parseByISO("2020-01-23T12:23:56");
+
+ LocalDateTime end = TimeUtil.endOfYear(localDateTime, false);
+ Assert.assertEquals("2020-12-31T23:59:59.999999999", end.toString());
+
+ end = TimeUtil.endOfYear(localDateTime, true);
+ Assert.assertEquals("2020-12-31T23:59:59", end.toString());
+ }
+
@Test
public void dayOfWeekTest() {
final Week one = TimeUtil.dayOfWeek(LocalDate.of(2021, 9, 20));