Skip to content

Instantly share code, notes, and snippets.

@circlee
Last active March 18, 2019 14:58
Show Gist options
  • Save circlee/61f014d60b07be2ced29eee57940df38 to your computer and use it in GitHub Desktop.
Save circlee/61f014d60b07be2ced29eee57940df38 to your computer and use it in GitHub Desktop.
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;
public class LocalDateTimeRange<T> {
enum EDGE {
START, END
}
Map<LocalDateTime, Set<EDGE>> localDateTimesMap = new HashMap<>();
private Set<RangeWrap<T>> rangeWrapList = new HashSet<>();
public LocalDateTimeRange() {
}
public void add(RangeWrap<T> rangeWrap) {
rangeWrapList.add(rangeWrap);
LocalDateTime startedAtKey = rangeWrap.getStartedAt().plusSeconds(0);
localDateTimesMap.computeIfAbsent(startedAtKey, (key) -> new HashSet<>()).add(EDGE.START);
LocalDateTime endedAtKey = rangeWrap.getEndedAt().plusSeconds(0);
localDateTimesMap.computeIfAbsent(endedAtKey, (key) -> new HashSet<>()).add(EDGE.END);
}
public void add(LocalDateTime startedAt, LocalDateTime endedAt, T wrapObj) {
this.add(new RangeWrap<T>(startedAt, endedAt, wrapObj));
}
public List<RangeWrapResult> getResults() {
List<RangeWrapResult> rangeWrapResults = new ArrayList<>();
List<LocalDateTime> timeKeyList = localDateTimesMap.keySet().stream()
.sorted()
.collect(Collectors.toList());
for (int i = 0; i < timeKeyList.size() - 1; i++) {
LocalDateTime from = timeKeyList.get(i);
LocalDateTime to = timeKeyList.get(i + 1);
// 시작일이 아닐 경우 기간 분리를 위해 1초 +
if (!localDateTimesMap.get(from).contains(EDGE.START)) {
from = from.plusSeconds(1);
}
// 종료일이 아닐경우 기간 분리를 위해 1초 -
if (!localDateTimesMap.get(to).contains(EDGE.END)) {
to = to.minusSeconds(1);
}
// lambda 참조를 위한 final 선언
final LocalDateTime checkedFrom = from;
final LocalDateTime checkedTo = to;
// 기간분리시 종료~시작 케이스 , 역순 기간은 제외
if (from.compareTo(to) < 0) {
// 기간에 포함되는 obj list
List<T> wrapObjList = rangeWrapList.stream()
.filter(wrapItem -> {
if (checkedFrom.compareTo(wrapItem.startedAt) >= 0 && checkedTo.compareTo(wrapItem.endedAt) <= 0) {
return true;
}
return false;
})
.map(wrapItem -> wrapItem.wrapObj)
.collect(Collectors.toList());
// 기가엔 포함되는 obj가 없을경우 결과 제외
if(!wrapObjList.isEmpty()) {
RangeWrapResult result = new RangeWrapResult(checkedFrom, checkedTo, wrapObjList);
rangeWrapResults.add(result);
}
}
}
return rangeWrapResults;
}
@SuppressWarnings("hiding")
class RangeWrap<T> {
private LocalDateTime startedAt;
private LocalDateTime endedAt;
private T wrapObj;
public RangeWrap(LocalDateTime startedAt, LocalDateTime endedAt, T wrapObj) {
this.startedAt = startedAt;
this.endedAt = endedAt;
this.wrapObj = wrapObj;
}
public LocalDateTime getStartedAt() {
return startedAt;
}
public void setStartedAt(LocalDateTime startedAt) {
this.startedAt = startedAt;
}
public LocalDateTime getEndedAt() {
return endedAt;
}
public void setEndedAt(LocalDateTime endedAt) {
this.endedAt = endedAt;
}
public T getWrapObj() {
return wrapObj;
}
public void setWrapObj(T wrapObj) {
this.wrapObj = wrapObj;
}
@Override
public String toString() {
return "RangeWrap [startedAt=" + startedAt + ", endedAt=" + endedAt + ", wrapObj=" + wrapObj + "]";
}
}
class RangeWrapResult {
private LocalDateTime startedAt;
private LocalDateTime endedAt;
private List<T> wrapObjList;
public RangeWrapResult(LocalDateTime startedAt, LocalDateTime endedAt, List<T> wrapObjList) {
this.startedAt = startedAt;
this.endedAt = endedAt;
this.wrapObjList = wrapObjList;
}
public LocalDateTime getStartedAt() {
return startedAt;
}
public void setStartedAt(LocalDateTime startedAt) {
this.startedAt = startedAt;
}
public LocalDateTime getEndedAt() {
return endedAt;
}
public void setEndedAt(LocalDateTime endedAt) {
this.endedAt = endedAt;
}
public List<T> getWrapObjList() {
return wrapObjList;
}
public void setWrapObjList(List<T> wrapObjList) {
this.wrapObjList = wrapObjList;
}
@Override
public String toString() {
return "RangeWrapResult [startedAt=" + startedAt + ", endedAt=" + endedAt + ", wrapObjList=" + wrapObjList + "]";
}
}
public static void main(String... args) {
LocalDateTime now = LocalDateTime.now();
LocalDateTime as = LocalDateTime.parse("2019-03-01 15:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime ae = LocalDateTime.parse("2019-03-10 14:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime bs = LocalDateTime.parse("2019-03-02 15:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime be = LocalDateTime.parse("2019-03-13 14:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime cs = LocalDateTime.parse("2019-03-08 15:00:00", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTime ce = LocalDateTime.parse("2019-03-15 14:59:59", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
LocalDateTimeRange<String> a = new LocalDateTimeRange<>();
LocalDateTimeRange<String>.RangeWrap<String> rw1 = a.new RangeWrap<>(as, ae, "1");
System.out.println(rw1);
LocalDateTimeRange<String>.RangeWrap<String> rw2 = a.new RangeWrap<>(bs, be, "2");
System.out.println(rw2);
LocalDateTimeRange<String>.RangeWrap<String> rw3 = a.new RangeWrap<>(cs, ce, "3");
System.out.println(rw3);
a.add(rw1);
a.add(rw2);
a.add(rw3);
a.getResults().stream().forEach(wrap -> {
System.out.println(wrap.getStartedAt() + " ~ " + wrap.getEndedAt() + " : " + wrap.getWrapObjList());
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment