Reputation: 184
How to compare two java.time.format.DateTimeFormatters?
Due to the fact that DateTimeFormatters does not have an overridden 'equals' method.
Test:
import java.time.format.DateTimeFormatter;
DateTimeFormatter.ofPattern("M/dd/yyyy").equals(DateTimeFormatter.ofPattern("M/dd/yyyy"))
Result:
false
This is the behavior of 'Object.equals()' method. Documentation: https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html
Methods inherited from class java.lang.Object clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
Use case when it needed:
For example my method returns DateTimeFormatter. And I would like to create test to verify that returned DateFormatter is correct.
For example:
DateTimeFormatter expectedFormatter = DateTimeFormatter.ofPattern("my custom format")
DateTimeFormatter actualFormatter = someService.getFormatter()
Assert.assertEquals(actualFormatter, expectedFormatter)
Upvotes: 0
Views: 1070
Reputation: 5072
There are ways to obtain the original pattern for comparison.
Since DateTimeFormatter
is a final
class that can't be extended, you could replace all your instances with a wrapper class that creates the instance of DateTimeFormatter
in the constructor and access to the generated DateTimeFormatter
instance and pass around your custom DataTimeFormatterContainer
classes in your code. It's a beast, but it'll do what you are asking.
Of course, this compares exactly the pattern; if two non-identical patterns generate the same result when parsing a date, this will return false.
Barebones proposal; no null checks, accessor methods, or hashcode:
public class DateTimeFormatterContainer() {
public final String pattern;
public final DateTimeFormatter formatter;
public DateTimeFormatterContainer(String pattern) {
this.pattern = pattern;
this.formatter = DateTimeFormatter.ofPattern(pattern);
}
public boolean equals(DateTimeFormatterContainer that) {
return this.pattern.equals(that.pattern);
}
}
Upvotes: 0
Reputation: 44150
Probably because determining equality of a formatter is non-trivial, since there are many ways to construct the "same" formatter (in terms of behaviour) via a builder, and is rarely useful.
The JDK developers have finite time. They prioritise the import things. DateTimeFormatter overriding equals
in a consistent and idiomatic way is much harder than it might seem, they're better off spending time elsewhere.
In any case, it doesn't help you to know why it doesn't exist. That is the situation you are in, and that is not changing any time soon.
My suggestion is to test the behaviour. Construct some date (or date-time) and see whether both formatters produce the same output.
DateTimeFormatter expectedFormatter = DateTimeFormatter.ofPattern("my custom format")
DateTimeFormatter actualFormatter = someService.getFormatter();
LocalDate someFakeDate = LocalDate.of(2020, 1, 1);
Assert.assertEquals(actualFormatter.format(someFakeDate), expectedFormatter.format(someFakeDate));
Upvotes: 4