【发布时间】:2018-02-19 06:11:47
【问题描述】:
我有一组日期范围,如果任何日期在 Java 中重叠,我需要获取组合日期范围。
给定三组日期范围,如果任何日期与另一个日期范围重叠,则需要合并。
示例:
20170101-20170331
20170101-20170430
20170430-20170501
预期结果是:
20170101-20170430
20170430-20170501
我在字符串变量中有所有日期。可以请任何人帮助我如何编写代码。我已粘贴在我的代码下方。
我想达到预期的效果。我不知道我需要如何修改此代码。我是初学者,请帮助我做到这一点。我从 StackOverflow 获得了这个示例程序。
package com.kkkkk.Combine;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
public class Ideone {
public static void main(String[] args) throws java.lang.Exception {
ArrayList<Interval> x = new ArrayList<>();
x.add(new Interval("20170430", "20170501")); // "20170101", "20170430"
x.add(new Interval("20170101", "20170430"));// 20170101-20170430
x.add(new Interval("20170101", "20170331"));
x = merge(x);
for (Interval i1 : x) {
System.out.println(i1.getStartDate() + " " + i1.getEndDate());
}
}
public static ArrayList<Interval> merge(ArrayList<Interval> intervals) {
if (intervals.size() == 0 || intervals.size() == 1)
return intervals;
ArrayList<Interval> result = new ArrayList<Interval>();
Collections.sort(intervals, new IntervalComparator());
System.out.println("intervals ggggg\n" + intervals + "\n");
Interval first = intervals.get(0);
String start = first.getStartDate();
String end = first.getEndDate();
Date startDateF = null;
Date endDateF = null;
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
startDateF = sdf.parse(start);
endDateF = sdf.parse(end);
// ArrayList<Interval> result = new ArrayList<Interval>();
for (int i = 1; i < intervals.size(); i++) {
Interval current = intervals.get(i);
Date currentEndDate = sdf.parse(current.getEndDate());
Date currentStartDate = sdf.parse(current.getStartDate());
// if ((current.getStartDate().after(endDateF)) ||
Date d1 = minDate(endDateF, currentStartDate);
if ((currentStartDate).compareTo(endDateF) <= 0) {
endDateF = maxDate(currentEndDate, endDateF);
} else {
result.add(new Interval(start, (sdf.format(endDateF))));
// start = current.start;
// end = current.end;
start = sdf.format(currentStartDate);
endDateF = (currentEndDate);
enter code here
}
}
result.add(new Interval(start, end));
// result.add(new Interval(start, (sdf.format(endDateF))));
}
catch (ParseException ex) {
ex.printStackTrace();
}
// result.add(new Interval(start, end));
return result;
// return intervals;
}
public static Date minDate(Date date1, Date date2) {
// if date1 before date2 then return date1 else return date2
return date1.before(date2) ? date1 : date2;
}
/**
* find Max Dates
*
* @param date1
* @param date2
* @return
*/
public static Date maxDate(Date date1, Date date2) {
// if date1 after date2 then return date1 else return date2
System.out.println("date max");
return date1.after(date2) ? date1 : date2;
}
}
【问题讨论】:
-
顺便说一句,我建议您废弃早已过时的课程
Date和SimpleDateFormat。现代 Java 日期和时间 API 要好得多,使用起来也好得多。现代的LocalDate类也非常适合您的需求,而使用Date,您正在拖着一天中的某个时间,而您确实希望避免这种情况。参见例如tutorial by Oracle。 -
进一步建议:您的
Interval类可以保存LocalDate对象而不是字符串(如果您真的坚持,甚至可以保存Date对象)。构造函数仍然可以接受字符串并解析它们。这样,您只需解析字符串一次,而不是每次都需要比较它们(黑客版本将直接比较字符串,因为它们是yyyyMMdd也可以)。 -
查看 ThreeTen-Extra 项目中的
LocalDateRange类。 -
假设你想要半开区间,为什么你不希望你的示例区间为一个区间 [2017-01-01/2017-05-01)习惯于看到封闭的日期间隔)?您应该真正澄清区间边界的状态以及为什么不合并相邻区间(没有间隙!)。
-
是的,你是对的! .我错误地提到了预期的结果。结果应该像一个间隔[2017-01-01/2017-05-01]
标签: java string date intervals localtime