Подсчет разницы в минутах между двумя датами
Лучше использовать java.time.format.DateTimeFormatter
и java.time.LocalDateTime
из нового Java API даты / времени вместо SimpleDateFormat
и Date
:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
LocalDateTime eventStart = LocalDateTime.parse("2019-10-09 01:24:05.0", formatter);
LocalDateTime eventEnd = LocalDateTime.parse("2019-10-09 01:35:14.0", formatter);
Duration duration;
if (eventStart.isBefore(eventEnd)) {
duration = Duration.between(eventStart, eventEnd);
} else {
duration = Duration.between(eventEnd, eventStart);
}
long minutes = duration.toMinutes();
System.out.println("" + minutes + " minute(s)");
Результат: 11 minute(s)
.
Объединение всех перекрывающихся диапазонов дат
Чтобы объединить все перекрывающиеся диапазоны дат, рассмотрите следующий подход.
Создание класс для представления диапазона дат с помощью методов isOverlappingWith
, mergeWith
, toMinutes
и переопределения equals
и hashCode
.
private static class DateRange {
private final LocalDateTime startDate;
private final LocalDateTime endDate;
public DateRange(LocalDateTime startDate, LocalDateTime endDate) {
this.startDate = startDate;
this.endDate = endDate;
}
public boolean isOverlappingWith(DateRange other) {
return !startDate.isAfter(other.endDate) && !endDate.isBefore(other.startDate);
}
public DateRange mergeWith(DateRange other) {
return new DateRange(
startDate.isBefore(other.startDate) ? startDate : other.startDate,
endDate.isAfter(other.endDate) ? endDate : other.endDate);
}
public long toMinutes() {
return Duration.between(startDate, endDate).toMinutes();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
DateRange dateRange = (DateRange) o;
return Objects.equals(startDate, dateRange.startDate) &&
Objects.equals(endDate, dateRange.endDate);
}
@Override
public int hashCode() {
return Objects.hash(startDate, endDate);
}
@Override
public String toString() {
return "DateRange{" +
"startDate=" + startDate +
", endDate=" + endDate +
'}';
}
}
Выполните итерацию по всем диапазонам дат и попытайтесь объединить их. Для отслеживания дубликатов требуется дополнительно HashSet
. Идея состоит в том, чтобы попытаться объединить каждый диапазон дат со следующими диапазонами в списке. Если произошло хотя бы одно слияние, удалите исходный диапазон дат. Если в списке нет результирующего диапазона дат слияния, добавьте его в список.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S");
List<List<String>> rawDateRanges = List.of(
List.of("2009-08-01 00:00:00.0", "2009-08-03 00:00:00.0"),
List.of("2009-08-05 00:00:00.0", "2009-08-06 00:00:00.0"),
List.of("2009-08-02 00:00:00.0", "2009-08-09 00:00:00.0"),
List.of("2009-08-12 00:00:00.0", "2009-08-13 00:00:00.0"),
List.of("2009-08-11 00:00:00.0", "2009-08-12 00:00:00.0"),
List.of("2009-08-02 00:00:00.0", "2009-08-02 00:00:00.0"));
List<DateRange> dateRanges = new ArrayList<>();
for (List<String> rawDateRange : rawDateRanges) { //Replace with while (rs.next()) { ... }
LocalDateTime fromDate = LocalDateTime.parse(rawDateRange.get(0), formatter);
LocalDateTime toDate = LocalDateTime.parse(rawDateRange.get(1), formatter);
dateRanges.add(new DateRange(fromDate, toDate));
}
Set<DateRange> mergedDateRanges = new HashSet<>();
for (int i = 0; i < dateRanges.size(); i++) {
DateRange dateRange = dateRanges.get(i);
boolean merged = false;
for (int j = i + 1; j < dateRanges.size(); j++) {
DateRange otherDateRange = dateRanges.get(j);
if (dateRange.isOverlappingWith(otherDateRange)) {
dateRange = dateRange.mergeWith(otherDateRange);
merged = true;
}
}
if (merged) {
dateRanges.remove(i--);
if (mergedDateRanges.add(dateRange)) {
dateRanges.add(dateRange);
}
}
}
List<Long> minutes = dateRanges.stream()
.peek(System.out::println)
.map(DateRange::toMinutes) //Convert to minutes
.collect(toList());
System.out.println(minutes);
Вывод:
DateRange{startDate=2009-08-01T00:00, endDate=2009-08-09T00:00}
DateRange{startDate=2009-08-11T00:00, endDate=2009-08-13T00:00}
[11520, 2880]