package org.sxkj.common.utils; import org.apache.commons.lang.StringUtils; import org.sxkj.common.enums.DateEnum; import java.time.*; import java.time.format.DateTimeFormatter; import java.time.temporal.TemporalAdjusters; import java.util.*; import java.util.function.Consumer; public class XAxisDataInitializer { /** * 根据时间范围枚举初始化X轴数据(截止当前时间点) * * @param timeRange 时间范围枚举 * @return X轴标签列表 */ public static List initXAxisDataToNow(DateEnum timeRange) { if (Objects.isNull(timeRange)) { return Collections.emptyList(); } switch (timeRange) { case TODAY: return initTodayXAxisToNow(null); case CURRENT_WEEK: return initCurrentWeekXAxisToNow(); case CURRENT_MONTH: return initCurrentMonthXAxisToNow(null); case CURRENT_YEAR: return initCurrentYearXAxisToNow(timeRange.getEndDate()); case INTERVAL_TIME: return initIntervalTime(timeRange); case YEARS: return initYears(timeRange); case MONTHS: return initMonths(timeRange); case DAYS: return initDays(timeRange); default: throw new IllegalArgumentException("未知的时间范围类型"); } } /** * 根据枚举与日期获取时间 * * @param timeRange 枚举 * @param startDate 开始时间 * @return 时间段 */ public static List initXAxisDataByStartTime(DateEnum timeRange, LocalDateTime startDate) { if (Objects.isNull(timeRange)) { return Collections.emptyList(); } switch (timeRange) { case DAY: return initTodayXAxisToNow(startDate); case MONTH: return initCurrentMonthXAxisToNow(startDate); case YEAR: return initCurrentYearXAxisToNow(startDate); default: throw new IllegalArgumentException("未知的时间范围类型"); } } /** * 根据枚举与日期获取时间 * * @param timeRange 枚举 * @param startDate 开始时间 * @return 时间段 */ public static List initXAxisDataByStartTimeTwo(DateEnum timeRange, LocalDateTime startDate, LocalDateTime endDate) { if (Objects.isNull(timeRange)) { return Collections.emptyList(); } switch (timeRange) { case DAY: return initTodayXAxisToNow(startDate, endDate); case MONTH: return initCurrentMonthXAxisToNow(startDate, endDate); case YEAR: return initCurrentYearXAxisToNow(startDate, endDate); default: throw new IllegalArgumentException("未知的时间范围类型"); } } /** * 间隔时间内数据 * * @param timeRange * @return */ private static List initIntervalTime(DateEnum timeRange) { LocalDateTime startDate = timeRange.getStartDate(); LocalDateTime endDate = timeRange.getEndDate(); List monthDaysBetween = getMonthDaysBetween(startDate, endDate); List days = new ArrayList<>(); for (int i = 0; i < monthDaysBetween.size(); i++) { MonthDay monthDay = monthDaysBetween.get(i); days.add(String.format("%02d", monthDay.getMonth().getValue()) + "-" + String.format("%02d", monthDay.getDayOfMonth())); } return days; } /** * 年份数据 * * @param timeRange * @return */ private static List initYears(DateEnum timeRange) { LocalDateTime startDate = timeRange.getStartDate(); LocalDateTime endDate = timeRange.getEndDate(); List years = new ArrayList<>(); // 确保开始日期不晚于结束日期 if (startDate.isAfter(endDate)) { return years; } int startYear = startDate.getYear(); int endYear = endDate.getYear(); // 如果同一年,直接返回该年份 if (startYear == endYear) { years.add(startYear + ""); } else { // 跨年份的情况,添加从开始年份到结束年份之间的所有年份 for (int year = startYear; year <= endYear; year++) { years.add(year + ""); } } return years; } /** * 获取指定时间范围内的所有月份(支持跨年) * * @param timeRange 时间范围枚举 * @return 月份字符串列表,格式为 "yyyy-MM" */ public static List initMonths(DateEnum timeRange) { LocalDateTime startDate = timeRange.getStartDate(); LocalDateTime endDate = timeRange.getEndDate(); List months = new ArrayList<>(); if (startDate == null || endDate == null || startDate.isAfter(endDate)) { // 空或非法时间范围返回空列表 return months; } DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM"); // 对齐到月初 LocalDateTime current = startDate.withDayOfMonth(1).withHour(0).withSecond(0).withMinute(0); LocalDateTime endMonthStart = endDate.withDayOfMonth(1).withHour(0).withSecond(0).withMinute(0); while (!current.isAfter(endMonthStart)) { months.add(current.format(formatter)); current = current.plusMonths(1); } return months; } /** * 获取指定时间范围内的所有天(支持跨月) * * @param timeRange 时间范围枚举 * @return 月份字符串列表,格式为 "mm-dd" */ public static List initDays(DateEnum timeRange) { LocalDateTime startDate = timeRange.getStartDate(); LocalDateTime endDate = timeRange.getEndDate(); List days = new ArrayList<>(); if (startDate == null || endDate == null || startDate.isAfter(endDate)) { // 空或非法时间范围返回空列表 return days; } DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM-dd"); // 设置为当天的最小时间 LocalDateTime current = startDate.with(LocalTime.MIN); while (!current.isAfter(endDate)) { days.add(current.format(formatter)); current = current.plusDays(1); } return days; } public static List getMonthDaysBetween(LocalDateTime startDate, LocalDateTime endDate) { List monthDays = new ArrayList<>(); // 确保开始日期不晚于结束日期 if (startDate.isAfter(endDate)) { return monthDays; } // 获取开始和结束的MonthDay MonthDay start = MonthDay.from(startDate); MonthDay end = MonthDay.from(endDate); // 如果同一年,直接比较 if (startDate.getYear() == endDate.getYear()) { LocalDateTime current = startDate; while (!current.isAfter(endDate)) { monthDays.add(MonthDay.from(current)); current = current.plusDays(1); } } else { // 跨年份的情况 // 添加从开始日期到年底的所有月日 LocalDateTime current = startDate; while (current.getYear() == startDate.getYear()) { monthDays.add(MonthDay.from(current)); current = current.plusDays(1); } // 添加中间完整年份的所有可能月日(2月29日需要特殊处理) // 这里可以根据需求决定是否包含2月29日 // 添加从年初到结束日期的所有月日 current = endDate.withDayOfYear(1); while (!current.isAfter(endDate)) { MonthDay md = MonthDay.from(current); if (!monthDays.contains(md)) { monthDays.add(md); } current = current.plusDays(1); } } return monthDays; } // 初始化今日X轴数据 (0时-当前小时) private static List initTodayXAxisToNow(LocalDateTime startDate) { LocalDateTime now = Optional.ofNullable(startDate).orElse(LocalDateTime.now()); // 设置当天的结束时间为23:59:59 int currentHour = now.with(LocalTime.MAX).getHour(); List hours = new ArrayList<>(); for (int i = 0; i <= currentHour; i++) { hours.add(String.format("%02d", i) + ""); } return hours; } // 初始化本周X轴数据 (周一到当前星期几 是多少号到多少号) private static List initCurrentWeekXAxisToNow() { LocalDate today = LocalDate.now(); LocalDate startOfWeek = today.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)); LocalDate endOfWeek = today; List days = new ArrayList<>(); LocalDate currentDay = startOfWeek; while (!currentDay.isAfter(endOfWeek)) { days.add(String.format("%02d", currentDay.getDayOfMonth()) + ""); currentDay = currentDay.plusDays(1); } return days; } // 初始化当月X轴数据 (1日-当前日期) private static List initCurrentMonthXAxisToNow(LocalDateTime startDate) { LocalDateTime endDay = Objects.nonNull(startDate) ? startDate.with(TemporalAdjusters.lastDayOfMonth()) : LocalDateTime.now(); int currentDayOfMonth = endDay.getDayOfMonth(); int currentMonth = endDay.getMonthValue(); List days = new ArrayList<>(); for (int i = 1; i <= currentDayOfMonth; i++) { days.add(String.format("%02d", currentMonth) + "-" + String.format("%02d", i)); } return days; } // 初始化本年X轴数据 (1月-当前月份) private static List initCurrentYearXAxisToNow(LocalDateTime startDate) { LocalDateTime endDay = getProcessedDateTime(startDate); int currentMonth = endDay.getMonthValue(); List months = new ArrayList<>(); for (int i = 1; i <= currentMonth; i++) { months.add(String.format("%02d", i) + ""); } return months; } // 初始化今日X轴数据 private static List initTodayXAxisToNow(LocalDateTime startDate, LocalDateTime endDate) { if (startDate == null || endDate == null || startDate.isAfter(endDate)) { return Collections.emptyList(); } // 判断是否跨年 boolean isCrossYear = startDate.getYear() != endDate.getYear(); DateTimeFormatter dayFormatter = DateTimeFormatter.ofPattern("dd"); DateTimeFormatter monthDayFormatter = DateTimeFormatter.ofPattern("MM-dd"); DateTimeFormatter fullFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); List xAxisData = new ArrayList<>(); LocalDateTime current = startDate.with(LocalTime.MIN); // 判断开始时间和结束时间是否同一个月 boolean isSameMonth = startDate.getMonth() != endDate.getMonth(); while (!current.isAfter(endDate)) { if (isCrossYear) { xAxisData.add(current.format(fullFormatter)); } else if (isSameMonth) { xAxisData.add(current.format(monthDayFormatter)); } else { xAxisData.add(current.format(dayFormatter)); } current = current.plusDays(1); } return xAxisData; } // 初始化当月X轴数据 (1日-当前日期) private static List initCurrentMonthXAxisToNow(LocalDateTime startDate, LocalDateTime endDate) { List result = new ArrayList<>(); boolean isCrossYear = startDate.getYear() != endDate.getYear(); DateTimeFormatter formatter = isCrossYear ? DateTimeFormatter.ofPattern("yyyy-MM") : DateTimeFormatter.ofPattern("MM"); LocalDateTime current = startDate.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0); LocalDateTime endMonthStart = endDate.withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0); while (!current.isAfter(endMonthStart)) { result.add(current.format(formatter)); current = current.plusMonths(1); } return result; } // 初始化本年X轴数据 (1月-当前月份) private static List initCurrentYearXAxisToNow(LocalDateTime startDate, LocalDateTime endDate) { List result = new ArrayList<>(); // 获取当前年份 int currentYear = LocalDateTime.now().getYear(); // 处理起始时间:若为空或小于2023,则从2023年开始 int startYear = 2023; if (startDate != null && startDate.getYear() >= 2023) { startYear = startDate.getYear(); } // 处理结束时间:若为空或大于当前年,则取当前年 int endYear = currentYear; if (startDate != null && startDate.getYear() < currentYear) { endYear = endDate.getYear(); } // 填充年份列表 for (int year = startYear; year <= endYear; year++) { result.add(String.valueOf(year)); } return result; } public static LocalDateTime getProcessedDateTime(LocalDateTime input) { LocalDateTime now = LocalDateTime.now(); int currentYear = now.getYear(); // 如果输入为空,返回今年到当前月份 if (input == null) { return now; } int inputYear = input.getYear(); // 如果输入年份是今年,返回当前时间 // if (inputYear == currentYear) { // return now; // } // // 如果输入年份不是今年,返回该年最后一天最后一刻 // else { return LocalDateTime.of(inputYear, Month.DECEMBER, 31, 23, 59, 59); // } } // public static void main(String[] args) { // // 测试用例 // System.out.println("输入2024年: " + getProcessedDateTime(LocalDateTime.of(2024, 1, 1, 0, 0))); // System.out.println("输入2025年(今年): " + getProcessedDateTime(LocalDateTime.of(2025, 1, 1, 0, 0))); // System.out.println("输入为空: " + getProcessedDateTime(null)); // } /** * 设置dateEnum 每根柱子上对应的时间数据 * * @param dateEnum 事件枚举 * @param chartIndex 从0 开始第几根柱子 * @param setStartTime 设置开始时间 * @param setEndTime 设置结束时间 */ public static void settingBarIndexDateValue(DateEnum dateEnum, Integer chartIndex, Consumer setStartTime, Consumer setEndTime) { if (Objects.isNull(dateEnum) || Objects.isNull(chartIndex) || Objects.isNull(setStartTime) || Objects.isNull(setEndTime)) { return; } List xAxisDataToNow = XAxisDataInitializer.initXAxisDataToNow(dateEnum); LocalDateTime now = LocalDateTime.now(); ValidUtil.assertIf(xAxisDataToNow.size() <= chartIndex, "传参有误"); String dateStr = xAxisDataToNow.get(chartIndex); if (StringUtils.isEmpty(dateStr)) { return; } LocalDateTime start = null; LocalDateTime end = null; switch (dateEnum) { case TODAY: { start = now.withHour(Integer.parseInt(dateStr)); end = now.withHour(Integer.parseInt(dateStr)); } break; case CURRENT_WEEK: { now = now.withDayOfMonth(Integer.parseInt(dateStr)).withHour(0); start = now.withHour(0); end = now.withHour(23); } break; case CURRENT_MONTH: { String[] split = dateStr.split("-"); now = now.with(TemporalAdjusters.firstDayOfMonth()); LocalDateTime localDateTime = now.withDayOfMonth(Integer.parseInt(split[1])); start = localDateTime.withHour(0); end = localDateTime.withHour(23); } break; case CURRENT_YEAR: { LocalDateTime firstMonthOfYear = LocalDateTime.now() .withMonth(Integer.parseInt(dateStr)); start = firstMonthOfYear.withDayOfMonth(1).withHour(0); end = firstMonthOfYear.with(TemporalAdjusters.lastDayOfMonth()).withHour(23); } break; } ; //开始时间 结束时间设置 setStartTime.accept(start.withMinute(0).withSecond(0).withNano(0)); setEndTime.accept(end.withMinute(59).withSecond(59).withNano(0)); } /** * 获取开始与结束时间内 格式化的时间数据 * * @param startDate 开始时间 * @param endDate 结束时间 * @param formatTime 格式化时间 字符串 * @return 格式化时间列表 */ public static List getFormatTimeByDate(LocalDateTime startDate, LocalDateTime endDate, String formatTime) { List formattedDates = new ArrayList<>(); if (startDate == null || endDate == null || formatTime == null) { return Collections.emptyList(); } // 如果开始时间晚于结束时间,交换它们 if (startDate.isAfter(endDate)) { LocalDateTime temp = startDate; startDate = endDate; endDate = temp; } DateTimeFormatter formatter = DateTimeFormatter.ofPattern(formatTime); // 添加开始时间 formattedDates.add(startDate.format(formatter)); // 如果开始和结束时间相同,直接返回 if (startDate.isEqual(endDate)) { return formattedDates; } // 按天递增,直到达到结束时间 LocalDateTime current = startDate.plusDays(1); while (!current.isAfter(endDate)) { formattedDates.add(current.format(formatter)); current = current.plusDays(1); } return formattedDates; } }