Dates are messy things, full of complicated edge cases and surprising ways for our assumptions to fail. They lack the pure mathematical beauty of other data types, like integers. But that absence doesn't mean we can't apply the beautiful, concise, and simple tools of functional programming to handling dates.
I mean, you or I could. J Banana's co-worker seems to struggle a bit with it.
/**
* compare two dates, rounding them to the day
*/
private static int compareDates( LocalDateTime date1, LocalDateTime date2 ) {
List<BiFunction<LocalDateTime,LocalDateTime,Integer>> criterias = Arrays.asList(
(d1,d2) -> d1.getYear() - d2.getYear(),
(d1,d2) -> d1.getMonthValue() - d2.getMonthValue(),
(d1,d2) -> d1.getDayOfMonth() - d2.getDayOfMonth()
);
return criterias.stream()
.map( f -> f.apply(date1, date2) )
.filter( r -> r != 0 )
.findFirst()
.orElse( 0 );
}
This Java code creates a list containing three Java functions. Each function will take two dates and returns an integer. It then stream
s that list, applying each function in turn to a pair of dates. It then filters through the list of resulting integers for the first non-zero value, and failing that, returns just zero.
Why three functions? Well, because we have to check the year, the month, and the day. Obviously. The goal here is to return a negative value if date1
preceeds date2
, zero if they're equal, and positive if date1
is later. And on this metric… it does work. That it works is what makes me hate it, honestly. This not only shouldn't work, but it should make the compiler so angry that the computer gets up and walks away until you've thought about what you've done.
Our submitter replaced all of this with a simple:
return date1.toLocalDate().compareTo( date2.toLocalDate() );

This post originally appeared on The Daily WTF.