Java关于时间分割工具类实现

时间分割算法(工具)实现

原文地址

需求背景

​ 给定一个时间段:
​ 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 赫兹
 */
@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)
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值