java时间切片工具 时间切割 时间切分
java时间切片工具 时间切割 时间切分
项目中经常会遇到根据根据时间区间来查询数据的场景, 如时间跨度大可能相应的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()); } }
结果