[英]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.