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
相关产品推荐
相关产品推荐

