DateTimeComparator behavior inconsistent with its javadoc

422 Views Asked by At

I wanted to compare only the dates of two org.joda.time.DateTime values, so I was using the DateTimeComparator.getDateOnlyInstance() - but I saw some behavior that does not match with its javadoc. I wonder if someone here can explain that. The javadoc of DateTimeComparator says the following about its parameters and return value:

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.

Question 1: Why does it return zero if order does not matter. The contract of this method as defined in the Comparator interface's javadoc says that the return value should be a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second. (Just occurred to me that order does not matter may be the author's way of saying that the objects are equal, but it is a confusing way to put it.)

Question 2: Consider the following code and its output:

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

The output (Remember that null means now, and only the date should be compared):

comparisonResult = -1

=== Additional info after reading first answer and some more experimenting:

Agreed that null means "now in default system timezone" but if you compare entire date time value of DateTime.now(DateTimeZone.UTC) and null, they are the same (see additional code below). That seems right to me because now in any timezone is the same instant. However, individual fields could be different. So, yesterday, I compared date only when date was different in UTC and PST (my default system timezone), I got the expected result = 1 because date in UTC was greater. At this time, though the dates are the same in both zones, but the comparator seems to say that the date in UTC is less than date in PST, which is never possible.

Test code:

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);

}

Output:

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
1

There are 1 best solutions below

3
On BEST ANSWER

Answer to question 1:

I agree that the phrase "zero if order does not matter" is confusing. It might better be replaced by "zero if temporal objects are equal" or similar. You can post an issue or even a pull request on the github-location of Joda-Time to suggest your preferred description.

Answer to question 2:

Null value does not mean simply now, but now in default system timezone. So only following code works:

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

Anyway, I strongly recommend not to use this null-"feature" but specify explicit timezone references because interpreting null as anything related to "now" is not per se intuitive.