首页 > 解决方案 > 将日期与 Arraylist 中的下一个对象日期进行比较未按预期工作

问题描述

我有一个记录列表,其中每条记录都有日期对象。我正在检查第一条记录的日期是否应该早于第二条记录,第二条记录的日期应该小于第三条记录等等。这是我的代码..

for(int i = 0; i < machines.size(); i++) {
        for(int j = i + 1; j < machines.size(); j++) {

            if((machines.get(j).getStrt_Dt().compareTo(machines.get(i).getStrt_Dt()) 
                    * machines.get(i).getStrt_Dt().compareTo(machines.get(j).getStrt_Dt()) >= 0)
                ||
                (machines.get(j).getStrt_Dt().compareTo(machines.get(i).getStrt_Dt()) 
                        * machines.get(i).getStrt_Dt().compareTo(machines.get(j).getStrt_Dt()) >= 0)) {

                throw new Exception("Dates are not as per criteria..");

            }

        }
    }

我来自数据库的日期是:

  STRT_DT    END_DT
 ---------- ----------     
 2014-01-01 2014-12-31
 2013-01-01 2013-02-01 (Here the second record is having the date less than first record), this should fail 
 2016-01-01 2016-12-31
 2017-01-01 2017-12-31
 2018-01-01 2018-02-01

我错过了什么吗?任何帮助将不胜感激..

标签: javadate

解决方案


你太复杂了。检查成对条目就足够了,因为如果 a < b 的顺序正确且 b < c 的顺序正确,那么您已经知道 a < c 的顺序也正确。

for(int i = 0; i < machines.size() - 1; i++) {
    if (! machines.get(i).getEnd_Dt().before(machines.get(i + 1).getStrt_Dt())) {
        throw new IllegalStateException("Dates are not in chronological order");
    }
}

我用“not before”来表示“on or after”。或者换句话说,我要求每个开始日期严格在下一个开始日期之前,如果没有,我会抛出异常。编辑:我不知道如何从您的对象类型中获取结束日期,所以请在我写的地方替换正确的 getter 调用getEnd_Dt()

如果您还需要检查每台机器的开始日期和结束日期是否按正确的顺序排列(使用增强for循环):

for (Machine m : machines) {
    if (m.getEnd_Dt().before(m.getStrt_Dt())) {
        throw new IllegalStateException("Dates are not in chronological order");
    }
}

顺便说一句,Java 命名约定不在名称中使用下划线(a 除外CONSTANT_NAME),因此更getStrtDt喜欢getStrt_Dt. 甚至更好,getStartDate.

也就是说,Embid123 是正确的,你应该看看你是否可以替换DateLocalDate. 该类Date存在设计问题并且早已过时。尽管它的名字它并不代表一个日期,而是一个时间点。LocalDate是 java.time 的一部分,它是现代 Java 日期和时间 API,使用起来更方便。

您需要的另一件事是让您的数据库查询按开始日期对条目进行排序,然后您知道您以正确的顺序获取它们。

你的代码出了什么问题?

首先,您的代码在不可读的边界上很复杂。

接下来,当两个条目ij开始日期顺序错误时,即j日期早于i日期,machines.get(j).getStrt_Dt().compareTo(machines.get(i).getStrt_Dt())则为负数和machines.get(i).getStrt_Dt().compareTo(machines.get(j).getStrt_Dt()正数。真的是一样的比较,只是颠倒了。所以产品将是负面的,你的>= 0条件将是错误的,你不会抛出异常。

只有当两个条目具有完全相同的日期(精确到毫秒)时,才compareTo返回 0,乘积为 0,>= 0才会为真并且您的异常将被抛出。


推荐阅读