package com.southern.power.grid.utils; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.List; /** * 时间工具类 * * @author: junzhangfm * @date: 2026/3/14 **/ public class TimeUtil { // 完整格式:年月日 时分 private static final DateTimeFormatter FULL = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"); private static final DateTimeFormatter FULL_HOUR = DateTimeFormatter.ofPattern("yyyy/MM/dd HH时"); // 仅小时格式 private static final DateTimeFormatter HOUR = DateTimeFormatter.ofPattern("dd日HH时"); /** * 获取开始时间到结束时间的小时数组,仅当天的第一条数据会展示年月日 * 比如[2026/03/13/22, 13/23, 2026/03/14/00, 14/01] * * @param startTime 开始时间 * @param endTime 结束时间 * @return 结果 */ public static List generateHourList(String startTime, String endTime) { LocalDateTime start = LocalDateTime.parse(startTime, FULL); LocalDateTime end = LocalDateTime.parse(endTime, FULL); if (start.isAfter(end)) { throw new RuntimeException("generateHourList error! The endTime comes before the startTime."); } List result = new ArrayList<>(); LocalDateTime current = start; LocalDateTime preDate = null; while (!current.isAfter(end)) { // 第一次 或 日期发生变化(跨天0点)→ 显示完整年月日 if (preDate == null || !current.toLocalDate().equals(preDate.toLocalDate())) { result.add(current.format(FULL_HOUR)); } else { // 同一天 → 只显示小时 result.add(current.format(HOUR)); } preDate = current; current = current.plusHours(1); } return result; } /** * 获取开始时间到结束时间的小时数组,比如[2026-03-13 23:00, 2026-03-14 00:00, 2026-03-14 01:00] * * @param startTime 开始时间 * @param endTime 结束时间 * @return 结果 */ public static List generateHourListAll(String startTime, String endTime) { LocalDateTime start = LocalDateTime.parse(startTime, FULL); LocalDateTime end = LocalDateTime.parse(endTime, FULL); if (start.isAfter(end)) { throw new RuntimeException("generateHourList error! The endTime comes before the startTime."); } List result = new ArrayList<>(); LocalDateTime current = start; while (!current.isAfter(end)) { // 第一次 或 日期发生变化(跨天0点)→ 显示完整年月日 result.add(current.format(FULL)); current = current.plusHours(1); } return result; } /** * 获取开始日期到结束日期之间的所有日期(包含首尾) */ public static List getBetweenDates(String startDate, String endDate) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); List dateList = new ArrayList<>(); // 字符串转日期 LocalDate start = LocalDate.parse(startDate, formatter); LocalDate end = LocalDate.parse(endDate, formatter); // 循环遍历每一天 LocalDate current = start; while (!current.isAfter(end)) { dateList.add(current.format(formatter)); current = current.plusDays(1); } return dateList; } /** * 获取指定日期 往前推n天 的日期 * * @param dateStr 传入日期字符串 yyyy-MM-dd * @param num 前n天 * @return 前n天日期字符串 */ public static String getBeforeNumDays(String dateStr, int num) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 字符串转日期 LocalDate date = LocalDate.parse(dateStr, formatter); // 减去n天 LocalDate beforeDay = date.minusDays(num); // 转回字符串 return beforeDay.format(formatter); } /** * 获取前n个小时的时间 * * @param hourTime 指定时间,比如2026-03-17 11:00 * @param beforeHourNum 前n小时,比如2 * @return 前n小时的时间,比如2026-03-17 09:00 */ public static String getBeforeHourTime(String hourTime, int beforeHourNum) { // 定义格式 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:00"); // 1. 把字符串转成 LocalDateTime LocalDateTime dateTime = LocalDateTime.parse(hourTime, formatter); // 2. 减去 n 小时(核心方法) LocalDateTime beforeHour = dateTime.minusHours(beforeHourNum); // 3. 格式化返回(精确到小时,分钟固定 00) return beforeHour.format(formatter); } /** * 获取前n天的时间 * * @param dayTime 指定时间,比如2026-03-17 * @param beforeDayNum 前n天,比如2 * @return 前n天的日期,比如2026-03-15 */ public static String getBeforeDate(String dayTime, int beforeDayNum) { return LocalDate.parse(dayTime).minusDays(beforeDayNum).toString(); } public static void main(String[] args) { // List strings = generateHourList("2026-03-13 22:00", "2026-03-14 01:00"); // List strings = getBetweenDates("2026-03-10", "2026-03-14"); // String strings = getBeforeNumDays("2026-03-15", 5); // String beforeHourTime = getBeforeHourTime("2026-03-17 11:00", 2); // System.out.println(beforeHourTime); // System.out.println(getBeforeDate("2026-03-20", 2)); System.out.println(Math.round(12.12345 * 100) / 100.0); } private static final DateTimeFormatter DEFAULT_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); public static LocalDateTime parseToLocalDateTime(String dateTimeStr) { if (dateTimeStr == null || dateTimeStr.isEmpty()) { return null; } try { return LocalDateTime.parse(dateTimeStr, DEFAULT_FORMATTER); } catch (DateTimeParseException e) { return null; } } }