如何测试和比较两个 java.time.format.DateTimeFormatter?

huangapple go评论62阅读模式
英文:

How to test and compare two java.time.format.DateTimeFormatter-s?

问题

如何比较两个java.time.format.DateTimeFormatters?

由于DateTimeFormatters没有重写的'equals'方法。

测试:

import java.time.format.DateTimeFormatter;

DateTimeFormatter.ofPattern("M/dd/yyyy").equals(DateTimeFormatter.ofPattern("M/dd/yyyy"))

结果:

false

这是'Object.equals()'方法的行为。
文档:https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

从类java.lang.Object继承的方法:
clone、equals、finalize、getClass、hashCode、notify、notifyAll、wait、wait、wait

需要时的使用案例:

例如,我的方法返回DateTimeFormatter。我想创建一个测试来验证返回的DateFormatter是否正确。

例如:

DateTimeFormatter expectedFormatter = DateTimeFormatter.ofPattern("my custom format");
DateTimeFormatter actualFormatter = someService.getFormatter();
Assert.assertEquals(actualFormatter, expectedFormatter);
英文:

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)

答案1

得分: 4

可能是因为确定格式化程序的相等性并不是一项简单的任务,因为可以通过构建器以多种方式构造与“相同”(在行为方面)的格式化程序,而这很少有用。

JDK 开发人员的时间是有限的。他们会优先考虑重要的事情。以一种一致且惯用的方式覆盖 equals 方法对于 DateTimeFormatter 来说要比看起来的要困难得多,他们最好在其他地方花时间。

无论如何,了解为什么它不存在对你也没有帮助。这就是你所处的境地,短时间内不会有改变。

我的建议是测试行为。构造一些日期(或日期时间),然后查看这两个格式化程序是否产生相同的输出。

DateTimeFormatter expectedFormatter = DateTimeFormatter.ofPattern("我自定义的格式");
DateTimeFormatter actualFormatter = someService.getFormatter();

LocalDate someFakeDate = LocalDate.of(2020, 1, 1);
Assert.assertEquals(actualFormatter.format(someFakeDate), expectedFormatter.format(someFakeDate));
英文:

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

答案2

得分: 0

获取原始模式的方法用于比较。

由于DateTimeFormatter是一个无法扩展的final类,您可以将所有实例替换为一个包装器类,在构造函数中创建DateTimeFormatter实例并访问生成的DateTimeFormatter实例,在代码中传递自定义的DataTimeFormatterContainer类。虽然它有点复杂,但它会实现您的要求。

当然,这会精确比较模式;如果两个非相同的模式在解析日期时生成相同的结果,则会返回false。

基本提案;没有空值检查、访问方法或哈希码:

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);
    }
}
英文:

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

huangapple
  • 本文由 发表于 2020年9月14日 23:43:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/63887606.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定