Java 将日期与 JUnit 测试进行比较

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21585892/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:30:54  来源:igfitidea点击:

Comparing dates with JUnit testing

javadatejunitcalendar

提问by user3276602

Hello I'm new to the site and have a issue with my application using JUnit testing. My issue is when I try to compare the Date method with itself it always fails. I printed the Date object in the test to see the problem and always end up with the package name and random letters. Here is the Date constructor:

您好,我是该站点的新手,我的应用程序使用 JUnit 测试时遇到问题。我的问题是当我尝试将 Date 方法与其自身进行比较时,它总是失败。我在测试中打印了 Date 对象以查看问题,并且总是以包名称和随机字母结束。这是日期构造函数:

public class Date
{
SimpleDateFormat dformat = new SimpleDateFormat("dd-MM-yyyy");

private int day;
private int month;
private int year;

public Date() 
{
    String today;
    Calendar present = Calendar.getInstance();

    day = present.get(Calendar.DAY_OF_MONTH);
    month = present.get(Calendar.MONTH);
    year = present.get(Calendar.YEAR);

    present.setLenient(false);
    present.set(year, month - 1, day, 0, 0);

    today = dformat.format(present.getTime());
    System.out.println(today);
}

Here is my test:

这是我的测试:

@Test 
public void currentDay()
{
    Date current = new Date();
    System.out.println(current);
    assertEquals("today:", current, new Date());
}

Yet the result always fails and I get something on the lines of:

然而结果总是失败,我得到了一些关于:

comp.work.wk.Date@d3ade7

Any help would be appreciated.

任何帮助,将不胜感激。

采纳答案by Srikanth Ganji

The default equals object compares memory locations. If both objects are pointing to same memory location then only it will print equals which is not the case in your program. since they are pointing to two different memory locations it is always giving false which is expected.

默认等于对象比较内存位置。如果两个对象都指向相同的内存位置,那么它只会打印 equals,这在您的程序中并非如此。因为它们指向两个不同的内存位置,所以总是给出预期的 false。

If you feel your assertEquals(date1,date2) method should return true since the contents are equal then you should override the equals method. And when ever you override equals you should override hashcode() method also to ensure that you can confidently use your class instance as a key in any hashing based collection like HashMap or HashSet.

如果你觉得你的 assertEquals(date1,date2) 方法应该返回 true 因为内容是相等的,那么你应该覆盖 equals 方法。并且当您覆盖 equals 时,您还应该覆盖 hashcode() 方法,以确保您可以放心地将您的类实例用作任何基于散列的集合(如 HashMap 或 HashSet)中的键。

Here is a link explaining how to override equals() and hashcode() method

这是一个解释如何覆盖 equals() 和 hashcode() 方法的链接

http://javarevisited.blogspot.in/2011/02/how-to-write-equals-method-in-java.html

http://javarevisited.blogspot.in/2011/02/how-to-write-equals-method-in-java.html

And don't name your class same as any API class as Jon Skeet suggested.

并且不要像 Jon Skeet 建议的那样将您的类命名为与任何 API 类相同的名称。

Hope this helps.

希望这可以帮助。

回答by Thom

You need to override both equals() and toString(). If you override equals, always override hashcode() so that you're maps work properly.

您需要覆盖 equals() 和 toString()。如果您覆盖 equals,请始终覆盖 hashcode() 以便您的地图正常工作。

回答by Basil Bourque

UpdateThe Joda-Time project is now in maintenance mode, with the team recommending migration to the java.time classes.

更新Joda-Time 项目现在处于维护模式,团队建议迁移到 java.time 类。



This kind of work is much easier with the Joda-Timelibrary instead of the notoriously troublesome Date/Calendar classes.

使用Joda-Time库而不是臭名昭著的日期/日历类,这种工作要容易得多。

Example Code in Joda-Time 2.3

Joda-Time 2.3 中的示例代码

Set up some data…

设置一些数据…

DateTime now = new DateTime();
DateTime yesterday = now.minusDays( 1 );
DateTime nowAgain = new DateTime( now.toString() ); // New object, but same value inside.

Compare…

相比…

boolean isNowEqualToYesterday = now.equals( yesterday );
boolean isNowEqualToNowAgain = now.equals( nowAgain );

Dump to console…

转储到控制台...

System.out.println( "now: " + now );
System.out.println( "yesterday: " + yesterday );
System.out.println( "nowAgain: " + nowAgain );

System.out.println( "isNowEqualToYesterday: " + isNowEqualToYesterday );
System.out.println( "isNowEqualToNowAgain: " + isNowEqualToNowAgain );

When run…

运行时…

now: 2014-02-06T01:31:43.157-08:00
yesterday: 2014-02-05T01:31:43.157-08:00
nowAgain: 2014-02-06T01:31:43.157-08:00
isNowEqualToYesterday: false
isNowEqualToNowAgain: true

Convert

转变

You can convert in and out of Joda-Time if need be.

如果需要,您可以在 Joda-Time 内外进行转换。

org.joda.time.DateTime dateTime = new DateTime( date ); // From Date to DateTime.
java.util.Date date = dateTime.toDate();  // From DateTime to Date.

回答by Hans Wouters

Although the answer by @Shrikanth solves it, this issue also arises with normal Date objects. Two possible solutions are given here:

尽管@Shrikanth 的回答解决了这个问题,但普通 Date 对象也会出现这个问题。这里给出两种可能的解决方案:

  1. Make use of DateUtils.truncate (or even DateUtils.truncatedEquals) to compare the dates. This is something you could use in your equals method, or for normal Date objects directly in you assertEquals/assertTrue.

    assertEquals(DateUtils.truncate(date1,Calendar.SECOND), 
                 DateUtils.truncate(date2,Calendar.SECOND));
    
  2. Don't check whether the dates are the same, but whether they are close enough to eachother (for JUnit test sake):

    assertTrue("Dates aren't close enough to each other!", 
               Math.abs(date2.getTime() - date1.getTime()) < 1000);
    
  1. 利用 DateUtils.truncate(甚至 DateUtils.truncatedEquals)来比较日期。这是你可以在你的 equals 方法中使用的东西,或者直接在你的 assertEquals/assertTrue 中用于普通的 Date 对象。

    assertEquals(DateUtils.truncate(date1,Calendar.SECOND), 
                 DateUtils.truncate(date2,Calendar.SECOND));
    
  2. 不要检查日期是否相同,而是检查它们是否彼此足够接近(为了 JUnit 测试):

    assertTrue("Dates aren't close enough to each other!", 
               Math.abs(date2.getTime() - date1.getTime()) < 1000);
    

回答by Karthik Kota

Overriding default equals method is not necessary. You simply use Date.compareTo()to compare two date objects.

不需要覆盖默认的 equals 方法。您只需使用Date.compareTo()来比较两个日期对象。