时间分割算法(工具)实现
需求背景
给定一个时间段:
1.可以将时间段按年、按月、按周、按日进行切分。
2.并且可以根据某一时间轮数,获取当前的时间,例如:如将2021-10-01~2022-10-01,按月分割时,就能得到12轮时间段。可以通过指定轮数,获得对应的时间范围。
使用说明
🥝创建时间对象DataRange.java
类
/**
* @author 赫兹
*/
@Data
public class DateRange {
/**
* 开始时间
*/
private LocalDateTime begin;
/**
* 结束时间
*/
private LocalDateTime end;
/**
* 当前时间的第几轮(段)
*/
private Long turnNum;
}
🥝编写时间分割工具类DateSplitUtil.java
/**
* 时间分割工具类
*
* @author 赫兹
*/
public class DateSplitUtil {
private DateSplitUtil() {
throw new IllegalStateException("请通过静态方法调用!");
}
/**
* 切分时间,并且获取切分后的时间段集合
*
* @param type 分割类型:按年、按月、按周、按日
* @param startTime 开始时间
* @param endTime 结束时间
* @return 切分后的时间段集合
*/
public static List<DateRange> splitAndGetByType(int type, LocalDateTime startTime, LocalDateTime endTime) {
if (type == 1) {
// 按年切分
return splitDateRangeByYear(startTime, endTime);
} else if (type == 2) {
// 按月切分
return splitDateRangeByMonth(startTime, endTime);
} else if (type == 3) {
// 按周切分
return splitDateRangeByWeek(startTime, endTime);
} else if (type == 4) {
//按日切分
return splitDateRangeByDay(startTime, endTime);
} else if (type == 5) {
//一次性
List<DateRange> dateRangeList = new ArrayList<>();
DateRange dateRange = new DateRange();
dateRange.setBegin(startTime);
dateRange.setEnd(endTime);
dateRangeList.add(dateRange);
return dateRangeList;
} else {
return new ArrayList<>();
}
}
/**
* 切分时间,并且获取某一轮的时间对象
*
* @param type 分割类型:按年、按月、按周、按日
* @param turn 时间段(分割后的时间轮数,如将2021-10-01~2022-10-01,按月分割时,就能得到12轮时间段)
* @param startTime 开始时间
* @param endTime 结束时间
* @return 第turn段的时间对象
*/
public static DateRange splitAndGetByTurn(int type, long turn, LocalDateTime startTime, LocalDateTime endTime) {
//按年切分
if (type == 1) {
List<DateRange> dateRangeList = splitDateRangeByYear(startTime, endTime);
return getRangeByTurn(dateRangeList, turn);
} else if (type == 2) {
// 按月切分
List<DateRange> dateRangeList = splitDateRangeByMonth(startTime, endTime);
return getRangeByTurn(dateRangeList, turn);
} else if (type == 3) {
// 按周切分
List<DateRange> dateRangeList = splitDateRangeByWeek(startTime, endTime);
return getRangeByTurn(dateRangeList, turn);
} else if (type == 4) {
//按日切分
List<DateRange> dateRangeList = splitDateRangeByDay(startTime, endTime);
return getRangeByTurn(dateRangeList, turn);
} else if (type == 5) {
//一次性
DateRange dateRange = new DateRange();
dateRange.setBegin(startTime);
dateRange.setEnd(endTime);
return dateRange;
} else {
return new DateRange();
}
}
/**
* 按年分割
*
* @param startTime 开始时间
* @param endTime 结束时间
* @return 分割后的时间段集合
*/
private static List<DateRange> splitDateRangeByYear(LocalDateTime startTime, LocalDateTime endTime) {
long seconds = startTime.until(endTime, ChronoUnit.SECONDS);
if (seconds <= 0) {
return new ArrayList<>();
}
//轮数
long turnNum = 0;
//分割的时间段集合,使用累加算法
List<DateRange> dateList = new ArrayList<>();
DateRange range = new DateRange();
range.setBegin(startTime);
while (true) {
turnNum++;
//年份相等,不再累加
if (startTime.getYear() == endTime.getYear()) {
range.setEnd(endTime);
range.setTurnNum(turnNum);
dateList.add(range);
break;
}
//将时间调整为该年的第一天 0时 0分 0秒
startTime = LocalDateTime.of(LocalDate.from(startTime.with(TemporalAdjusters.firstDayOfYear()).plusYears(1)), LocalTime.MIN);
LocalDateTime tmpBegin = startTime;
//计算出上一天的最后一秒
LocalDateTime endDate = tmpBegin.minusSeconds(1);
range.setEnd(endDate);
range.setTurnNum(turnNum);
dateList.add(range);
//创建新的时间段
range = new DateRange();
range.setBegin(tmpBegin);
}
return dateList;
}
/**
* 按月分割
*
* @param startTime 开始时间
* @param endTime 结束时间
* @return 分割后的时间段集合
*/
private static List<DateRange> splitDateRangeByMonth(LocalDateTime startTime, LocalDateTime endTime) {
long seconds = startTime.until(endTime, ChronoUnit.SECONDS);
if (seconds <= 0) {
return new ArrayList<>();
}
//轮数
long turnNum = 0;
//分割的时间段集合,使用累加算法
List<DateRange> dateList = new ArrayList<>();
DateRange range = new DateRange();
range.setBegin(startTime);
while (true) {
turnNum++;
startTime = startTime.plusMonths(1);
//大于截止日期时,不再累加
if (startTime.isAfter(endTime)) {
range.setEnd(endTime);
range.setTurnNum(turnNum);
dateList.add(range);
break;
}
//将时间调整为当前月的第一天的 0时 0分 0秒
startTime = LocalDateTime.of(LocalDate.from(startTime.with(TemporalAdjusters.firstDayOfMonth())), LocalTime.MIN);
LocalDateTime tmpBegin = startTime;
//计算出上一天的最后一秒
LocalDateTime endDate = tmpBegin.minusSeconds(1);
range.setEnd(endDate);
range.setTurnNum(turnNum);
dateList.add(range);
//创建新的时间段
range = new DateRange();
range.setBegin(tmpBegin);
}
return dateList;
}
/**
* 按周分割
*
* @param startTime 开始时间
* @param endTime 结束时间
* @return 分割后的时间段集合
*/
private static List<DateRange> splitDateRangeByWeek(LocalDateTime startTime, LocalDateTime endTime) {
long seconds = startTime.until(endTime, ChronoUnit.SECONDS);
if (seconds <= 0) {
return new ArrayList<>();
}
//轮数
long turnNum = 0;
//分割的时间段集合,使用累加算法
List<DateRange> dateList = new ArrayList<>();
DateRange range = new DateRange();
range.setBegin(startTime);
while (true) {
turnNum++;
startTime = startTime.plusWeeks(1);
//大于截止日期时,不再累加
if (startTime.isAfter(endTime)) {
range.setEnd(endTime);
range.setTurnNum(turnNum);
dateList.add(range);
break;
}
//将时间调整为该周第一天的 0时 0分 0秒
startTime = LocalDateTime.of(LocalDate.from(startTime.with(DayOfWeek.MONDAY)), LocalTime.MIN);
LocalDateTime tmpBegin = startTime;
//计算出上一天的最后一秒
LocalDateTime endDate = tmpBegin.minusSeconds(1);
range.setEnd(endDate);
range.setTurnNum(turnNum);
dateList.add(range);
//创建新的时间段
range = new DateRange();
range.setBegin(tmpBegin);
}
return dateList;
}
/**
* 按日分割
*
* @param startTime 开始时间
* @param endTime 结束时间
* @return 分割后的时间段集合
*/
private static List<DateRange> splitDateRangeByDay(LocalDateTime startTime, LocalDateTime endTime) {
long seconds = startTime.until(endTime, ChronoUnit.SECONDS);
if (seconds < 0) {
return new ArrayList<>();
}
//轮数
long turnNum = 0;
//分割的时间段集合,使用累加算法
List<DateRange> dateList = new ArrayList<>();
DateRange range = new DateRange();
range.setBegin(startTime);
while (true) {
turnNum++;
startTime = startTime.plusDays(1);
//大于截止日期时,不再累加
if (startTime.isAfter(endTime)) {
range.setEnd(endTime);
range.setTurnNum(turnNum);
dateList.add(range);
break;
}
//将时间调整为该天的 0时 0分 0秒
startTime = LocalDateTime.of(startTime.getYear(), startTime.getMonth(), startTime.getDayOfMonth(), 0, 0, 0);
LocalDateTime tmpBegin = startTime;
//计算出上一天的最后一秒
LocalDateTime endDate = tmpBegin.minusSeconds(1);
range.setEnd(endDate);
range.setTurnNum(turnNum);
dateList.add(range);
//创建新的时间段
range = new DateRange();
range.setBegin(tmpBegin);
}
return dateList;
}
/**
* 根据时间段(分割后的时间轮数,2021-10-01~2022-10-01,按月分隔时就有12轮时间段)获取时间范围
*
* @param dateRangeList 分隔后的时间段集合
* @param turn 轮次,当前时间处于第几段
* @return 时间对象
*/
private static DateRange getRangeByTurn(List<DateRange> dateRangeList, long turn) {
DateRange dateRange = new DateRange();
for (DateRange d : dateRangeList) {
if (d.getTurnNum() == turn) {
dateRange = d;
}
}
return dateRange;
}
}
🥝编写单元测,测试结果
/**
* @author haizhou
* @since 2022/9/21
*/
@Slf4j
public class JUnitTest {
@Test
public void testDateSplitUtil() {
//2019-10-25 13:25:55
LocalDateTime startTime = LocalDateTime.of(2019, 10, 25, 13, 25, 55);
//2020-01-25 12:30:32
LocalDateTime endTime = LocalDateTime.of(2020, 1, 25, 12, 30, 32);
List<DateRange> dateYearRanges = DateSplitUtil.splitAndGetByType(1, startTime, endTime);
log.info("按年切分后的结果:\n{}",dateYearRanges);
List<DateRange> dateMonthRanges = DateSplitUtil.splitAndGetByType(2, startTime, endTime);
log.info("按月切分后的结果:\n{}",dateMonthRanges);
List<DateRange> dateWeekRanges = DateSplitUtil.splitAndGetByType(3, startTime, endTime);
log.info("按周切分后的结果:\n{}",dateWeekRanges);
List<DateRange> dateDayRanges = DateSplitUtil.splitAndGetByType(4, startTime, endTime);
log.info("按日切分后的结果:\n{}",dateDayRanges);
//获取割后的第二段时间
DateRange dateYearRangeByTurn = DateSplitUtil.splitAndGetByTurn(1,2, startTime, endTime);
log.info("第二段时间:\n{}",dateYearRangeByTurn);
}
}
🥝结果输出
22:19:20.774 [main] INFO com.hz.codecase.test.JUnitTest - 按年切分后的结果:
[DateRange(begin=2019-10-25T13:25:55, end=2019-12-31T23:59:59, turnNum=1), DateRange(begin=2020-01-01T00:00, end=2020-01-25T12:30:32, turnNum=2)]
22:19:20.778 [main] INFO com.hz.codecase.test.JUnitTest - 按月切分后的结果:
[DateRange(begin=2019-10-25T13:25:55, end=2019-10-31T23:59:59, turnNum=1), DateRange(begin=2019-11-01T00:00, end=2019-11-30T23:59:59, turnNum=2), DateRange(begin=2019-12-01T00:00, end=2019-12-31T23:59:59, turnNum=3), DateRange(begin=2020-01-01T00:00, end=2020-01-25T12:30:32, turnNum=4)]
22:19:20.778 [main] INFO com.hz.codecase.test.JUnitTest - 按周切分后的结果:
[DateRange(begin=2019-10-25T13:25:55, end=2019-10-27T23:59:59, turnNum=1), DateRange(begin=2019-10-28T00:00, end=2019-11-03T23:59:59, turnNum=2), DateRange(begin=2019-11-04T00:00, end=2019-11-10T23:59:59, turnNum=3), DateRange(begin=2019-11-11T00:00, end=2019-11-17T23:59:59, turnNum=4), DateRange(begin=2019-11-18T00:00, end=2019-11-24T23:59:59, turnNum=5), DateRange(begin=2019-11-25T00:00, end=2019-12-01T23:59:59, turnNum=6), DateRange(begin=2019-12-02T00:00, end=2019-12-08T23:59:59, turnNum=7), DateRange(begin=2019-12-09T00:00, end=2019-12-15T23:59:59, turnNum=8), DateRange(begin=2019-12-16T00:00, end=2019-12-22T23:59:59, turnNum=9), DateRange(begin=2019-12-23T00:00, end=2019-12-29T23:59:59, turnNum=10), DateRange(begin=2019-12-30T00:00, end=2020-01-05T23:59:59, turnNum=11), DateRange(begin=2020-01-06T00:00, end=2020-01-12T23:59:59, turnNum=12), DateRange(begin=2020-01-13T00:00, end=2020-01-19T23:59:59, turnNum=13), DateRange(begin=2020-01-20T00:00, end=2020-01-25T12:30:32, turnNum=14)]
22:19:20.778 [main] INFO com.hz.codecase.test.JUnitTest - 按日切分后的结果:
[DateRange(begin=2019-10-25T13:25:55, end=2019-10-25T23:59:59, turnNum=1), DateRange(begin=2019-10-26T00:00, end=2019-10-26T23:59:59, turnNum=2), DateRange(begin=2019-10-27T00:00, end=2019-10-27T23:59:59, turnNum=3), DateRange(begin=2019-10-28T00:00, end=2019-10-28T23:59:59, turnNum=4), DateRange(begin=2019-10-29T00:00, end=2019-10-29T23:59:59, turnNum=5), DateRange(begin=2019-10-30T00:00, end=2019-10-30T23:59:59, turnNum=6), DateRange(begin=2019-10-31T00:00, end=2019-10-31T23:59:59, turnNum=7), DateRange(begin=2019-11-01T00:00, end=2019-11-01T23:59:59, turnNum=8), DateRange(begin=2019-11-02T00:00, end=2019-11-02T23:59:59, turnNum=9), DateRange(begin=2019-11-03T00:00, end=2019-11-03T23:59:59, turnNum=10), DateRange(begin=2019-11-04T00:00, end=2019-11-04T23:59:59, turnNum=11), DateRange(begin=2019-11-05T00:00, end=2019-11-05T23:59:59, turnNum=12), DateRange(begin=2019-11-06T00:00, end=2019-11-06T23:59:59, turnNum=13), DateRange(begin=2019-11-07T00:00, end=2019-11-07T23:59:59, turnNum=14), DateRange(begin=2019-11-08T00:00, end=2019-11-08T23:59:59, turnNum=15), DateRange(begin=2019-11-09T00:00, end=2019-11-09T23:59:59, turnNum=16), DateRange(begin=2019-11-10T00:00, end=2019-11-10T23:59:59, turnNum=17), DateRange(begin=2019-11-11T00:00, end=2019-11-11T23:59:59, turnNum=18), DateRange(begin=2019-11-12T00:00, end=2019-11-12T23:59:59, turnNum=19), DateRange(begin=2019-11-13T00:00, end=2019-11-13T23:59:59, turnNum=20), DateRange(begin=2019-11-14T00:00, end=2019-11-14T23:59:59, turnNum=21), DateRange(begin=2019-11-15T00:00, end=2019-11-15T23:59:59, turnNum=22), DateRange(begin=2019-11-16T00:00, end=2019-11-16T23:59:59, turnNum=23), DateRange(begin=2019-11-17T00:00, end=2019-11-17T23:59:59, turnNum=24), DateRange(begin=2019-11-18T00:00, end=2019-11-18T23:59:59, turnNum=25), DateRange(begin=2019-11-19T00:00, end=2019-11-19T23:59:59, turnNum=26), DateRange(begin=2019-11-20T00:00, end=2019-11-20T23:59:59, turnNum=27), DateRange(begin=2019-11-21T00:00, end=2019-11-21T23:59:59, turnNum=28), DateRange(begin=2019-11-22T00:00, end=2019-11-22T23:59:59, turnNum=29), DateRange(begin=2019-11-23T00:00, end=2019-11-23T23:59:59, turnNum=30), DateRange(begin=2019-11-24T00:00, end=2019-11-24T23:59:59, turnNum=31), DateRange(begin=2019-11-25T00:00, end=2019-11-25T23:59:59, turnNum=32), DateRange(begin=2019-11-26T00:00, end=2019-11-26T23:59:59, turnNum=33), DateRange(begin=2019-11-27T00:00, end=2019-11-27T23:59:59, turnNum=34), DateRange(begin=2019-11-28T00:00, end=2019-11-28T23:59:59, turnNum=35), DateRange(begin=2019-11-29T00:00, end=2019-11-29T23:59:59, turnNum=36), DateRange(begin=2019-11-30T00:00, end=2019-11-30T23:59:59, turnNum=37), DateRange(begin=2019-12-01T00:00, end=2019-12-01T23:59:59, turnNum=38), DateRange(begin=2019-12-02T00:00, end=2019-12-02T23:59:59, turnNum=39), DateRange(begin=2019-12-03T00:00, end=2019-12-03T23:59:59, turnNum=40), DateRange(begin=2019-12-04T00:00, end=2019-12-04T23:59:59, turnNum=41), DateRange(begin=2019-12-05T00:00, end=2019-12-05T23:59:59, turnNum=42), DateRange(begin=2019-12-06T00:00, end=2019-12-06T23:59:59, turnNum=43), DateRange(begin=2019-12-07T00:00, end=2019-12-07T23:59:59, turnNum=44), DateRange(begin=2019-12-08T00:00, end=2019-12-08T23:59:59, turnNum=45), DateRange(begin=2019-12-09T00:00, end=2019-12-09T23:59:59, turnNum=46), DateRange(begin=2019-12-10T00:00, end=2019-12-10T23:59:59, turnNum=47), DateRange(begin=2019-12-11T00:00, end=2019-12-11T23:59:59, turnNum=48), DateRange(begin=2019-12-12T00:00, end=2019-12-12T23:59:59, turnNum=49), DateRange(begin=2019-12-13T00:00, end=2019-12-13T23:59:59, turnNum=50), DateRange(begin=2019-12-14T00:00, end=2019-12-14T23:59:59, turnNum=51), DateRange(begin=2019-12-15T00:00, end=2019-12-15T23:59:59, turnNum=52), DateRange(begin=2019-12-16T00:00, end=2019-12-16T23:59:59, turnNum=53), DateRange(begin=2019-12-17T00:00, end=2019-12-17T23:59:59, turnNum=54), DateRange(begin=2019-12-18T00:00, end=2019-12-18T23:59:59, turnNum=55), DateRange(begin=2019-12-19T00:00, end=2019-12-19T23:59:59, turnNum=56), DateRange(begin=2019-12-20T00:00, end=2019-12-20T23:59:59, turnNum=57), DateRange(begin=2019-12-21T00:00, end=2019-12-21T23:59:59, turnNum=58), DateRange(begin=2019-12-22T00:00, end=2019-12-22T23:59:59, turnNum=59), DateRange(begin=2019-12-23T00:00, end=2019-12-23T23:59:59, turnNum=60), DateRange(begin=2019-12-24T00:00, end=2019-12-24T23:59:59, turnNum=61), DateRange(begin=2019-12-25T00:00, end=2019-12-25T23:59:59, turnNum=62), DateRange(begin=2019-12-26T00:00, end=2019-12-26T23:59:59, turnNum=63), DateRange(begin=2019-12-27T00:00, end=2019-12-27T23:59:59, turnNum=64), DateRange(begin=2019-12-28T00:00, end=2019-12-28T23:59:59, turnNum=65), DateRange(begin=2019-12-29T00:00, end=2019-12-29T23:59:59, turnNum=66), DateRange(begin=2019-12-30T00:00, end=2019-12-30T23:59:59, turnNum=67), DateRange(begin=2019-12-31T00:00, end=2019-12-31T23:59:59, turnNum=68), DateRange(begin=2020-01-01T00:00, end=2020-01-01T23:59:59, turnNum=69), DateRange(begin=2020-01-02T00:00, end=2020-01-02T23:59:59, turnNum=70), DateRange(begin=2020-01-03T00:00, end=2020-01-03T23:59:59, turnNum=71), DateRange(begin=2020-01-04T00:00, end=2020-01-04T23:59:59, turnNum=72), DateRange(begin=2020-01-05T00:00, end=2020-01-05T23:59:59, turnNum=73), DateRange(begin=2020-01-06T00:00, end=2020-01-06T23:59:59, turnNum=74), DateRange(begin=2020-01-07T00:00, end=2020-01-07T23:59:59, turnNum=75), DateRange(begin=2020-01-08T00:00, end=2020-01-08T23:59:59, turnNum=76), DateRange(begin=2020-01-09T00:00, end=2020-01-09T23:59:59, turnNum=77), DateRange(begin=2020-01-10T00:00, end=2020-01-10T23:59:59, turnNum=78), DateRange(begin=2020-01-11T00:00, end=2020-01-11T23:59:59, turnNum=79), DateRange(begin=2020-01-12T00:00, end=2020-01-12T23:59:59, turnNum=80), DateRange(begin=2020-01-13T00:00, end=2020-01-13T23:59:59, turnNum=81), DateRange(begin=2020-01-14T00:00, end=2020-01-14T23:59:59, turnNum=82), DateRange(begin=2020-01-15T00:00, end=2020-01-15T23:59:59, turnNum=83), DateRange(begin=2020-01-16T00:00, end=2020-01-16T23:59:59, turnNum=84), DateRange(begin=2020-01-17T00:00, end=2020-01-17T23:59:59, turnNum=85), DateRange(begin=2020-01-18T00:00, end=2020-01-18T23:59:59, turnNum=86), DateRange(begin=2020-01-19T00:00, end=2020-01-19T23:59:59, turnNum=87), DateRange(begin=2020-01-20T00:00, end=2020-01-20T23:59:59, turnNum=88), DateRange(begin=2020-01-21T00:00, end=2020-01-21T23:59:59, turnNum=89), DateRange(begin=2020-01-22T00:00, end=2020-01-22T23:59:59, turnNum=90), DateRange(begin=2020-01-23T00:00, end=2020-01-23T23:59:59, turnNum=91), DateRange(begin=2020-01-24T00:00, end=2020-01-24T23:59:59, turnNum=92), DateRange(begin=2020-01-25T00:00, end=2020-01-25T12:30:32, turnNum=93)]
22:19:20.779 [main] INFO com.hz.codecase.test.JUnitTest - 第二段时间:
DateRange(begin=2020-01-01T00:00, end=2020-01-25T12:30:32, turnNum=2)
评论区