时间段划分
0.已经时间段,需要知道这个时间段包含那些天
1.把一个时间段划分为 整天 和非整天的时间段
例如: "2024-07-11 08:30:00" ~ "2024-07-23 08:30:00";
例如 完整的日期:
2024-07-12 2024-07-13 2024-07-14 2024-07-15 2024-07-16 2024-07-17
2024-07-18 2024-07-19 2024-07-20 2024-07-21 2024-07-22
不完整的日期时间戳段:
2024-07-11 08:30:00 - 2024-07-11 23:59:59
2024-07-23 00:00:00 - 2024-07-23 08:30:00
2.已经知道 List<LocalDate> localDay 例如 2024-07-11 2024-07-12 2024-07-15 2024-07-16 2024-07-17 2024-07-18 2024-07-19 2024-07-28
把相邻的day , 划分为一个时间段,并且每个时间段 最大为3天
/** * 把一个时间段划分为 整天 有哪些day 已经时间段,需要知道这个时间段包含那些天 */ public static List<LocalDate> getDiffDay(LocalDate startDate,LocalDate endDate){ List<LocalDate> localDateList = new ArrayList<>(); for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)){ localDateList.add(date);} return localDateList; }
计算时间差
@Test public void testTimeDiff() { // 计算时间差 LocalDateTime startTime = LocalDateTime.of(2023, 10, 1, 10, 0); LocalDateTime endTime = LocalDateTime.of(2023, 10, 2, 10, 0); long hoursBetween = ChronoUnit.HOURS.between(startTime, endTime); long dayBetween = ChronoUnit.DAYS.between(startTime, endTime); long minutesBetween = ChronoUnit.MINUTES.between(startTime, endTime); System.out.println("Hours: " + hoursBetween); System.out.println("day: " + dayBetween); System.out.println("Minutes: " + minutesBetween); }
import java.sql.Timestamp; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.util.*; /*************************** *<pre> * @File Name : BaseTesst * @Author : Sea * @Mail : lshan523@163.com * @Date : 2024/8/7 17:45 * @Purpose : * @History : *</pre> ***************************/ public class BaseTesst { /** * 把一个时间段划分为 整天 和非整天的时间段 * @param fromDateStr "2024-07-11 08:30:00"; * @param toDateStr "2024-07-23 08:30:00"; * @return map{full->list<LocalDate> ,part ->list<Long> } */ public static HashMap<String, List> getDateRange(String fromDateStr , String toDateStr) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(TimeZone.getTimeZone("Asia/Shanghai").toZoneId()); LocalDateTime fromDateTime = LocalDateTime.parse(fromDateStr, formatter); LocalDateTime toDateTime = LocalDateTime.parse(toDateStr, formatter); List<LocalDate> fullDays = new ArrayList<>(); List<List<Long>> partialDaysTimestamps = new ArrayList<>(); // 获取开始和结束日期 LocalDate startDate = fromDateTime.toLocalDate(); LocalDate endDate = toDateTime.toLocalDate(); // 遍历日期范围 for (LocalDate date = startDate; !date.isAfter(endDate); date = date.plusDays(1)) { if (date.equals(startDate) && fromDateTime.toLocalTime().isAfter(LocalTime.MIN)) { // 从开始日期的时间部分不在整天内 long startTimestamp = Timestamp.valueOf(fromDateTime).getTime()/1000; long endTimestamp = Timestamp.valueOf(date.atTime(LocalTime.MAX)).getTime()/1000; // String startTimestamp = fromDateTime.format(formatter); // String endTimestamp = date.atTime(LocalTime.MAX).format(formatter); partialDaysTimestamps.add(Arrays.asList(startTimestamp,endTimestamp)); } else if (date.equals(endDate) && toDateTime.toLocalTime().isBefore(LocalTime.MAX)) { // 至结束日期的时间部分不在整天内 long startTimestamp = Timestamp.valueOf(date.atTime(LocalTime.MIN)).getTime()/1000; long endTimestamp = Timestamp.valueOf(toDateTime).getTime()/1000; // String startTimestamp = date.atTime(LocalTime.MIN).format(formatter); // String endTimestamp = toDateTime.format(formatter); partialDaysTimestamps.add(Arrays.asList(startTimestamp,endTimestamp)); } else { // 完整的一天 fullDays.add(date); } } HashMap<String, List> result = new HashMap<>(); result.put("full",fullDays); result.put("part",partialDaysTimestamps); System.out.println("完整的日期:"); fullDays.forEach(System.out::println); System.out.println("不完整的日期时间戳段:"); partialDaysTimestamps.forEach(System.out::println); return result; } @Test public void testGetDateRange() throws Exception { String fromDateStr = "2024-07-11 08:30:00"; String toDateStr = "2024-07-14 08:30:00"; getDateRange(fromDateStr,toDateStr); // 完整的日期: // 2024-07-12 // 2024-07-13 // 不完整的日期时间戳段: // [1720657800, 1720713599] // [1721664000, 1721694600] } /** * 将相邻的 LocalDate 划分为时间段,同时确保每个时间段的最大长度为 3 天 * @throws Exception */ @Test public void testGroupDateRanges() throws Exception { // 创建一个 LocalDate 列表 List<LocalDate> localDays = Arrays.asList( LocalDate.of(2024, 7, 11), LocalDate.of(2024, 7, 12) , LocalDate.of(2024, 7, 15), LocalDate.of(2024, 7, 16), LocalDate.of(2024, 7, 17), LocalDate.of(2024, 7, 18), LocalDate.of(2024, 7, 19), LocalDate.of(2024, 7, 20), LocalDate.of(2024, 7, 21), LocalDate.of(2024, 7, 25) ); // 划分时间段 List<List<LocalDate>> dateRanges = groupDateRanges(localDays,3); // 输出结果 for (List<LocalDate> range : dateRanges) { System.out.println(formatRange(range.get(0),range.get(range.size()-1))); } // 2024-07-11 to 2024-07-12 // 2024-07-15 to 2024-07-17 // 2024-07-18 to 2024-07-20 // 2024-07-21 // 2024-07-25 } /** * 将相邻的 LocalDate 划分为时间段,同时确保每个时间段的最大长度为 3 天 * @param localDays * @param maxIntervalDay * @return */ private static List<List<LocalDate>> groupDateRanges(List<LocalDate> localDays,int maxIntervalDay) { List<List<LocalDate>> ranges = new ArrayList<>(); if (localDays.isEmpty()) { return ranges; } LocalDate start = localDays.get(0); LocalDate end = start; for (int i = 1; i < localDays.size(); i++) { LocalDate current = localDays.get(i); // 检查当前日期与上一个日期的差异 if (current.equals(end.plusDays(1))) { end = current; // 继续扩展当前时间段 } else { // 检查时间段长度是否超过 3 天 addRange(ranges, start, end,maxIntervalDay); start = current; // 开始新的时间段 end = start; } } // 添加最后一个时间段 addRange(ranges, start, end,maxIntervalDay); return ranges; } private static void addRange(List<List<LocalDate>> ranges, LocalDate start, LocalDate end,int intervalDay) { while (!start.isAfter(end)) { LocalDate rangeEnd = start.plusDays(intervalDay-1); // 最大 3 天(起始日 + 2) if (rangeEnd.isAfter(end)) { rangeEnd = end; // 不超过实际结束日期 } // ranges.add(formatRange(start, rangeEnd)); ranges.add(Arrays.asList(start, rangeEnd)); start = rangeEnd.plusDays(1); // 移动到下一个时间段的开始 } } private static String formatRange(LocalDate start, LocalDate end) { if (start.equals(end)) { return start.toString(); // 单个日期 } else { return start + " to " + end; // 时间段 } } }