我有一个自定义范围(〜Collection),它具有2个Temporal界限(fromto),并且可以通过增加给定的TemporalUnit incrementUnitType来枚举这2个界限之间的所有值。

private final Temporal_ from;
private final Temporal_ to;
private final TemporalUnit incrementUnitType; // For example Month, Day,  Minute, ...

在其中,我需要实现一个contains方法,以检查在该范围内进行迭代是否将包含特定值。例如,如果包含3月8日。这是我想编写该方法的方式:
public boolean contains(Temporal_ value) {
    ...
    if (from.until(value, incrementUnitType) < 0
            || value.until(to, incrementUnitType) <= 0) {
        return false; // Out of bounds
    }
    // This doesn't work because 1-MAR + 1 month doesn't include 8-MAR
    return true;
}

这里有一些迭代:
  • 从-到(incrementUnitType)
  • 1-MAR-10-APR(1天): 1-MAR,2-MAR,3-MAR,4-MAR,...,8-APR,9-APR
  • 1月-10月4日(1周):1月,8月,8月,15月,22月,29月,5月5日
  • 1月-10月4日(1个月):1-MAR,1-APR

  • 在最后一种情况下,上面的代码对于8-MAR将错误地返回true。这是我需要通过执行for循环并检查所有可能的值来编写该代码的方法:
    public boolean contains(Temporal_ value) {
        ...
        if (from.until(value, incrementUnitType) < 0
                || value.until(to, incrementUnitType) <= 0) {
            return false; // Out of bounds
        }
        // This works but it kills scalability
        for (long i = 0; i < getSize(); i++) {
            Temporal_ temporal = get(i);
            if (value.equals(temporal)) {
                return true;
            }
        }
        return false;
    }
    

    那是一个可扩展性问题。有什么办法可以避免这种情况吗?

    最佳答案

    您可以使用Temporal.until方法获取结果。当它返回“两个时态之间的完整单位数”(doc)时,您可以将此数字添加到from中,以查看它是否等于该值,但这不能立即生效。

    long wholeAmount = from.until(value, incrementUnitType)
    return value.equals(from.plus(wholeAmount, incrementUnitType));
    

    正如您所注意到的,问题在于某些时间单位的持续时间并不总是相同的(例如,一个月可能是28、29、30或31天)。 untilplus可能不一致(即我们添加一个月后temporal.until(temporal.plus(1,ChronoUnit.MONTHS),ChronoUnit.MONTHS)可能为0)。

    引用doc:

    在某些情况下,尚未完全定义更改字段。例如,如果
    目标对象是代表1月31日的日期,然后添加
    一个月还不清楚。在这种情况下,该字段为
    负责解决结果。通常,它将选择
    上一个有效日期,这是2月的最后一个有效日期
    这个例子。

    这意味着我们也应该检查wholeAmount + 1,以防万一整个数字被四舍五入。
    // ... out of bound check
    // ...
    long wholeAmount = from.until(value, incrementUnitType)
    return value.equals(from.plus(wholeAmount, incrementUnitType)) || value.equals(from.plus(wholeAmount + 1, incrementUnitType));
    

    处理Temporal似乎很棘手,因此我无法确定它是否适用于每个单位和每个时态(请确保检查递增单位类型是否与您的时态兼容)。可能有几种边缘情况应该进行测试。

    10-06 02:34