如何在Java中检查间隔列表(Joda Time)是否完全覆盖一个月
我使用Java中的库来跟踪时间列表。我想检查对象列表是否完全覆盖了一个月的每一分钟。大约有30个时间间隔,从几小时到几天不等 我认为一种便宜的方法是按开始时间对间隔列表进行排序,然后依次检查该月范围内的间隔之间是否有中断。如果是,则该月未完全覆盖 我被困在第一部分,整理名单。我计划使用.sort(),但它需要元素来实现可比较的接口。然而,在查看了源代码之后,Joda Time的Interval类似乎没有一个我可以重写的类,并且我无法扩展它来编写我自己的compareTo方法 除了写我自己的排序方法,还有谁知道一个更简单的方法来完成这个任务?谢谢您可以使用与对时间间隔进行排序,并使用检查间隔。如果开始和结束之间的间隔完全由时间间隔覆盖,则以下代码返回true:如何在Java中检查间隔列表(Joda Time)是否完全覆盖一个月,java,jodatime,Java,Jodatime,我使用Java中的库来跟踪时间列表。我想检查对象列表是否完全覆盖了一个月的每一分钟。大约有30个时间间隔,从几小时到几天不等 我认为一种便宜的方法是按开始时间对间隔列表进行排序,然后依次检查该月范围内的间隔之间是否有中断。如果是,则该月未完全覆盖 我被困在第一部分,整理名单。我计划使用.sort(),但它需要元素来实现可比较的接口。然而,在查看了源代码之后,Joda Time的Interval类似乎没有一个我可以重写的类,并且我无法扩展它来编写我自己的compareTo方法 除了写我自己的排序方
public static boolean isCovered(List<Interval> timeIntervals, DateTime start, DateTime end) {
if (timeIntervals.isEmpty()) {
return false;
}
// create sorted set from original List to get
// sorted intervals without double entries
Set<Interval> intervalSet = new TreeSet<>(new Comparator<Interval>() {
@Override
public int compare(Interval o1, Interval o2) {
return o1.getStart().compareTo(o2.getStart());
}
});
intervalSet.addAll(timeIntervals);
List<Interval> intervals = new ArrayList<>(intervalSet);
// remove intervals completely contained in others
List<Interval> removedIntervals = new ArrayList<>();
for (int i = 0; i < (intervals.size()-1); i++) {
for (int j = (i+1); j < intervals.size(); j++) {
if (intervals.get(i).contains(intervals.get(j))) {
if (!removedIntervals.contains(intervals.get(j))) {
removedIntervals.add(intervals.get(j));
}
}
}
}
intervals.removeAll(removedIntervals);
if (intervals.get(0).getStart().isAfter(start) ||
intervals.get(intervals.size() - 1).getEnd().isBefore(end)) {
return false;
}
// check for gaps
for (int i = 0; i < (intervals.size() - 1); i++) {
Interval gap = intervals.get(i).gap(intervals.get(i+1));
if (gap != null && new Interval(start, end).overlaps(gap)) {
// gap detected between interval i and interval (i+1)
return false;
}
}
return true;
}
发现公共静态布尔值(列出时间间隔、日期时间开始、日期时间结束){
if(timeinterval.isEmpty()){
返回false;
}
//从原始列表创建排序集以获取
//无双条目的已排序区间
Set intervalSet=新树集(新比较器(){
@凌驾
公共整数比较(区间o1、区间o2){
返回o1.getStart().compareTo(o2.getStart());
}
});
intervalSet.addAll(时间间隔);
列表间隔=新的ArrayList(intervalSet);
//删除其他文件中完全包含的间隔
List RemovedInterval=新建ArrayList();
对于(int i=0;i<(interval.size()-1);i++){
对于(intj=(i+1);j静态布尔覆盖(间隔月,列出间隔)
{
//假设间隔已按开始时间排序
最终可变间隔月数=新可变间隔月数;
开始:用于(最终间隔:间隔)
{
if(interval.getStartMillis()monthInterval.getStartMillis())
{
if(interval.getEndMillis()>monthInterval.getEndMillis())
{
返回true;
}
monthInterval.setStartMillis(interval.getEndMillis());
//continue start;//循环将继续
}否则{
if(间隔重叠(月))返回false;
}
}
返回monthInterval.getStartMillis()==monthInterval.getEndMillis();
}
示例
static final List<Interval> intervals = new ArrayList<Interval>();
static
{
intervals.add(new Interval(new DateTime(1990, 05, 15, 00, 00, 00, 00), new DateTime(1990, 05, 18, 00, 00, 00, 00)));
intervals.add(new Interval(new DateTime(1990, 04, 28, 00, 00, 00, 00), new DateTime(1990, 05, 18, 00, 00, 00, 00)));
intervals.add(new Interval(new DateTime(1990, 05, 17, 00, 00, 00, 00), new DateTime(1990, 05, 21, 00, 00, 00, 00)));
intervals.add(new Interval(new DateTime(1990, 05, 21, 00, 00, 00, 00), new DateTime(1990, 05, 29, 00, 00, 00, 00)));
intervals.add(new Interval(new DateTime(1990, 05, 22, 00, 00, 00, 00), new DateTime(1990, 05, 25, 00, 00, 00, 00)));
intervals.add(new Interval(new DateTime(1990, 05, 27, 00, 00, 00, 00), new DateTime(1990, 06, 02, 00, 00, 00, 00)));
}
public static void main(String[] args)
{
final DateTime startOfMonth = new DateTime(1990, 05, 01, 00, 00);
final Interval monthInterval = new Interval(startOfMonth, startOfMonth.plusMonths(1));
covers(monthInterval, intervals);
}
static boolean covers(Interval month, List<Interval> intervals)
{
final MutableInterval monthInterval = new MutableInterval(month);
start: for (final Interval interval : intervals)
{
if (interval.getStartMillis() <= monthInterval.getStartMillis()
&& interval.getEndMillis() > monthInterval.getStartMillis())
{
if (interval.getEndMillis() > monthInterval.getStartMillis())
{
return true;
}
monthInterval.setStartMillis(interval.getEndMillis());
continue start;
}
}
return monthInterval.getStartMillis()== monthInterval.getEndMillis();
}
static final List interval=new ArrayList();
静止的
{
添加(新间隔(新日期时间(1990,05,15,00,00,00,00,00),新日期时间(1990,05,18,00,00,00,00,00,00));
添加(新时间间隔(新日期时间(1990,04,28,00,00,00,00),新日期时间(1990,05,18,00,00,00,00,00,00));
添加(新间隔(新日期时间(1990,05,17,00,00,00,00,00),新日期时间(1990,05,21,00,00,00,00,00));
添加(新的间隔(新的日期时间(1990,05,21,00,00,00,00),新的日期时间(1990,05,29,00,00,00,00,00));
添加(新间隔(新日期时间(1990,05,22,00,00,00,00,00),新日期时间(1990,05,25,00,00,00,00,00));
添加(新间隔(新日期时间(1990,05,27,00,00,00,00,00),新日期时间(1990,06,02,00,00,00,00));
}
公共静态void main(字符串[]args)
{
final DateTime startOfMonth=新日期时间(1990,05,01,00,00);
最终间隔monthInterval=新间隔(startOfMonth,startOfMonth.plusMonth(1));
封面(月底、间隔);
}
静态布尔覆盖(间隔月、列表间隔)
{
最终可变间隔月数=新可变间隔月数;
开始:用于(最终间隔:间隔)
{
if(interval.getStartMillis()monthInterval.getStartMillis())
{
if(interval.getEndMillis()>monthInterval.getStartMillis())
{
返回true;
}
monthInterval.setStartMillis(interval.getEndMillis());
继续启动;
}
}
返回monthInterval.getStartMillis()==monthInterval.getEndMillis();
}
还有一个问题我不能用评论的形式来描述)@Ilya好的,你能用文字表达吗?如果有错误,我想知道,以便更正;)间隔:1)3-10,2)4-5,3)6-11。2和3之间有一个间隙,因此这将返回false
@Ilya您是对的,谢谢您指出这一点。我会解决它。因为你有单循环,你不需要这个标志继续。我使这个解决方案在使用Katja的建议对间隔进行初始排序后工作。否则,该alg无法判断间隙在哪里。然后在第一个if语句失败时返回false,因为它将指示上一个间隔和当前间隔之间的间隔。谢谢你的帮助!