宋来一缕春风 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("时间段不连续");
}
}
}