欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

java时间切片工具

程序员文章站 2022-07-02 11:54:45
项目中经常会遇到根据根据时间区间来查询数据的场景, 如时间跨度大可能相应的sql的执行效率会显著降低, 因此可以对时间区间进行切割成若干个小范围的时间片, 这样不仅可以提高sql的性能还可以做一下并发执行, 提高整体查询的速度; java没有原生的api,或者可能是我没找到, 项目中用到过, 把这个 ......

  项目中经常会遇到根据根据时间区间来查询数据的场景, 如时间跨度大可能相应的sql的执行效率会显著降低, 因此可以对时间区间进行切割成若干个小范围的时间片, 这样不仅可以提高sql的性能还可以做一下并发执行, 提高整体查询的速度;

      java没有原生的api,或者可能是我没找到, 项目中用到过, 把这个工具类抽出来. 方便需要的朋友取用;

      功能: 支持根据时间区间 按照 天 小时 分 秒做指定时间间隔的分隔

      直接上代码了:

      

import lombok.allargsconstructor;
import lombok.data;
import lombok.noargsconstructor;
import lombok.extern.slf4j.slf4j;

import java.text.simpledateformat;
import java.util.arraylist;
import java.util.calendar;
import java.util.date;
import java.util.list;

/**
 * @description: 时间切片工具
 * @auther: xuxiaojun
 * @date: 2020-03-19
 */
public class datesplitutils {

    public enum intervaltype {
        day,
        hour,
        minute,
        second,
        ;
    }

    /**
     * 时间切割
     * @param starttime    被切割的开始时间
     * @param endtime      被切割的结束时间
     * @param intervaltype
     * @param interval     >0
     * @return
     */
    public static list<datesplit> splitdate(date starttime, date endtime, intervaltype intervaltype, int interval) {
        if (interval < 0) {
            return null;
        }
        if (endtime.gettime() <= starttime.gettime()) {
            return null;
        }

        if (intervaltype == intervaltype.day) {
            return splitbyday(starttime, endtime, interval);
        }
        if (intervaltype == intervaltype.hour) {
            return splitbyhour(starttime, endtime, interval);
        }
        if (intervaltype == intervaltype.minute) {
            return splitbyminute(starttime, endtime, interval);
        }
        if (intervaltype == intervaltype.second) {
            return splitbysecond(starttime, endtime, interval);
        }
        return null;
    }

    /**
     * 按照小时切割时间区间
     */
    public static list<datesplit> splitbyhour(date starttime, date endtime, int intervalhours) {
        if (endtime.gettime() <= starttime.gettime()) {
            return null;
        }

        list<datesplit> datesplits = new arraylist<>(256);

        datesplit param = new datesplit();
        param.setstartdatetime(starttime);
        param.setenddatetime(endtime);
        param.setenddatetime(addhours(starttime, intervalhours));
        while (true) {
            param.setstartdatetime(starttime);
            date tempendtime = addhours(starttime, intervalhours);
            if (tempendtime.gettime() >= endtime.gettime()) {
                tempendtime = endtime;
            }
            param.setenddatetime(tempendtime);

            datesplits.add(new datesplit(param.getstartdatetime(), param.getenddatetime()));

            starttime = addhours(starttime, intervalhours);
            if (starttime.gettime() >= endtime.gettime()) {
                break;
            }
            if (param.getenddatetime().gettime() >= endtime.gettime()) {
                break;
            }
        }
        return datesplits;
    }

    /**
     * 按照秒切割时间区间
     */
    public static list<datesplit> splitbysecond(date starttime, date endtime, int intervalseconds) {
        if (endtime.gettime() <= starttime.gettime()) {
            return null;
        }
        list<datesplit> datesplits = new arraylist<>(256);

        datesplit param = new datesplit();
        param.setstartdatetime(starttime);
        param.setenddatetime(endtime);
        param.setenddatetime(addseconds(starttime, intervalseconds));
        while (true) {
            param.setstartdatetime(starttime);
            date tempendtime = addseconds(starttime, intervalseconds);
            if (tempendtime.gettime() >= endtime.gettime()) {
                tempendtime = endtime;
            }
            param.setenddatetime(tempendtime);

            datesplits.add(new datesplit(param.getstartdatetime(), param.getenddatetime()));

            starttime = addseconds(starttime, intervalseconds);
            if (starttime.gettime() >= endtime.gettime()) {
                break;
            }
            if (param.getenddatetime().gettime() >= endtime.gettime()) {
                break;
            }
        }
        return datesplits;
    }

