宋来一缕春风 2024-12-11 15:58:31

计算时间交集

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder(toBuilder = true)
public class TimePeriod {

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime beginTime;

    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime endTime;


    public static TimePeriod generateTimePeriod(String beginTime, String endTime){
        return TimePeriod.builder()
                .beginTime(DateUtil.parseLocalDateTime(beginTime, DateUtil.YYYYMMDD))
                .endTime(DateUtil.parseLocalDateTime(endTime, DateUtil.YYYYMMDD))
                .build();
    }

    public static TimePeriod generateTimePeriod(LocalDateTime beginTime, LocalDateTime endTime){
        return TimePeriod.builder()
                .beginTime(beginTime)
                .endTime(endTime)
                .build();
    }
}





import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

@Slf4j
public class TimePeriodUtil {
    private TimePeriodUtil(){
        throw new IllegalStateException("Utility class");
    }
    /**
     * 获取两个时间段的交集 <br/>
     * 若有一个时间段为 空,则返回空
     *
     * @param a
     * @param b
     * @return
     */
    public static TimePeriod getOverlapDate(TimePeriod a, TimePeriod b) {
        if (Objects.isNull(a) && Objects.isNull(b)) {
            return null;
        }else if (Objects.isNull(a)){
            return b;
        }else if (Objects.isNull(b)){
            return a;
        }
        LocalDateTime aBegin = a.getBeginTime();
        LocalDateTime aEnd = a.getEndTime();
        LocalDateTime bBegin = b.getBeginTime();
        LocalDateTime bEnd = b.getEndTime();

        TimePeriod overlapDate = new TimePeriod();
        if (Objects.isNull(aBegin) || Objects.isNull(aEnd) || Objects.isNull(bBegin) || Objects.isNull(bEnd)) {
            log.info("存在时间点为null");
            return overlapDate;
        }

        if (aBegin.isAfter(aEnd) || bBegin.isAfter(bEnd)){
            throw new ParamInvalidException("开始时间不得大于结束时间");
        }

        // 没有交集
        if (aEnd.isBefore(bBegin) || aBegin.isAfter(bEnd)){
            return overlapDate;
        }

        LocalDateTime overlapBegin = aBegin.isAfter(bBegin) ? aBegin : bBegin;
        LocalDateTime overlapEnd = aEnd.isBefore(bEnd) ? aEnd : bEnd;

        overlapDate.setBeginTime(overlapBegin);
        overlapDate.setEndTime(overlapEnd);
        log.info("交集为:{}", overlapDate);
        return overlapDate;
    }

    public static boolean ge(LocalDateTime a, LocalDateTime b) {
        Objects.requireNonNull(a);
        Objects.requireNonNull(b);

        return a.isAfter(b) || a.isEqual(b);
    }

    public static boolean le(LocalDateTime a, LocalDateTime b) {
        Objects.requireNonNull(a);
        Objects.requireNonNull(b);

        return a.isAfter(b) || a.isEqual(b);
    }

    public static TimePeriod getOverlapDate(List<TimePeriod> timePeriods) {
        TimePeriod ans = new TimePeriod();
        if (CollectionUtils.isEmpty(timePeriods)) {
            return ans;
        }
        if (timePeriods.size() == 1) {
            return timePeriods.get(0);
        }
        for (int i = 0, len=timePeriods.size(); i < len; i++) {
            if (i==0){
                ans = getOverlapDate(null, timePeriods.get(i));
            }else{
                ans = getOverlapDate(ans, timePeriods.get(i));
            }
            if (Objects.isNull(ans) || (Objects.isNull(ans.getBeginTime()) && Objects.isNull(ans.getEndTime()))) {
                break;
            }
            log.info("时间交集为{}至{}", ans.getBeginTime(), ans.getEndTime());
        }
        log.info("时间交集为:{}", ans);
        return ans;
    }

    public static boolean nonOverlap(TimePeriod timePeriod) {
        if (Objects.isNull(timePeriod)){
            return true;
        }
        return Objects.isNull(timePeriod.getBeginTime()) || Objects.isNull(timePeriod.getEndTime());
    }


    /**
     * 校验时间段是否连续
     * @param timePeriodList
     */
    public static void checkPeriodContinue(List<TimePeriod> timePeriodList){
        if (CollectionUtils.isEmpty(timePeriodList)){
            throw new ParamInvalidException("时间段为空");
        }
        // 根据区间的开始日期排序
        timePeriodList.sort(Comparator.comparing(TimePeriod::getBeginTime));
        int lastPeriodIndex = timePeriodList.size() - 1;
        for (int i = 0; i < lastPeriodIndex; i++) {

            if ((timePeriodList.get(i).getBeginTime().isAfter(timePeriodList.get(i).getEndTime()))
                    || !timePeriodList.get(i).getEndTime().plusDays(1).equals(timePeriodList.get(i + 1).getBeginTime())) {
                throw new ParamInvalidException("时间段不连续");
            }
        }
        // 校验最后一个期间
        if (timePeriodList.get(lastPeriodIndex).getBeginTime().isAfter(timePeriodList.get(lastPeriodIndex).getEndTime())) {
            throw new ParamInvalidException("时间段不连续");
        }
    }
}

评论

Home - Wiki
Copyright © 2011-2024 iteam. Current version is 2.138.0. UTC+08:00, 2024-12-22 01:11
浙ICP备14020137号-1 $Map of visitor$