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

Java基于时间范围判断有效数据 如何获取指定日期的属性有效值

Java基于时间范围的属性有效值查询最优实现方案

以下方案同时覆盖数据库查询、Java内存查询两类使用场景,可根据实际业务选择。


场景1:仅含生效起始日(valid_from)的表结构

匹配规则

同属性名下,生效起始日小于等于查询日期的所有记录中,生效起始日最大的记录即为有效值。
以示例为例,2021-06-13查询时,符合条件的生效日为2020-01-01、2021-02-02,取最大的2021-02-02对应的值41,123。

SQL查询实现(数据存储在关系型数据库时优先用该方案)

假设表名为attribute_validity,字段为attr_name(属性名)、value(属性值)、valid_from(生效起始日,日期类型):

SELECT value 
FROM attribute_validity 
WHERE attr_name = 'attr1' 
  AND valid_from <= '2021-06-13'
ORDER BY valid_from DESC
LIMIT 1;

Java内存查询实现(配置类数据已加载到内存时使用)

// 实体类定义
public class AttrValidity {
    private String attrName;
    private String value;
    private LocalDate validFrom;
    // 省略getter、setter、构造方法
}

// 查询逻辑
public Optional<String> getValidValueOnlyFrom(String attrName, LocalDate queryDate, List<AttrValidity> allRecords) {
    return allRecords.stream()
            .filter(record -> attrName.equals(record.getAttrName()))
            // 过滤生效日晚于查询日期的记录
            .filter(record -> !record.getValidFrom().isAfter(queryDate))
            // 取生效日最大的记录
            .max(Comparator.comparing(AttrValidity::getValidFrom))
            .map(AttrValidity::getValue);
}

场景2:同时含生效起始日(valid_from)、生效截止日(valid_to)的表结构

匹配规则

同属性名下,满足 valid_from <= 查询日期 < valid_to(左闭右开规则,避免时间段边界冲突)的记录即为有效值。
以示例为例,2021-06-13查询时,41,123的截止日为2021-04-02,早于查询日期不符合条件,最终取符合区间的41。

SQL查询实现

SELECT value 
FROM attribute_validity 
WHERE attr_name = 'attr1' 
  AND valid_from <= '2021-06-13'
  AND valid_to > '2021-06-13'
-- 若存在脏数据导致多条符合,加排序取最新生效的,避免返回异常
ORDER BY valid_from DESC
LIMIT 1;

Java内存查询实现

// 扩展实体类
public class AttrValidityRange extends AttrValidity {
    private LocalDate validTo;
    // 省略getter、setter、构造方法
}

// 查询逻辑
public Optional<String> getValidValueWithRange(String attrName, LocalDate queryDate, List<AttrValidityRange> allRecords) {
    return allRecords.stream()
            .filter(record -> attrName.equals(record.getAttrName()))
            .filter(record -> !record.getValidFrom().isAfter(queryDate))
            .filter(record -> record.getValidTo().isAfter(queryDate))
            // 兼容脏数据,多匹配结果时取最新生效的
            .max(Comparator.comparing(AttrValidityRange::getValidFrom))
            .map(AttrValidityRange::getValue);
}

通用优化建议

  • 时间字段统一用数据库原生日期类型、JavaLocalDate/LocalDateTime类型存储,不要用字符串,避免格式转换错误
  • 永久生效的记录统一用2100-01-01这类远日期作为valid_to值,不要用null,减少空判断逻辑,查询更统一
  • 高频内存查询场景可提前将同属性的记录按valid_from排序,用二分查找替代遍历,性能提升10倍以上
  • 场景2的数据入库前要校验时间段不可重叠,避免查询出现多匹配结果的异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 10:27:07