Java对时间切片,对时间分片,时间切割

我们在数据查询或者数据导出的时候,经常因为时间跨度过大,降低了导出性能。

为了提高性能,我们往往需要对时间进行切分查询,鉴于此,我们需要对时间段,进行切分。

需要一个工具的时候,不应该是先造轮子,而是先寻找别人已经造好的轮子,我到了java时间切片工具 时间切割 时间切分,但是不是很满意。

因为为了提高查询效率,往往我们也会去缓存查询到结果,例如用时间区间做 key 去缓存。但是如果你的时间切割的不合理就会造成很多缓存无法命中。

为了提高时间切片查询缓存的命中率,我决定花时间去造个轮子。

如果它对你的工作和学习有所帮助,请你不要吝惜你的。


import cn.hutool.core.date.LocalDateTimeUtil;
import lombok.Data;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

public class TimeUtil {
    @Data
    public static class TimePage {
        /**
         * 分片开始查询时间
         */
        private LocalDateTime beginDateTime;

        /**
         * 分片结束查询时间
         */
        private LocalDateTime endDateTime;

        /**
         * 初始开始查询时间
         */
        private LocalDateTime initBeginDateTime;

        /**
         * 初始结束查询时间
         */
        private LocalDateTime initEndDateTime;

        /**
         * 是否分页查询完成
         *
         * @return 完成
         */
        public boolean isPageFinish() {
            return getEndDateTime().isEqual(getInitEndDateTime());
        }
    }

    public static TimePage genHighHitTimePage(TimePage timePage, long interval) {
        TimePage newTimePage = new TimePage();
        newTimePage.setInitBeginDateTime(timePage.getInitBeginDateTime());
        newTimePage.setInitEndDateTime(timePage.getInitEndDateTime());
        LocalDateTime beginDateTime = timePage.getBeginDateTime();
        // 分片查询开始时间
        newTimePage.setBeginDateTime(beginDateTime);
        LocalDateTime endDateTime = LocalDateTimeUtil.offset(LocalDateTimeUtil.beginOfDay(beginDateTime), TimeUtil.getSkipHour(beginDateTime, interval), ChronoUnit.HOURS);
        newTimePage.setEndDateTime(endDateTime);
        // 防止分片查询结束时间超过查询结束时间
        if (newTimePage.getEndDateTime().isAfter(newTimePage.getInitEndDateTime())) {
            newTimePage.setEndDateTime(newTimePage.getInitEndDateTime());
        }

        return newTimePage;
    }

    /**
     * 返回时间的高命中时间
     *
     * @param now      从 0 - 23 点
     * @param interval 间隔单位秒
     * @return 返回小时,相对于 now 的 0 点
     */
    public static int getSkipHour(LocalDateTime now, long interval) {
        int hour;
        int nowHour = now.getHour();
        if (interval >= 86400) {
            // 间隔超过 24 小时
            hour = 24;
        } else if (interval >= (3600 * 12)) {
            // 间隔超过 12 个小时
            hour = nowHour < 12 ? 12 : 24;
        } else if (interval >= (3600 * 8)) {
            // 间隔超过 8 个小时
            hour = nowHour < 8 ? 8 : (nowHour < 16 ? 16 : 24);
        } else if (interval >= (3600 * 6)) {
            // 间隔超过 6 个小时
            hour = nowHour < 6 ? 6 : (nowHour < 12 ? 12 : (nowHour < 18 ? 18 : 24));
        } else if (interval >= (3600 * 4)) {
            // 间隔超过 4 个小时
            if (nowHour < 4) {
                hour = 4;
            } else if (nowHour < 8) {
                hour = 8;
            } else if (nowHour < 12) {
                hour = 12;
            } else if (nowHour < 16) {
                hour = 16;
            } else if (nowHour < 20) {
                hour = 20;
            } else {
                hour = 24;
            }
        } else if (interval >= (3600 * 3)) {
            // 间隔超过 2 个小时
            if (nowHour < 3) {
                hour = 3;
            } else if (nowHour < 6) {
                hour = 6;
            } else if (nowHour < 9) {
                hour = 9;
            } else if (nowHour < 12) {
                hour = 12;
            } else if (nowHour < 15) {
                hour = 15;
            } else if (nowHour < 18) {
                hour = 18;
            } else if (nowHour < 21) {
                hour = 21;
            } else {
                hour = 24;
            }
        } else if (interval >= (3600 * 2)) {
            // 间隔超过 2 个小时
            if (nowHour < 2) {
                hour = 2;
            } else if (nowHour < 4) {
                hour = 4;
            } else if (nowHour < 6) {
                hour = 6;
            } else if (nowHour < 8) {
                hour = 8;
            } else if (nowHour < 10) {
                hour = 10;
            } else if (nowHour < 12) {
                hour = 12;
            } else if (nowHour < 14) {
                hour = 14;
            } else if (nowHour < 16) {
                hour = 16;
            } else if (nowHour < 18) {
                hour = 18;
            } else if (nowHour < 20) {
                hour = 20;
            } else if (nowHour < 22) {
                hour = 22;
            } else {
                hour = 24;
            }
        } else {
            hour = nowHour + 1;
        }

        return hour;
    }
}

