【问题标题】:DateTimeComparator behavior inconsistent with its javadocDateTimeComparator 行为与其 javadoc 不一致
【发布时间】:2016-05-20 05:10:40
【问题描述】:

我只想比较两个 org.joda.time.DateTime 值的日期,所以我使用了 DateTimeComparator.getDateOnlyInstance() - 但我看到了一些与其 javadoc 不匹配的行为。我想知道这里是否有人可以解释一下。 javadoc of DateTimeComparator 的参数和返回值如下:

Parameters:
    lhsObj - the first object, logically on the left of a < comparison, null means now
    rhsObj - the second object, logically on the right of a < comparison, null means now
Returns:
    zero if order does not matter, negative value if lhsObj < rhsObj, positive value otherwise.

问题1:为什么返回zero if order does not matter。在Comparator interface's javadoc 中定义的此方法的合同规定返回值应为a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second。 (我突然想到order does not matter可能是作者说对象相等的方式,但这是一种令人困惑的说法。)

问题 2:考虑以下代码及其输出:

public static void main(String[] args) {
    DateTime nowUTC = DateTime.now(DateTimeZone.UTC);
    int comparisonResult = DateTimeComparator.getDateOnlyInstance().compare(null, nowUTC);
    System.out.println("comparisonResult = " + comparisonResult);
}

输出(请记住,null 表示现在,并且只需要比较日期):

comparisonResult = -1

=== 阅读第一个答案和更多实验后的附加信息:

同意null 的意思是“现在处于默认系统时区”,但是如果您比较DateTime.now(DateTimeZone.UTC)null 的整个日期时间值,它们是相同的(请参阅下面的附加代码)。这对我来说似乎是正确的,因为任何时区的 now 都是同一时刻。但是,各个字段可能不同。因此,昨天,我仅在 UTC 和 PST(我的默认系统时区)中的日期不同时才比较日期,我得到了预期的结果 = 1,因为 UTC 中的日期更大。此时,虽然两个区域的日期相同,但比较器似乎说 UTC 的日期小于 PST 的日期,这是不可能的。

测试代码:

public static void main(String[] args) {

System.out.println("Printing DateTime.now(DateTimeZone.UTC), and (DateTime)null using formatter.withZoneUTC()");
System.out.println("\tDateTime.now(DateTimeZone.UTC)\t= " +
        DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss-z").withZoneUTC().print(DateTime.now(DateTimeZone.UTC)));
System.out.println("\t(DateTime)null\t\t\t= " +
        DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss-z").withZoneUTC().print((DateTime)null));
System.out.println();

System.out.println("Printing (DateTime)null using formatter with default timezone");
System.out.println("\t(DateTime)null\t\t\t= " + DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ss-z").print((DateTime)null));
System.out.println();

System.out.println("Comparing date only of DateTime.now(DateTimeZone.UTC) (LHS) and null (RHS)");
int dateOnlyComparisonResult = DateTimeComparator.getDateOnlyInstance().compare(DateTime.now(DateTimeZone.UTC), null);
System.out.println("\tdateOnlyComparisonResult\t= " + dateOnlyComparisonResult);
System.out.println();

System.out.println("Comparing entire date time value of DateTime.now(DateTimeZone.UTC) and null");
int instantComparisonResult = DateTimeComparator.getInstance().compare(DateTime.now(DateTimeZone.UTC), null);
System.out.println("\tinstantComparisonResult\t\t=  " + instantComparisonResult);

}

输出:

Printing DateTime.now(DateTimeZone.UTC), and (DateTime)null using formatter.withZoneUTC()
    DateTime.now(DateTimeZone.UTC)  = 2016-02-11T19:26:07-UTC
    (DateTime)null          = 2016-02-11T19:26:08-UTC

Printing (DateTime)null using formatter with default timezone
    (DateTime)null          = 2016-02-11T11:26:08-PST

Comparing date only of DateTime.now(DateTimeZone.UTC) (LHS) and null (RHS)
    dateOnlyComparisonResult    = -1

Comparing entire date time value of DateTime.now(DateTimeZone.UTC) and null
    instantComparisonResult     =  0

【问题讨论】:

    标签: jodatime datetime-comparison


    【解决方案1】:

    问题 1 的答案:

    我同意“如果顺序无关紧要为零”这句话令人困惑。最好将其替换为“如果时间对象相等则为零”或类似。您可以在 Joda-Time 的 github-location 上发布问题甚至拉取请求,以建议您喜欢的描述。

    问题 2 的答案:

    Null 值不仅仅意味着现在,而是现在在默认系统时区。所以只有以下代码有效:

    DateTime nowDefaultZone = DateTime.now(DateTimeZone.getDefault());
    int comparisonResult = 
      DateTimeComparator.getDateOnlyInstance().compare(null, nowDefaultZone);
    System.out.println("comparisonResult = " + comparisonResult); // 0
    

    无论如何,我强烈建议不要使用这个空“功能”,而是指定明确的时区引用,因为将 null 解释为与“现在”相关的任何内容本身并不直观。

    【讨论】:

    • 添加了更多代码及其输出。为什么DateTimeComparator.getDateOnlyInstance(obj1,obj2) 认为UTC 的日期小于 PST 的日期,而它们都相同?
    • 我不打算在我的代码中使用 null-“功能”。就在昨天,在调试器中单步执行我的代码时,我看到仅日期比较方法的参数之一无意中为空。因为 null 表示现在而另一个 arg 是 DateTime.now(DateTimeZone.UTC),如果比较返回 0,它会破坏我的代码 - 但它没有返回 0。这让我更深入地研究了这个 null-“功能”。 :-)
    • @AjoyBhatia 是的,Joda-Time 中的 null 处理是邪恶的恕我直言。无论如何,我会稍后再找时间检查您问题的更新部分,看看 Joda-Time 是否存在错误。感谢您的学习。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-23
    • 2013-09-02
    • 2020-02-28
    • 2022-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多