|
|
@@ -0,0 +1,195 @@
|
|
|
+package org.dromara.business.utils;
|
|
|
+
|
|
|
+
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.LocalDateTime;
|
|
|
+import java.time.ZoneId;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.time.format.DateTimeParseException;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 获取开始时间和结束时间 工具类
|
|
|
+ */
|
|
|
+public class DateTimeRangeUtils {
|
|
|
+
|
|
|
+ private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取指定类型的开始时间(LocalDateTime)
|
|
|
+ *
|
|
|
+ * @param type 支持: "day", "three", "week", "month"
|
|
|
+ * @return 开始时间
|
|
|
+ */
|
|
|
+ public static LocalDateTime getStartLocalDateTime(String type) {
|
|
|
+ LocalDate today = LocalDate.now();
|
|
|
+ LocalDateTime start;
|
|
|
+
|
|
|
+ switch (type.toLowerCase()) {
|
|
|
+ case "day":
|
|
|
+ start = today.atStartOfDay(); // 今天 00:00:00
|
|
|
+ break;
|
|
|
+
|
|
|
+ case "three":
|
|
|
+ start = today.minusDays(3).atStartOfDay(); // 3天前 00:00:00
|
|
|
+ break;
|
|
|
+
|
|
|
+ case "week":
|
|
|
+ start = today.minusDays(7).atStartOfDay(); // 7天前 00:00:00
|
|
|
+ break;
|
|
|
+
|
|
|
+ case "month":
|
|
|
+ start = today.withDayOfMonth(1).atStartOfDay(); // 本月第一天 00:00:00
|
|
|
+ break;
|
|
|
+
|
|
|
+ default:
|
|
|
+ throw new IllegalArgumentException("不支持的时间类型: " + type);
|
|
|
+ }
|
|
|
+
|
|
|
+ return start;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取指定类型的结束时间(LocalDateTime)
|
|
|
+ *
|
|
|
+ * @param type 支持: "day", "three", "week", "month"
|
|
|
+ * @return 结束时间
|
|
|
+ */
|
|
|
+ /**
|
|
|
+ * 获取指定类型的结束时间(不包含)—— 用于 < 查询
|
|
|
+ */
|
|
|
+ public static LocalDateTime getEndLocalDateTime(String type) {
|
|
|
+ LocalDate today = LocalDate.now();
|
|
|
+
|
|
|
+ return switch (type.toLowerCase()) {
|
|
|
+ case "day" -> today.plusDays(1).atStartOfDay(); // 明天 00:00:00
|
|
|
+ case "three", "week", "month" -> today.atStartOfDay(); // 今天 00:00:00
|
|
|
+ default -> throw new IllegalArgumentException("不支持的时间类型: " + type);
|
|
|
+ };
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 获取开始时间字符串(格式:yyyy-MM-dd HH:mm:ss)
|
|
|
+ */
|
|
|
+ public static String getStartString(String type) {
|
|
|
+ return getStartLocalDateTime(type).format(FORMATTER);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取结束时间字符串(格式:yyyy-MM-dd HH:mm:ss)
|
|
|
+ */
|
|
|
+ public static String getEndString(String type) {
|
|
|
+ return getEndLocalDateTime(type).format(FORMATTER);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * (可选)转换为 java.util.Date(如果你还在用老日期)
|
|
|
+ */
|
|
|
+ public static java.util.Date getStartDate(String type) {
|
|
|
+ return java.util.Date.from(getStartLocalDateTime(type).atZone(ZoneId.systemDefault()).toInstant());
|
|
|
+ }
|
|
|
+
|
|
|
+ public static java.util.Date getEndDate(String type) {
|
|
|
+ return java.util.Date.from(getEndLocalDateTime(type).atZone(ZoneId.systemDefault()).toInstant());
|
|
|
+ }
|
|
|
+
|
|
|
+ // ================== 测试用例 ==================
|
|
|
+ public static void main(String[] args) {
|
|
|
+ System.out.println("今天是: " + LocalDate.now());
|
|
|
+
|
|
|
+ String[] types = {"day", "three", "week", "month"};
|
|
|
+ for (String type : types) {
|
|
|
+ System.out.println("\n--- " + type.toUpperCase() + " ---");
|
|
|
+ System.out.println("开始: " + getStartString(type));
|
|
|
+ System.out.println("结束: " + getEndString(type));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ // 默认输入时间格式(支持时分秒)
|
|
|
+ private static final DateTimeFormatter INPUT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
+
|
|
|
+ // 默认输出日期格式
|
|
|
+ private static final DateTimeFormatter OUTPUT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算两个字符串表示的时间之间的所有日期(返回 yyyy-MM-dd 格式的字符串列表)
|
|
|
+ *
|
|
|
+ * @param startStr 开始时间字符串,格式:yyyy-MM-dd HH:mm:ss
|
|
|
+ * @param endStr 结束时间字符串,格式:yyyy-MM-dd HH:mm:ss
|
|
|
+ * @param includeEnd 是否包含结束日
|
|
|
+ * @return List<String> 如 ["2025-04-05", "2024-04-06", ...]
|
|
|
+ * @throws IllegalArgumentException 如果时间格式错误或参数为空
|
|
|
+ */
|
|
|
+ public static List<String> getDatesBetween(String startStr, String endStr, boolean includeEnd) {
|
|
|
+ return getDatesBetween(startStr, endStr, includeEnd, OUTPUT_FORMATTER);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 计算两个字符串时间之间的日期范围,并指定输出格式
|
|
|
+ *
|
|
|
+ * @param startStr 开始时间字符串
|
|
|
+ * @param endStr 结束时间字符串
|
|
|
+ * @param includeEnd 是否包含结束日
|
|
|
+ * @param outputFormatter 输出日期格式化器(如 DateTimeFormatter.ofPattern("MM/dd"))
|
|
|
+ * @return List<String>
|
|
|
+ */
|
|
|
+ public static List<String> getDatesBetween(
|
|
|
+ String startStr,
|
|
|
+ String endStr,
|
|
|
+ boolean includeEnd,
|
|
|
+ DateTimeFormatter outputFormatter) {
|
|
|
+
|
|
|
+ // 校验输入
|
|
|
+ if (startStr == null || endStr == null || startStr.trim().isEmpty() || endStr.trim().isEmpty()) {
|
|
|
+ throw new IllegalArgumentException("开始时间和结束时间不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ LocalDateTime start;
|
|
|
+ LocalDateTime end;
|
|
|
+
|
|
|
+ try {
|
|
|
+ start = LocalDateTime.parse(startStr.trim(), INPUT_FORMATTER);
|
|
|
+ } catch (DateTimeParseException e) {
|
|
|
+ throw new IllegalArgumentException("开始时间格式错误,正确格式: yyyy-MM-dd HH:mm:ss", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ end = LocalDateTime.parse(endStr.trim(), INPUT_FORMATTER);
|
|
|
+ } catch (DateTimeParseException e) {
|
|
|
+ throw new IllegalArgumentException("结束时间格式错误,正确格式: yyyy-MM-dd HH:mm:ss", e);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (outputFormatter == null) {
|
|
|
+ throw new IllegalArgumentException("输出格式化器不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取日期部分
|
|
|
+ LocalDate startDate = start.toLocalDate();
|
|
|
+ LocalDate endDate = end.toLocalDate();
|
|
|
+
|
|
|
+ // 确定结束边界
|
|
|
+ LocalDate endInclusive = includeEnd ? endDate : endDate.minusDays(1);
|
|
|
+
|
|
|
+ // 如果开始日期 > 结束边界,返回空
|
|
|
+ if (startDate.isAfter(endInclusive)) {
|
|
|
+ return new ArrayList<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成日期字符串列表
|
|
|
+ List<String> result = new ArrayList<>();
|
|
|
+ LocalDate current = startDate;
|
|
|
+
|
|
|
+ while (!current.isAfter(endInclusive)) {
|
|
|
+ result.add(current.format(outputFormatter));
|
|
|
+ current = current.plusDays(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|