测试:

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN);
String startDateTime = "2023-05-01 11:00:05";
String endDateTime = "2023-05-03 18:23:00";
// 间隔,单位秒
long interval = 7200L;
LocalDateTime startTime = LocalDateTime.parse(startDateTime, dateTimeFormatter);
LocalDateTime endTime = LocalDateTime.parse(endDateTime, dateTimeFormatter);
TimeUtil.TimePage timePage = new TimeUtil.TimePage();
// 初始化
timePage.setInitBeginDateTime(startTime);
timePage.setInitEndDateTime(endTime);
timePage.setBeginDateTime(startTime);
timePage.setEndDateTime(endTime);
// 生成
TimeUtil.TimePage newTimePage = TimeUtil.genHighHitTimePage(timePage, interval);
System.out.println(newTimePage);
while (!newTimePage.isPageFinish()) {
    newTimePage.setBeginDateTime(newTimePage.getEndDateTime());
    newTimePage = TimeUtil.genHighHitTimePage(newTimePage, interval);
    System.out.println(newTimePage);
}

结果:

TimeUtil.TimePage(beginDateTime=2023-05-01T11:00:05, endDateTime=2023-05-01T12:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-01T12:00, endDateTime=2023-05-01T14:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-01T14:00, endDateTime=2023-05-01T16:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-01T16:00, endDateTime=2023-05-01T18:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-01T18:00, endDateTime=2023-05-01T20:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-01T20:00, endDateTime=2023-05-01T22:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-01T22:00, endDateTime=2023-05-02T00:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-02T00:00, endDateTime=2023-05-02T02:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-02T02:00, endDateTime=2023-05-02T04:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-02T04:00, endDateTime=2023-05-02T06:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-02T06:00, endDateTime=2023-05-02T08:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-02T08:00, endDateTime=2023-05-02T10:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-02T10:00, endDateTime=2023-05-02T12:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-02T12:00, endDateTime=2023-05-02T14:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-02T14:00, endDateTime=2023-05-02T16:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-02T16:00, endDateTime=2023-05-02T18:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-02T18:00, endDateTime=2023-05-02T20:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-02T20:00, endDateTime=2023-05-02T22:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-02T22:00, endDateTime=2023-05-03T00:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-03T00:00, endDateTime=2023-05-03T02:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-03T02:00, endDateTime=2023-05-03T04:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-03T04:00, endDateTime=2023-05-03T06:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-03T06:00, endDateTime=2023-05-03T08:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-03T08:00, endDateTime=2023-05-03T10:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-03T10:00, endDateTime=2023-05-03T12:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-03T12:00, endDateTime=2023-05-03T14:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-03T14:00, endDateTime=2023-05-03T16:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-03T16:00, endDateTime=2023-05-03T18:00, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)
TimeUtil.TimePage(beginDateTime=2023-05-03T18:00, endDateTime=2023-05-03T18:23, initBeginDateTime=2023-05-01T11:00:05, initEndDateTime=2023-05-03T18:23)

参考

posted @ 2023-05-07 23:16  沙里  阅读(951)  评论(0)    收藏  举报