Chris_F
Chris_F

Reputation: 93

Compare DateTime objects by their dates

I hope someone can help me that knows Joda Time pretty well. Here is the code:

DateTimeComparator comparator = DateTimeComparator.getInstance(
    DateTimeFieldType.dayOfMonth(), DateTimeFieldType.year());

java.sql.Date beforeDate = new java.sql.Date(1372910400000L);  // July 4 2013
java.sql.Date nowDate = new java.sql.Date(System.currentTimeMillis());
DateTime beforeDateTime = new DateTime(beforeDate);
DateTime nowDateTime = new DateTime(nowDate);

int result = comparator.compare(nowDateTime, beforeDateTime);
System.out.println(nowDate+" compared to "+beforeDate+" = "+result);
2015-03-15 compared to 2013-07-04 = -1

From the Javadocs API for compare:

Returns: zero if order does not matter, negative value if lhsObj < rhsObj, positive value otherwise.

What am I doing wrong?

Upvotes: 2

Views: 468

Answers (2)

dimo414
dimo414

Reputation: 48804

Given your current code sample, you want to pass null as the upper bound for the DateTimeComparator to properly compare DateTime objects by date:

DateTimeComparator.getInstance(DateTimeFieldType.dayOfMonth(), null);

This says "Compare DateTime objects on the basis of the day of the month, and everything broader than that, treating more precise fields like time as equal".


But really, this isn't what you want to do with JodaTime at all. JodaTime provides a number of different date and time classes for different operations, and if your goal is to compare dates, you want to use LocalDate. Its .compareTo() works exactly as you'd expect:

new LocalDate().compareTo(new LocalDate(2013,7,4)) // returns 1

Notice that java.sql.Date only stores date information, not time or timezone information. By constructing a DateTime object, you artificially associate a time and timezone with what was just a date. java.sql.Date's proper sibling in Joda-Time is LocalDate.

When you care about dates, use LocalDate, when you care about times, use LocalTime, when you care about times on a given day, use LocalDateTime. What these classes all have in common is they represent our abstract notions of time, not an instant in history. This might seem strange, but it's often what you really want. The key-concepts documentation on partials goes into some detail about this.

Only when you actually need to talk about instants in real-time should you use DateTime and its related classes. This is actually not as common as you might think with date/time-heavy code. Start with the Local* classes, and see if they can fulfill your use case.

Upvotes: 2

mazaneicha
mazaneicha

Reputation: 9427

It looks like you're excluding the year from comparison, which makes it 03/15 is less than 07/04.
From getInstance(DateTimeFieldType lowerLimit,DateTimeFieldType upperLimit)

Returns a DateTimeComparator with a lower and upper limit. Fields of a magnitude less than the lower limit are excluded from comparisons. Fields of a magnitude greater than or equal to the upper limit are also excluded from comparisons. Either limit may be specified as null, which indicates an unbounded limit.

Upvotes: 2

Related Questions