    /**
     * 按照天切割时间区间
     */
    public static list<datesplit> splitbyday(date starttime, date endtime, int intervaldays) {
        if (endtime.gettime() <= starttime.gettime()) {
            return null;
        }
        list<datesplit> datesplits = new arraylist<>(256);

        datesplit param = new datesplit();
        param.setstartdatetime(starttime);
        param.setenddatetime(endtime);
        param.setenddatetime(adddays(starttime, intervaldays));
        while (true) {
            param.setstartdatetime(starttime);
            date tempendtime = adddays(starttime, intervaldays);
            if (tempendtime.gettime() >= endtime.gettime()) {
                tempendtime = endtime;
            }
            param.setenddatetime(tempendtime);

            datesplits.add(new datesplit(param.getstartdatetime(), param.getenddatetime()));

            starttime = adddays(starttime, intervaldays);
            if (starttime.gettime() >= endtime.gettime()) {
                break;
            }
            if (param.getenddatetime().gettime() >= endtime.gettime()) {
                break;
            }
        }
        return datesplits;
    }

    /**
     * 按照分钟切割时间区间
     *
     * @param starttime
     * @param endtime
     * @param intervalminutes
     * @return
     */
    public static list<datesplit> splitbyminute(date starttime, date endtime, int intervalminutes) {
        if (endtime.gettime() <= starttime.gettime()) {
            return null;
        }
        list<datesplit> datesplits = new arraylist<>(256);

        datesplit param = new datesplit();
        param.setstartdatetime(starttime);
        param.setenddatetime(endtime);
        param.setenddatetime(addminute(starttime, intervalminutes));
        while (true) {
            param.setstartdatetime(starttime);
            date tempendtime = addminute(starttime, intervalminutes);
            if (tempendtime.gettime() >= endtime.gettime()) {
                tempendtime = endtime;
            }
            param.setenddatetime(tempendtime);

            datesplits.add(new datesplit(param.getstartdatetime(), param.getenddatetime()));

            starttime = addminute(starttime, intervalminutes);
            if (starttime.gettime() >= endtime.gettime()) {
                break;
            }
            if (param.getenddatetime().gettime() >= endtime.gettime()) {
                break;
            }
        }
        return datesplits;
    }



    private static date adddays(date date, int days) {
        return add(date, calendar.day_of_month, days);
    }

    private static date addhours(date date, int hours) {
        return add(date, calendar.hour_of_day, hours);
    }

    private static date addminute(date date, int minute) {
        return add(date, calendar.minute, minute);
    }
    private static date addseconds(date date, int second) {
        return add(date, calendar.second, second);
    }

    private static date add(final date date, final int calendarfield, final int amount) {
        final calendar c = calendar.getinstance();
        c.settime(date);
        c.add(calendarfield, amount);
        return c.gettime();
    }

    private static string formatdatetime(date date) {
        if (date == null) {
            return "";
        }
        simpledateformat simpledateformat = new simpledateformat("yyyy-mm-dd hh:mm:ss");
        return simpledateformat.format(date);
    }

    @data
    @allargsconstructor
    @noargsconstructor
    public static class datesplit {
        private date startdatetime;
        private date enddatetime;

        public string getstartdatetimestr() {
            return formatdatetime(startdatetime);
        }

        public string getenddatetimestr() {
            return formatdatetime(enddatetime);
        }
    }


}

  

 测试一下 按照小时做每两个小时的时间切割

    public static void main(string[] args) {
        date yesterdayfirsttime = dateutils.minusdays(dateutils.getdayfirsttime(), 2);
        date yesterdayendtime = dateutils.minusdays(dateutils.getdayendtime(), 1);
        list<datesplitutils.datesplit> datesplits = datesplitutils.splitdate(yesterdayfirsttime, yesterdayendtime, datesplitutils.intervaltype.hour,2);

        for (datesplitutils.datesplit datesplit : datesplits) {
            system.out.println("切割后的时间区间: " + datesplit.getstartdatetimestr() + " --->  " +  datesplit.getenddatetimestr());

        }
    }

  

结果

 java时间切片工具