|
|
@@ -0,0 +1,241 @@
|
|
|
+package cn.iocoder.yudao.module.iscs.utils;
|
|
|
+
|
|
|
+import java.time.DayOfWeek;
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.YearMonth;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+public class SuperDateUtils {
|
|
|
+
|
|
|
+
|
|
|
+ // ------------------------------------- 获取指定时间段内的所有日期 ---------------------------------------------------
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取指定时间段内的所有日期
|
|
|
+ *
|
|
|
+ * @param startStr 起始日期,格式为yyyy-MM-dd
|
|
|
+ * @param endStr 结束日期,格式为yyyy-MM-dd
|
|
|
+ * @return 包含所有日期的列表(含起止日期)
|
|
|
+ */
|
|
|
+ public static List<String> getAllDatesBetween(String startStr, String endStr) {
|
|
|
+ // 定义日期格式
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
+
|
|
|
+ // 解析输入字符串为LocalDate对象
|
|
|
+ LocalDate startDate = LocalDate.parse(startStr, formatter);
|
|
|
+ LocalDate endDate = LocalDate.parse(endStr, formatter);
|
|
|
+
|
|
|
+ // 确保startDate <= endDate(自动纠正顺序)
|
|
|
+ if (startDate.isAfter(endDate)) {
|
|
|
+ LocalDate temp = startDate;
|
|
|
+ startDate = endDate;
|
|
|
+ endDate = temp;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 生成日期列表
|
|
|
+ List<String> result = new ArrayList<>();
|
|
|
+ LocalDate current = startDate;
|
|
|
+ while (!current.isAfter(endDate)) { // 包含边界值
|
|
|
+ result.add(current.format(formatter));
|
|
|
+ current = current.plusDays(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试示例
|
|
|
+ /*public static void main(String[] args) {
|
|
|
+ List<String> dates = getAllDatesBetween("2025-07-23", "2025-08-02");
|
|
|
+ System.out.println(dates);
|
|
|
+ // 输出: [2025-07-23, 2025-07-24, 2025-07-25]
|
|
|
+
|
|
|
+ // 测试逆序输入
|
|
|
+ dates = getAllDatesBetween("2025-07-25", "2025-07-23");
|
|
|
+ System.out.println(dates);
|
|
|
+ // 输出: [2025-07-23, 2025-07-24, 2025-07-25]
|
|
|
+ }*/
|
|
|
+
|
|
|
+ // ---------------------------------- 获取指定时间段内的所有周几的日期 -----------------------------------------------------
|
|
|
+ private static final Map<String, DayOfWeek> WEEKDAY_MAP = new HashMap<>();
|
|
|
+
|
|
|
+ static {
|
|
|
+ WEEKDAY_MAP.put("周一", DayOfWeek.MONDAY);
|
|
|
+ WEEKDAY_MAP.put("周二", DayOfWeek.TUESDAY);
|
|
|
+ WEEKDAY_MAP.put("周三", DayOfWeek.WEDNESDAY);
|
|
|
+ WEEKDAY_MAP.put("周四", DayOfWeek.THURSDAY);
|
|
|
+ WEEKDAY_MAP.put("周五", DayOfWeek.FRIDAY);
|
|
|
+ WEEKDAY_MAP.put("周六", DayOfWeek.SATURDAY);
|
|
|
+ WEEKDAY_MAP.put("周日", DayOfWeek.SUNDAY);
|
|
|
+ // 兼容全称写法
|
|
|
+ WEEKDAY_MAP.put("星期一", DayOfWeek.MONDAY);
|
|
|
+ WEEKDAY_MAP.put("星期二", DayOfWeek.TUESDAY);
|
|
|
+ WEEKDAY_MAP.put("星期三", DayOfWeek.WEDNESDAY);
|
|
|
+ WEEKDAY_MAP.put("星期四", DayOfWeek.THURSDAY);
|
|
|
+ WEEKDAY_MAP.put("星期五", DayOfWeek.FRIDAY);
|
|
|
+ WEEKDAY_MAP.put("星期六", DayOfWeek.SATURDAY);
|
|
|
+ WEEKDAY_MAP.put("星期日", DayOfWeek.SUNDAY);
|
|
|
+ WEEKDAY_MAP.put("星期天", DayOfWeek.SUNDAY); // 部分地区使用
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取指定时间段内所有匹配给定星期的日期
|
|
|
+ *
|
|
|
+ * @param startDateStr 开始日期,格式为yyyy-MM-dd
|
|
|
+ * @param endDateStr 结束日期,格式为yyyy-MM-dd
|
|
|
+ * @param weekday 星期几(如"周三"、"星期三")
|
|
|
+ * @return 匹配的日期列表
|
|
|
+ */
|
|
|
+ public static List<String> getDatesByWeekday(String startDateStr, String endDateStr, String weekday) {
|
|
|
+ // 校验星期参数
|
|
|
+ DayOfWeek targetDay = WEEKDAY_MAP.get(weekday);
|
|
|
+ if (targetDay == null) {
|
|
|
+ throw new IllegalArgumentException("无效的星期参数: " + weekday);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析日期
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
+ LocalDate startDate = LocalDate.parse(startDateStr, formatter);
|
|
|
+ LocalDate endDate = LocalDate.parse(endDateStr, formatter);
|
|
|
+
|
|
|
+ // 自动校正日期顺序
|
|
|
+ if (startDate.isAfter(endDate)) {
|
|
|
+ LocalDate temp = startDate;
|
|
|
+ startDate = endDate;
|
|
|
+ endDate = temp;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 遍历日期并收集结果
|
|
|
+ List<String> result = new ArrayList<>();
|
|
|
+ LocalDate current = startDate;
|
|
|
+ while (!current.isAfter(endDate)) {
|
|
|
+ if (current.getDayOfWeek() == targetDay) {
|
|
|
+ result.add(current.format(formatter));
|
|
|
+ }
|
|
|
+ current = current.plusDays(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 示例用法
|
|
|
+ /*public static void main(String[] args) {
|
|
|
+ List<String> dates = getDatesByWeekday("2025-07-23", "2025-08-25", "周三");
|
|
|
+ System.out.println(dates); // 输出: [2025-07-23]
|
|
|
+ }*/
|
|
|
+
|
|
|
+ // ---------------------------------- 获取指定时间段内的所有指定号日期 -----------------------------------------------------
|
|
|
+ /**
|
|
|
+ * 根据时间段和指定日期中的“日”部分,获取所有匹配的日期。
|
|
|
+ *
|
|
|
+ * @param startStr 开始日期字符串,格式为yyyy-MM-dd
|
|
|
+ * @param endStr 结束日期字符串,格式为yyyy-MM-dd
|
|
|
+ * @param targetDay 目标日期的“日”部分(如24)
|
|
|
+ * @return 符合条件的日期列表
|
|
|
+ */
|
|
|
+ public static List<String> getDatesWithDayInRange(String startStr, String endStr, int targetDay) {
|
|
|
+ // 解析输入的日期字符串
|
|
|
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
|
|
|
+ LocalDate startDate = LocalDate.parse(startStr);
|
|
|
+ LocalDate endDate = LocalDate.parse(endStr);
|
|
|
+
|
|
|
+ // 确保startDate不晚于endDate
|
|
|
+ if (startDate.isAfter(endDate)) {
|
|
|
+ LocalDate temp = startDate;
|
|
|
+ startDate = endDate;
|
|
|
+ endDate = temp;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> result = new ArrayList<>();
|
|
|
+ // 获取开始和结束的YearMonth
|
|
|
+ YearMonth startYearMonth = YearMonth.from(startDate);
|
|
|
+ YearMonth endYearMonth = YearMonth.from(endDate);
|
|
|
+
|
|
|
+ YearMonth currentYearMonth = startYearMonth;
|
|
|
+ // 遍历每个月
|
|
|
+ while (!currentYearMonth.isAfter(endYearMonth)) {
|
|
|
+ int daysInMonth = currentYearMonth.lengthOfMonth(); // 获取当前月的总天数
|
|
|
+ if (targetDay <= daysInMonth) {
|
|
|
+ LocalDate targetDate = currentYearMonth.atDay(targetDay);
|
|
|
+ // 检查目标日期是否在范围内
|
|
|
+ if (!targetDate.isBefore(startDate) && !targetDate.isAfter(endDate)) {
|
|
|
+ result.add(targetDate.format(formatter));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 进入下一个月
|
|
|
+ currentYearMonth = currentYearMonth.plusMonths(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试示例
|
|
|
+ /*public static void main(String[] args) {
|
|
|
+ List<LocalDate> dates = getDatesWithDayInRange("2025-01-23", "2025-12-31", 29);
|
|
|
+ dates.forEach(System.out::println); // 输出:2025-06-24 和 2025-07-24
|
|
|
+ }*/
|
|
|
+
|
|
|
+// ---------------------------------- 获取指定时间段内的所有指定第多少天,如果超过则输出最后一天 -----------------------------------------------------
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取指定时间段内每月的第指定天数的日期。
|
|
|
+ * @param startStr 起始日期字符串,格式为yyyy-MM-dd
|
|
|
+ * @param endStr 结束日期字符串,格式为yyyy-MM-dd
|
|
|
+ * @param dayOfMonth 每月的第几天(如1表示每月1日)
|
|
|
+ * @return 符合条件的日期列表
|
|
|
+ */
|
|
|
+ public static List<LocalDate> getDatesByDayOfMonth(String startStr, String endStr, int dayOfMonth) {
|
|
|
+ // 解析输入日期
|
|
|
+ LocalDate startDate = LocalDate.parse(startStr);
|
|
|
+ LocalDate endDate = LocalDate.parse(endStr);
|
|
|
+
|
|
|
+ // 如果起始日期晚于结束日期,交换顺序
|
|
|
+ if (startDate.isAfter(endDate)) {
|
|
|
+ LocalDate temp = startDate;
|
|
|
+ startDate = endDate;
|
|
|
+ endDate = temp;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<LocalDate> result = new ArrayList<>();
|
|
|
+ YearMonth startMonth = YearMonth.from(startDate);
|
|
|
+ YearMonth endMonth = YearMonth.from(endDate);
|
|
|
+
|
|
|
+ // 遍历从起始月份到结束月份的所有月份
|
|
|
+ for (YearMonth ym = startMonth; !ym.isAfter(endMonth); ym = ym.plusMonths(1)) {
|
|
|
+ int maxDay = ym.lengthOfMonth(); // 获取当月最大天数
|
|
|
+ int targetDay = Math.min(dayOfMonth, maxDay); // 防止超过最大天数
|
|
|
+ LocalDate targetDate = ym.atDay(targetDay);
|
|
|
+
|
|
|
+ // 检查目标日期是否在时间范围内
|
|
|
+ if ((!targetDate.isBefore(startDate)) && (!targetDate.isAfter(endDate))) {
|
|
|
+ result.add(targetDate);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 测试示例
|
|
|
+ /*public static void main(String[] args) {
|
|
|
+ // 示例1:输入2025-08-23到2025-10-25,每月第1天
|
|
|
+ List<LocalDate> dates1 = getDatesByDayOfMonth("2025-08-23", "2025-10-25", 23);
|
|
|
+ // dates1.forEach(System.out::println); // 输出:2025-09-01 和 2025-10-01
|
|
|
+
|
|
|
+ // 示例2:输入2025-09-01到2025-10-31,每月第31天
|
|
|
+ List<LocalDate> dates2 = getDatesByDayOfMonth("2025-01-01", "2025-12-31", 31);
|
|
|
+ dates2.forEach(System.out::println); // 输出:2025-09-30 和 2025-10-31
|
|
|
+
|
|
|
+ // 其他测试用例
|
|
|
+ // 跨年测试:2024-12-15到2025-02-10,每月第5天
|
|
|
+ List<LocalDate> dates3 = getDatesByDayOfMonth("2024-12-15", "2025-02-10", 5);
|
|
|
+ // dates3.forEach(System.out::println); // 输出:2025-01-05
|
|
|
+
|
|
|
+ // 单月测试:2025-03-01到2025-03-31,每月第31天
|
|
|
+ List<LocalDate> dates4 = getDatesByDayOfMonth("2025-03-01", "2025-03-31", 31);
|
|
|
+ // dates4.forEach(System.out::println); // 输出:2025-03-31
|
|
|
+ }*/
|
|
|
+
|
|
|
+}
|