LocalDate:缺少方法 isEqualOrBefore 和 isEqualOrAfter

Ret*_*ner 0 java java-8 localdate

问题:您如何处理这些用例?

  • 你使用静态辅助方法吗?
  • 你使用冗长的等于后跟 isAfter/isBefore 吗?
  • 你使用否定的相反条件吗?
  • 你使用 3rd 方库助手吗?

在日常业务中,我经常需要检查日期 a <= 日期 b 或日期 a >= 日期 b。

互联网经常建议使用 isBefore/isAfter 方法的否定版本。

在实践中我发现我

  • 几乎从来没有在第一次尝试时就得到这些否定的比较(它们应该是直观和简单的)。
  • 阅读代码时很难理解业务逻辑

我想我的一部分仍然希望我只是忽略了 API 中的相应方法(请!)。

  /**
   * @return true if candidate >= reference </br>
   *         or in other words: <code>candidate.equals(reference) || candidate.isAfter(reference)</code> </br>
   *         or in other words: <code>!candidate.isBefore(reference) </br>
   *         or in other words: <code>candidate.compareTo(reference) >= 0
   */
  public static boolean isEqualOrAfter(LocalDate candidate, LocalDate reference)
  {
    return !candidate.isBefore(reference);
  }

  /**
   * @return true if candidate <= reference </br>
   *         or in other words: <code>candidate.equals(reference) || candidate.isBefore(reference)</code> </br>
   *         or in other words: <code>!candidate.isAfter(reference) </br>
   *         or in other words: <code>candidate.compareTo(reference) <= 0
   */
  public static boolean isEqualOrBefore(LocalDate candidate, LocalDate reference)
  {   
    return !candidate.isAfter(reference);
  }
Run Code Online (Sandbox Code Playgroud)

编辑:正如 Andreas 所建议的,我添加了带有compareTo方法的版本,我希望我做对了(没有测试)。

编辑 2:示例:

// Manager says: "Show me everything from 3 days ago or later" or "show me everything that's at most 3 days old"
for(Item item : items) {
  // negation idiom
  if(!item.getDate().isBefore(LocalDate.now().minusDays(3))) {
    // show
  }

  // compareTo idiom
  if(item.getDate().compareTo(LocalDate.now().minusDays(3)) >= 0) {
    // show
  }

  // desired
  if(item.getDate().isEqualOrAfter(LocalDate.now().minusDays(3))) {
    // show
  }
}
Run Code Online (Sandbox Code Playgroud)

Dar*_*usz 5

你寻求的方法是不必要的。这就是你的做法:

isEqualOrBefore == !isAfter
isEqualOrAfter == !isBefore
Run Code Online (Sandbox Code Playgroud)

  • 看到这正是我强烈不同意的地方(也是安德烈亚斯将这个问题标记为主要基于意见的原因)。我发现这个建议的解决方案不方便,可读性不好,而且很容易出错(根据我的经验)。 (3认同)
  • 我还认为,我寻求这些方法的事实使它们变得必要。 (3认同)
  • 这也适合`&lt;=` 运算符,即`&lt;` 或`=`,也就是before-or-equal。--- 事实上,人们可能会争辩说 `isBefore`、`isEqual` 和 `isAfter` 都是多余的 *(opinion)*,因为所有六个比较运算符都可以使用 `a.compareTo(b) OP 0` 来完成,其中`OP`是`&lt;`、`==`、`&gt;`、`&gt;=`、`!=`或`&lt;=`。见[我的其他评论](http://stackoverflow.com/questions/43932309/localdate-missing-methods-isequalorbefore-and-isequalorafter/43932750?noredirect=1#comment74898134_43932750)。 (2认同)
  • 我已经多次将 `compareTo` 与 `BigDecimal` 结合使用,并且将 `a.compareTo(b) &lt;= 0` 读作 `a &lt;= b` 从来没有遇到过问题。重要的部分是`a`、`b`和`&lt;=`。`compareTo` 和 `0` 只是次要的填充代码,易于阅读。这是您将很快学会识别的标准结构。并不是说你真的需要翻译它才能理解它的意思。`&lt;=` 表示 `&lt;=`。 (2认同)
  • @Dariusz 问题是没有幻数“-1”和“1”。似乎很多人都这么认为,但是 `compareTo()` 返回 `&lt; 0`、`== 0` 或 `&gt; 0`。根据约定,它不会返回 `-1` 或 `1`,尽管许多实现碰巧这样做,但是您**永远不要**依赖它,因为它是*实现*细节,而不是要求,并且将来可能会改变。只有一个幻数,‘0’,对于返回 *sign* 指示符 *(opinion)* 的方法,我不认为这是一种反模式。 (2认同)