在列表中创建日期的期间是连续的(它们之间的差异的一天)

时间:2018-03-19 12:23:32

标签: java algorithm datetime

我遇到了一个我不知道如何解决的问题。

我有一个包含日期的列表,如下代码所示:

public static void main(String[] args) {
    TreeSet<LocalDate> dates = getDaysBetween("2017-02-01","2017-03-31");
    dates.removeAll(getDaysBetween("2017-01-01","2017-02-01"));
    dates.removeAll(getDaysBetween("2017-03-01","2017-03-04"));
    dates.removeAll(getDaysBetween("2017-03-08","2017-03-08"));
    dates.removeAll(getDaysBetween("2017-03-10","2017-03-12"));
    dates.removeAll(getDaysBetween("2017-03-14","2017-03-16"));
    dates.removeAll(getDaysBetween("2017-03-19","2017-03-19"));
    dates.removeAll(getDaysBetween("2017-03-22","2017-03-22"));
}

public static TreeSet<LocalDate> getDaysBetween(String start, String end){
    DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    LocalDate startDate = LocalDate.parse(start, fmt);
    LocalDate endDate = LocalDate.parse(end, fmt);
    TreeSet<LocalDate> dates = new TreeSet<LocalDate>();
    LocalDate current = startDate;
    while (current.isBefore(endDate) || current.equals(endDate)) {
       dates.add(current);
       current = current.plusDays(1);
    }
    return dates;
 }

 class Period {
     private Date startDate;
     private Date endDate;
 }

开始日期和结束日期的标准是“日期是连续的(它们之间的差异的一天)”,当它们不连续时,则开始另一个时期。

在main方法中,我创建了很多存储在List中的日期,然后从该列表中删除一些日期。使用列表中的左连续日期(它们之间的差异的一天)来创建一个期间,当它们不连续时,则开始另一个期间。

时期如下:

startDate: 2017-02-02, endDate: 2017-02-28
startDate: 2017-03-05, endDate: 2017-03-07
startDate: 2017-03-09, endDate: 2017-03-09
startDate: 2017-03-13, endDate: 2017-03-13
startDate: 2017-03-17, endDate: 2017-03-18
startDate: 2017-03-20, endDate: 2017-03-21
startDate: 2017-03-23, endDate: 2017-03-31

我想根据提供的日期列表创建一个算法来创建这些Period对象。

我被这封了很长时间。到目前为止,我还没有对这个案子提出好感。

1 个答案:

答案 0 :(得分:3)

我假设开始日期和结束日期的标准是&#34;日期是连续的(它们之间有一天差异)&#34; ,以及它们何时#39 ;不是连续的,那么另一个时期已经开始了。我还根据您的输入假设日期列表已经排序。

首先,您可以更改代码以使用java.time API,而不是旧的java.util.Date。如果您使用的是Java 7或更低版​​本,请使用具有相同类别和功能的threenten backport

所以首先要确定你是否关心时间。在您的输入中,所有时间都是午夜。如果这没有什么不同,你可以使用LocalDate,这是一个只关心日,月和年的类。

我假设必须保留当天的时间,因此我使用LocalDateTime(具有日期和时间的课程,因此它与您的输入完全匹配) ):

class Period {
    private LocalDateTime startDate;
    private LocalDateTime endDate;

    // constructor, getters and setters
}

现在我们必须循环遍历列表并将这些字符串转换为LocalDateTime。这可以使用DateTimeFormatter来完成。然后我们比较日期以查看它们是否是连续的 - 使用标准&#34;它们之间的差异是一天或更长时间&#34; - 并且我使用{{ 1}}类来计算差异。

我使用这个日期列表:

ChronoUnit

算法是这样的:

String[] datesList = new String[] {
    "2018-03-01 00:00:00",
    "2018-03-02 00:00:00",
    "2018-03-03 00:00:00",
    "2018-03-04 00:00:00",
    "2018-03-10 00:00:00",
    "2018-03-11 00:00:00",
    "2018-03-12 00:00:00",
    "2018-03-14 00:00:00",
    "2018-03-15 00:00:00",
    "2018-03-16 00:00:00",
    "2018-03-18 00:00:00" };

当我假设很多东西时,你必须根据你的标准进行调整。

如果您仍需要使用List<Period> periodList = new ArrayList<>(); Period p = null; LocalDateTime prev = null; DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); for (String s : datesList) { if (prev == null) { // starting new period prev = LocalDateTime.parse(s, fmt); p = new Period(); p.setStartDate(prev); } else { // in the middle of a period LocalDateTime date = LocalDateTime.parse(s, fmt); // check the difference in days // convert to LocalDate to ignore hours in the comparison if (ChronoUnit.DAYS.between(prev.toLocalDate(), date.toLocalDate()) > 1) { // difference is more than 1 day, period ended p.setEndDate(prev); periodList.add(p); // start new period p = new Period(); p.setStartDate(date); prev = date; } else { prev = date; } } } // check last period if (p != null && p.getEndDate() == null) { p.setEndDate(p.getStartDate()); periodList.add(p); } ,则可以将其转换为:Convert java.time.LocalDate into java.util.Date type