簡體   English   中英

列表中日期的創建期間是連續的(它們之間相差一天)

[英]Create periods for dates are consecutive (one day of difference between them) in list

我遇到了一個我不知道如何解決的問題。

我有一個包含日期的列表,如下代碼:

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對象。

我被這個困擾了很長時間。 到目前為止,我還沒有為此案提供很好的支持。

我假設開始日期和結束日期的條件是“日期是連續的(它們之間相差一天)” ,並且當它們不連續時,則又開始了一個時期。 我還假設根據您的輸入,日期列表已經排序。

首先,您可以將代碼更改為使用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完成。 然后,我們比較日期以查看它們是否連續-使用准則“它們之間的差異是一天或更多” -我正在使用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);
}

由於我假設了很多事情,因此您必須根據自己的條件進行調整。

如果仍然需要使用java.util.Date ,則可以對其進行轉換: 將java.time.LocalDate轉換為java.util.Date類型

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM