计算时差的Assert失败

lymgl2op  于 2021-07-13  发布在  Java
关注(0)|答案(2)|浏览(510)

我在减法 500 hours 从日历日期和我的方法是给不同的小时。
为什么下面的Assert失败了?
测试方法:

public long dataFetchTotalTime(long time) {
        long hours = 0;
        Calendar ackCal = Calendar.getInstance();
        long diff = ackCal.getTime().getTime() - time;
        hours = TimeUnit.HOURS.convert(diff, TimeUnit.MILLISECONDS);
        return hours;
    }

测试用例:

@Test
public void checkFetchTimeDiff()
{
    long expected = 500;
    Client client = new Client();
    Calendar ackCal = Calendar.getInstance();
    ackCal.set(Calendar.HOUR_OF_DAY, -500);
    long actual = client.dataFetchTotalTime(ackCal.getTime().getTime());
    Assert.assertEquals(expected, actual);
}

错误跟踪:

java.lang.AssertionError: expected:<500> but was:<514>
    at org.junit.Assert.fail(Assert.java:88)
    at org.junit.Assert.failNotEquals(Assert.java:834)
    at org.junit.Assert.assertEquals(Assert.java:645)
    at org.junit.Assert.assertEquals(Assert.java:631)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
pgvzfuti

pgvzfuti1#

这是个错误:

ackCal.set(Calendar.HOUR_OF_DAY, -500);

测试方法:

public long dataFetchTotalTime(long time) {
        long hours = 0;
        Calendar ackCal = Calendar.getInstance();
        long diff = ackCal.getTime().getTime() - time;
        hours = TimeUnit.HOURS.convert(diff, TimeUnit.MILLISECONDS);
        return hours;
    }

测试用例:

@Test
public void checkFetchTimeDiff()
{
    long expected = 500;
    Client client = new Client();
    Calendar ackCal = Calendar.getInstance();
    ackCal.add(Calendar.HOUR_OF_DAY, -500);
    long actual = client.dataFetchTotalTime(ackCal.getTime().getTime());
    Assert.assertEquals(expected, actual);
}
kq4fsx7k

kq4fsx7k2#

热释光;博士

ZonedDateTime now = ZonedDateTime.now( ZoneId.systemDefault() ) ;
System.out.println(
    Duration
    .between(
        now , 
        now.plusHours( 500L ) 
    )
    .toHours()
) ;

请在ideone.com上查看此代码的实时运行。
500

java.time文件

您正在使用可怕的日期时间类,这些类在几年前被jsr310中定义的现代java.time类所取代。

分区日期

这个 Calendar 类,实际上是它常用的子类, GregorianCalendar ,替换为 ZonedDateTime . 这个 ZonedDateTime 类代表一个特定地区的人们通过墙上的时钟看到的时刻。换句话说,一个日期,一天中的某个时间,在一个时区的上下文中。
您可以根据需要进行转换,但最好完全避免遗留的日期时间类。若要转换,请调用添加到旧类中的新方法。

GregorianCalendar gc = ( GregorianCalendar ) myJavaUtilCalendar  ;  // Cast from the more general to the concrete.
ZonedDateTime zdt = gc.toZonedDateTime() ;  // Convert from legacy class to modern class.

要捕获当前时刻,请指定所需的时区。在任何一个特定的时刻,世界各地的日期因地区而异。

ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ;

持续时间

算算吧。表示与时间线无关的时间跨度 Duration 以小时分秒为单位,或 Period 以年、月、日为单位。

Duration d = Duration.ofHours( 500 ) ;
ZonedDateTime zdtLater = zdt.plus( d ) ;

要确定经过的时间,请使用 Duration.between .

Duration elapsed = Duration.between( zdt , zdtLater ) ;

要以标准iso 8601格式查看文本,请调用 toString .

String output = elapsed.toString() ;

要以总小时数的形式查看已用时间,请拨打 Duration::toHours .

long hours = elapsed.toHours() ;

关于java.time

java.time框架内置于Java8及更高版本中。这些类取代了旧的遗留日期时间类,例如 java.util.Date , Calendar , & SimpleDateFormat .
要了解更多信息,请参阅oracle教程。和搜索堆栈溢出的许多例子和解释。规格为jsr 310。
现在处于维护模式的joda time项目建议迁移到java.time类。
您可以直接与数据库交换java.time对象。使用符合jdbc 4.2或更高版本的jdbc驱动程序。不需要线,不需要线 java.sql.* 班级。
从哪里获得java.time类?
JavaSE8、JavaSE9、JavaSE10、JavaSE11及更高版本—标准JavaAPI的一部分,带有捆绑实现。
Java9添加了一些次要的特性和修复。
java se 6和java se 7
大部分java.time功能都是通过三个十个后端口后端口移植到Java6和Java7的。
安卓
android包java.time类的更高版本实现。
对于早期的android(<26),threetenabp项目采用了threeten backport(如上所述)。了解如何使用threetenabp…。
threeten额外的项目用额外的类扩展了java.time。这个项目是java.time将来可能添加的一个试验场。您可以在这里找到一些有用的类,例如 Interval , YearWeek , YearQuarter ,等等。

相关问题