如何在Java中列出一系列非连续日期中的缺失日期?

时间:2008-12-07 14:57:48

标签: java datetime

我有一个按日期排序的数据表,用户可以通过提供开始和结束日期来选择一组数据。数据本身是不连续的,因为我没有周末和公众假期的数据。

我希望能够在提取的数据集中列出我没有数据的所有日子。在Java中,有一种简单的方法可以去:

  1. 这是一个有序的日期数组。
  2. 这是选定的开始日期。 (数组中的第一个日期并不总是开始日期)
  3. 这是选定的结束日期。 (数组中的最后一个日期并不总是结束日期)
  4. 返回没有数据的日期列表。

4 个答案:

答案 0 :(得分:2)

您可以根据需要创建临时列表和x。

(不是真正的Java。抱歉,我对它的记忆太可怕了。)

dates = [...]; // list you have now;

// build list
unused = [];
for (Date i = startdate; i < enddate; i += day) {
    unused.push(i);
}

// remove used dates
for (int j = 0; j < dates.length; j += 1) {
    if (unused.indexOf((Date) dates[j]) > -1) { // time = 00:00:00
        unused.remove(unused.indexOf((Date) dates[j]));
    }
}

答案 1 :(得分:1)

您应该能够创建一个提供此功能的过滤迭代器。也许让迭代器的方法接受子集合的开始和结束日期。至于迭代器的实际实现,一旦找到start元素,我就不会想到比整个集合中的暴力运行更优雅的东西。

答案 2 :(得分:0)

您可以创建开始日期和结束日期之间所有可能日期的列表,然后删除显示在给定数据列表中的日期(在大多数日期丢失时效果最佳),或者您可以从空白日期列表开始并添加未出现在给定数据中的那些。

无论哪种方式,您基本上都会迭代开始日期和结束日期之间的日期范围,跟踪您在给定日期列表中的位置。您可以将其视为“类似合并”操作,您可以并行执行两个列表,处理出现在一个列表中但不出现在另一个列表中的记录。在伪代码中,空列表版本可能是:

# given   - array of given dates
# N       - number of dates in given array
# missing - array of dates missing

i = 0;    # Index into given date array
j = 0;    # Index into missing data array
for (current_date = start_date; current_date <= end_date; current_date++)
{
    while (given[i] < current_date && i < N)
        i++
    if (i >= N)
        break
    if (given[i] != current_date)
        missing[j++] = current_date
}
while (current_date < end_date)
{
    missing[j++] = current_date
    current_date++
}

我假设日期类型是以一天为单位量化的;也就是说,date + 1(或date++)是date之后的第二天。

答案 3 :(得分:0)

虽然已经给出的其他答案看起来相当简单和愉快,并且持有一些好主意(我特别同意Nerdfest的Iterator建议),我认为无论如何我都会给出一个镜头并编写一个解决方案来展示我是怎样的我会在第一次迭代时这样做,我确信下面的内容还有改进的余地。

我也许你的要求有点过于字面意思,但你知道如何根据自己的喜好调整代码。哦,抱歉对象的可怕命名。此外,由于此示例使用Calendar,请记住Calendar.roll()在某些情况下可能不会更新整个Calendar对象,因此这是一个潜在的错误。

protected List<Calendar> getDatesWithNoData(Calendar start, Calendar end,
        Calendar[] existingDates) throws ParseException {

    List<Calendar> missingData = new ArrayList<Calendar>();

    for(Calendar c=start ; c.compareTo(end)<=0 ; c.roll(Calendar.DAY_OF_MONTH, true) ) {

        if(!isInDataSet(c, existingDates)) {
            Calendar c2 = Calendar.getInstance();
            c2.setTimeInMillis(c.getTimeInMillis());

            missingData.add(c2);
        }
    }
    return missingData;
}

protected boolean isInDataSet(Calendar toSearch, Calendar[] dataSet) {
    for(Calendar l : dataSet) {
        if(toSearch.equals(l)) return true;
    }
    return false;
}