我有一组[startdate,enddate]间隔,它们可以重叠并包含间隙。 我的目标是建立一个连续的新间隔列表,没有间隙,没有任何重叠日期。
范围示例:
[-----------------------------------A-----------------------]
[-B]
[-C]
[D]
[-----E-----]
[-----F----]
[-----G-----]
A [2009-01-01 - 2014-01-01] ~5 years
B [2009-01-01 - 2009-01-02] 2 days
C [2009-01-02 - 2009-01-03] 2 days
D [2009-01-04 - 2009-01-04] 1 day
E [2010-01-01 - 2011-01-01] ~1 year
F [2011-01-01 - 2012-01-01] ~1 year, a gap after this interval
G [2015-01-01 - 2016-01-01] ~1 year
我期望的是这个新的间隔列表:
[2009-01-01 - 2009-01-01]
[2009-01-02 - 2009-01-02]
[2009-01-03 - 2009-01-03]
[2009-01-04 - 2009-01-04]
[2009-01-05 - 2009-12-31]
[2010-01-01 - 2010-12-31]
[2011-01-01 - 2012-01-01]
[2012-01-02 - 2014-01-01]
[2014-01-02 - 2014-12-31]
[2015-01-01 - 2016-01-01]
因此,对于差距,添加了新的间隔。具有相同开始日期和结束日期的间隔完全有效,应按原样处理。
即使在以有效的方式实现这一目标之前,我仍然坚持实现这一目标的最佳方式:(
有关如何在Java中执行此操作的任何想法?
答案 0 :(得分:2)
您可以尝试我的库range-package的Time4J并使用此代码:
DateInterval a = DateInterval.between(PlainDate.of(2009, 1, 1), PlainDate.of(2014, 1, 1));
DateInterval b = DateInterval.between(PlainDate.of(2009, 1, 1), PlainDate.of(2009, 1, 2));
DateInterval c = DateInterval.between(PlainDate.of(2009, 1, 2), PlainDate.of(2009, 1, 3));
DateInterval d = DateInterval.between(PlainDate.of(2009, 1, 4), PlainDate.of(2009, 1, 4));
DateInterval e = DateInterval.between(PlainDate.of(2010, 1, 1), PlainDate.of(2011, 1, 1));
DateInterval f = DateInterval.between(PlainDate.of(2011, 1, 1), PlainDate.of(2012, 1, 1));
DateInterval g = DateInterval.between(PlainDate.of(2015, 1, 1), PlainDate.of(2016, 1, 1));
List<DateInterval> intervals = Arrays.asList(a, b, c, d, e, f, g);
IntervalCollection<PlainDate> icoll = IntervalCollection.onDateAxis().plus(intervals);
for (ChronoInterval<PlainDate> gap : icoll.withGaps().getIntervals()) {
icoll = icoll.plus(gap);
}
System.out.println(icoll.withSplits());
[2009-01-01/2009-01-01],
[2009-01-02/2009-01-02],
[2009-01-03/2009-01-03],
[2009-01-04/2009-01-04],
[2009-01-05/2009-12-31],
[2010-01-01/2010-12-31],
[2011-01-01/2011-01-01],
[2011-01-02/2012-01-01],
[2012-01-02/2014-01-01],
[2014-01-02/2014-12-31],
[2015-01-01/2016-01-01]
备注您的预期结果:
您的陈述
我的目标是建立一个连续的新间隔列表,没有间隙 没有任何重叠日期。
通过上面的代码实现。在分割之前,间隙作为正常间隔添加到整个间隔集合。默认情况下,Time4J中的所有日期间隔都作为封闭间隔处理(可配置)。这意味着,例如“[2009-01-01 / 2009-01-01]”之类的时间间隔仅包含一天(正如您在预期时间间隔列表的第一个条目中所示)。
但是,您似乎没有期望间隔“[2011-01-01 / 2011-01-01]”,但只是这个日期(仅包含一天的间隔)是间隔E +之间的重叠区域F也应出现在预期的间隔列表中。
关于与Java-8的互操作性:
您还可以在net.time4j.PlainDate
和java.time.LocalDate
类型之间应用toTemporalAccessor()或from(LocalDate)等直接转化方法。
答案 1 :(得分:0)
首先,按开始日期对它们进行排序。
然后迭代它们,并将以下所有内容与下一个进行比较:
如果curr.end >= next.start
则curr.end = next.start - 1
如果curr.end < curr.start
然后将其删除
如果curr.end < next.start - 1
然后添加新的:
new.start = curr.end + 1
new.end = next.start - 1
同时跟踪最大结束日期(更新前),如果max(end) > last.end
,则添加新日期:
new.start = last.end + 1
new.end = max(end)