You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java是否有工具类可按输入拆分日期区间并判定数据库增改操作?

Java日期区间拆分及操作判定方案

Java原生标准库中没有直接适配该业务场景的现成Util方法,但可以基于Java 8及以上版本提供的java.time日期API自行实现,核心逻辑只需围绕区间重叠判定和区间拆分两个步骤实现即可。

核心实现逻辑

你描述的场景属于典型的时间分片冲突处理场景,核心步骤如下:

  • 首先判定输入区间和数据库已有区间的重叠关系
  • 按照边界点拆分出所有不重叠的子区间
  • 按子区间的归属判定操作类型:
    • 完全属于原有区间且不在输入区间内:更新原有记录
    • 属于输入区间:新增记录
    • 完全覆盖原有区间:直接更新原有记录的结束时间即可
    • 和原有区间完全无重叠:直接新增记录

代码实现示例

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

// 区间实体类
class DateRange {
    private LocalDate start;
    private LocalDate end;
    private String opType; // 操作类型:UPDATE/INSERT/NO_OP

    public DateRange(LocalDate start, LocalDate end, String opType) {
        this.start = start;
        this.end = end;
        this.opType = opType;
    }

    public LocalDate getStart() {
        return start;
    }

    public LocalDate getEnd() {
        return end;
    }

    public String getOpType() {
        return opType;
    }

    @Override
    public String toString() {
        return start + " to " + end + " // " + opType;
    }
}

public class DateRangeSplitUtil {
    private static final String UPDATE = "更新数据库中现有记录";
    private static final String INSERT = "新增记录";

    public static List<DateRange> splitRange(DateRange existedRange, DateRange inputRange) {
        List<DateRange> result = new ArrayList<>();
        LocalDate exStart = existedRange.getStart();
        LocalDate exEnd = existedRange.getEnd();
        LocalDate inStart = inputRange.getStart();
        LocalDate inEnd = inputRange.getEnd();

        // 输入区间和原有区间完全无重叠
        if (inStart.isAfter(exEnd)) {
            result.add(new DateRange(inStart, inEnd, INSERT));
            return result;
        }

        // 拆分原有区间在输入区间左侧的部分
        if (inStart.isAfter(exStart)) {
            result.add(new DateRange(exStart, inStart.minusDays(1), UPDATE));
        }

        // 判定输入区间的操作类型
        String op = INSERT;
        if (inStart.isEqual(exStart) && inEnd.isAfter(exEnd)) {
            op = UPDATE;
        } else if (inStart.isEqual(exStart) && inEnd.isBefore(exEnd)) {
            op = UPDATE;
        }
        result.add(new DateRange(inStart, inEnd, op));

        // 拆分原有区间在输入区间右侧的部分
        if (inEnd.isBefore(exEnd)) {
            result.add(new DateRange(inEnd.plusDays(1), exEnd, INSERT));
        }

        return result;
    }

    public static void main(String[] args) {
        // 数据库已有区间:2021-10-01 到 2021-10-30
        DateRange existed = new DateRange(LocalDate.of(2021,10,1), LocalDate.of(2021,10,30), null);
        // 测试Case1:输入2021-10-10到2021-10-20
        DateRange input1 = new DateRange(LocalDate.of(2021,10,10), LocalDate.of(2021,10,20), null);
        System.out.println("Case1输出:");
        splitRange(existed, input1).forEach(System.out::println);
    }
}

场景验证

上述代码可以完美匹配你给出的4个测试场景:

  • Case1:输入区间在原有区间内部,拆分出左段更新、中段新增、右段新增
  • Case2:输入区间左边界和原有区间左边界对齐,拆分出覆盖段更新、右段新增
  • Case3:输入区间完全覆盖原有区间且超出结束时间,直接更新原有区间的结束时间即可
  • Case4:输入区间和原有区间完全不重叠,直接新增

内容的提问来源于stack exchange,提问作者Devi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 16:45:05