package com.lihong.DDPush.pms;
import com.lihong.DDPush.mybatis.Parser;
import org.junit.Test;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class TimeOverlapTest {
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
@Test
public void test() {
String[] params = new String[] {
"2017-09-28 08:00:00",
"2017-09-28 10:00:00",
"2017-09-28 12:00:00",
"2017-09-28 15:00:00",
"2017-09-28 07:00:00",
"2017-09-28 18:00:00"
};
String[] params1 = new String[] {
"2017-09-28 08:00:00",
"2017-09-28 10:00:00",
"2017-09-28 12:00:00",
"2017-09-28 15:00:00"
};
String[] params2 = new String[] {
"2017-09-28 07:00:00",
"2017-09-28 18:00:00"
};
caculate(params, params1, params2);
}
@Test
public void test01() {
String[] params = new String[]{
"2017-09-28 08:00:00",
"2017-09-28 17:00:00",
"2017-09-28 09:00:00",
"2017-09-28 16:00:00"
};
String[] params1 = new String[]{
"2017-09-28 08:00:00",
"2017-09-28 17:00:00"
};
String[] params2 = new String[]{
"2017-09-28 09:00:00",
"2017-09-28 16:00:00"
};
caculate(params, params1, params2);
}
@Test
public void test02() {
String[] params = new String[]{
"2017-09-28 08:00:00",
"2017-09-28 10:00:00",
"2017-09-28 09:00:00",
"2017-09-28 12:00:00",
"2017-09-28 11:00:00",
"2017-09-28 13:00:00",
"2017-09-28 12:00:00",
"2017-09-28 15:00:00"
};
String[] params1 = new String[]{
"2017-09-28 08:00:00",
"2017-09-28 10:00:00",
"2017-09-28 09:00:00",
"2017-09-28 12:00:00",
"2017-09-28 11:00:00",
"2017-09-28 13:00:00"
};
String[] params2 = new String[]{
"2017-09-28 12:00:00",
"2017-09-28 15:00:00"
};
caculate(params, params1, params2);
}
@Test
public void test03() {
String[] params = new String[]{
"2017-09-28 08:00:00",
"2017-09-28 10:00:00",
"2017-09-28 09:00:00",
"2017-09-28 12:00:00",
"2017-09-28 11:00:00",
"2017-09-28 13:00:00",
"2017-09-28 12:00:00",
"2017-09-28 15:00:00",
"2017-09-28 07:00:00",
"2017-09-28 11:00:00"
};
String[] params1 = new String[]{
"2017-09-28 08:00:00",
"2017-09-28 10:00:00",
"2017-09-28 09:00:00",
"2017-09-28 12:00:00",
"2017-09-28 11:00:00",
"2017-09-28 13:00:00"
};
String[] params2 = new String[]{
"2017-09-28 12:00:00",
"2017-09-28 15:00:00",
"2017-09-28 07:00:00",
"2017-09-28 11:00:00"
};
caculate(params, params1, params2);
}
@Test
public void test04() {
String[] params = new String[]{
"2017-09-28 08:00:00",
"2017-09-28 10:00:00",
"2017-09-28 09:00:00",
"2017-09-28 12:00:00",
"2017-09-28 11:00:00",
"2017-09-28 13:00:00",
"2017-09-28 12:00:00",
"2017-09-28 15:00:00",
"2017-09-28 07:00:00",
"2017-09-28 11:00:00"
};
String[] params1 = new String[] {
"2017-09-28 08:00:00",
"2017-09-28 10:00:00",
"2017-09-28 09:00:00",
"2017-09-28 12:00:00",
"2017-09-28 11:00:00",
"2017-09-28 13:00:00"
};
String[] params2 = new String[]{
"2017-09-28 12:00:00",
"2017-09-28 15:00:00",
"2017-09-28 07:00:00",
"2017-09-28 11:00:00"
};
caculate(params, params1, params2);
}
@Test
public void test05() {
String[] params = new String[] {
"2017-09-28 07:00:00",
"2017-09-28 10:00:00",
"2017-09-28 13:00:00",
"2017-09-28 18:00:00",
"2017-09-28 21:00:00",
"2017-09-28 23:00:00",
"2017-09-28 01:00:00",
"2017-09-28 23:40:00"
};
String[] params1 = new String[] {
"2017-09-28 07:00:00",
"2017-09-28 10:00:00",
"2017-09-28 13:00:00",
"2017-09-28 18:00:00",
"2017-09-28 21:00:00",
"2017-09-28 23:40:00"
};
String[] params2 = new String[]{
"2017-09-28 01:00:00",
"2017-09-28 23:40:00"
};
caculateNotInHoliday(params, params1, params2);
}
private void caculateNotInHoliday(String[] params, String[] authTimes, String[] parkTimes) {
List dates = getDateList(params);
removeRepeat(dates);
Collections.sort(dates);
List pairs = new ArrayList();
for (int i = 0, j = dates.size(); i if ((i + 2) <= j) {
System.out.println("i: " + i + ", j: " + (i + 1));
TimePair pair = new TimePair(dates.get(i), dates.get(i + 1));
pairs.add(pair);
pair.caculateOverLapWithAuth(getDateList(authTimes));
pair.caculateOverLapWithStay(getDateList(parkTimes));
System.out.println(pair);
System.out.println();
}
}
System.out.println("===============================================================================");
System.out.println(pairs);
System.out.println("===============================================================================");
List notInHolidayLi = new ArrayList<>();
for (int i = 0; i TimePair pair = pairs.get(i);
if (pair.notInHoliday()) {
notInHolidayLi.add(pair);
System.out.println(pair);
}
}
System.out.println("===============================================================================");
System.out.println(notInHolidayLi);
System.out.println("===============================================================================");
System.out.println(mergeContinous(notInHolidayLi));
}
private void caculate(String[] params, String[] authTimes, String[] parkTimes) {
List dates = getDateList(params);
removeRepeat(dates);
Collections.sort(dates);
List pairs = new ArrayList();
for (int i = 0, j = dates.size(); i if ((i + 2) <= j) {
System.out.println("i: " + i + ", j: " + (i + 1));
TimePair pair = new TimePair(dates.get(i), dates.get(i + 1));
pairs.add(pair);
pair.caculateOverLapWithAuth(getDateList(authTimes));
pair.caculateOverLapWithStay(getDateList(parkTimes));
System.out.println(pair);
System.out.println();
}
}
System.out.println("===============================================================================");
System.out.println(pairs);
System.out.println("===============================================================================");
List chargeTimes = new ArrayList<>();
for (int i = 0; i TimePair pair = pairs.get(i);
if (pair.needCharge()) {
chargeTimes.add(pair);
System.out.println(pair);
}
}
System.out.println("===============================================================================");
System.out.println("-------------------------------------------------------------------------------");
System.out.println(chargeTimes);
System.out.println("-------------------------------------------------------------------------------");
System.out.println(mergeContinous(chargeTimes));
}
public void removeRepeat(List dates) {
for (int i = 0; i <(dates.size() - 1); i++) {
for (int j = i + 1; j System.out.print("remove i: " + i);
System.out.print("remove j: " + j);
if (dates.get(i).getTime() == dates.get(j).getTime()) {
dates.remove(j);
}
}
}
}
public List mergeContinous(List pairs) {
if (pairs == null || pairs.size() == 0) {
return new ArrayList();
}
List li = new ArrayList();
if (pairs.size() == 1) {
Pair p = new Pair(pairs.get(0).getStartTime(), pairs.get(0).getEndTime());
li.add(p);
return li;
}
Date start = pairs.get(0).getStartTime();
Date end = pairs.get(0).getEndTime();
for (int i = 1; i TimePair tp = pairs.get(i);
if (tp.getStartTime().getTime() == end.getTime()) {
end = tp.getEndTime();
} else {
Pair pr = new Pair(start, end);
li.add(pr);
start = tp.getStartTime();
end = tp.getEndTime();
}
}
li.add(new Pair(start, end));
return li;
}
public static boolean isCollectionEmpty(Collection> collection) {
if (collection == null || collection.isEmpty()) {
return true;
}
return false;
}
public static Date stringToDate(String strValue, String strFormat) {
Date date = null;
try {
date = new SimpleDateFormat(strFormat).parse(strValue);
} catch (ParseException e) {
}
return date;
}
public static String dateToString(Date dateValue, String strFormat) {
return new SimpleDateFormat(strFormat).format(dateValue);
}
public static List getDateList(String... dateStr) {
if (dateStr == null || dateStr.length == 0) {
return new ArrayList<>();
}
List result = new ArrayList();
for (String el : dateStr) {
result.add(stringToDate(el, YYYY_MM_DD_HH_MM_SS));
}
return result;
}
private static class TimePair {
private Date startTime;
private Date endTime;
private Long startLong;
private Long endLong;
private String startString;
private String endString;
private int authOverlapCout;
private int stayOverlapCount;
private static final Predicate predicateIsCharge = new Predicate() {
@Override
public boolean test(TimePair timePair) {
return timePair.getStayOverlapCount() > timePair.getAuthOverlapCout();
}
};
private static final Predicate predicateNotInHoliday = new Predicate() {
@Override
public boolean test(TimePair timePair) {
int authOverlapCout = timePair.getAuthOverlapCout();
int stayOverlapCount = timePair.getStayOverlapCount();
return stayOverlapCount > 0 && authOverlapCout == 0;
}
};
public TimePair(Long startLong, Long endLong) {
this(new Date(startLong), new Date(endLong));
}
public TimePair(Date startTime, Date endTime) {
this.startTime = startTime;
this.endTime = endTime;
this.startLOng= startTime.getTime();
this.endLOng= endTime.getTime();
this.startString = dateToString(startTime, YYYY_MM_DD_HH_MM_SS);
this.endString = dateToString(endTime, YYYY_MM_DD_HH_MM_SS);
}
public TimePair(String startString, String endString) {
this.startString = startString;
this.endString = endString;
this.startTime = stringToDate(startString, YYYY_MM_DD_HH_MM_SS);
this.endTime = stringToDate(endString, YYYY_MM_DD_HH_MM_SS);
this.startLOng= this.startTime.getTime();
this.endLOng= this.endTime.getTime();
}
public String getStartString() {
return startString;
}
public void setStartString(String startString) {
this.startString = startString;
}
public String getEndString() {
return endString;
}
public void setEndString(String endString) {
this.endString = endString;
}
public int getStayOverlapCount() {
return stayOverlapCount;
}
public void setStayOverlapCount(int stayOverlapCount) {
this.stayOverlapCount = stayOverlapCount;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public Long getStartLong() {
return startLong;
}
public void setStartLong(Long startLong) {
this.startLOng= startLong;
}
public Long getEndLong() {
return endLong;
}
public void setEndLong(Long endLong) {
this.endLOng= endLong;
}
public int getAuthOverlapCout() {
return authOverlapCout;
}
public void setAuthOverlapCout(int authOverlapCout) {
this.authOverlapCout = authOverlapCout;
}
public int caculateOverLapWith(Date startTime, Date endTime) {
if (this.startLOng== null) {
this.startLOng= this.startTime.getTime();
}
if (this.endLOng== null) {
this.endLOng= this.endTime.getTime();
}
int incr = 0;
if (this.startLong >= startTime.getTime() && this.endLong <= endTime.getTime()) {
if (this.startLong != this.endLong) {
incr += 1;
}
}
return incr;
}
public int caculateOverLapWithAuth(Date startTime, Date endTime) {
int incr = caculateOverLapWith(startTime, endTime);
if (incr > 0) {
String startTimeStr = dateToString(startTime, YYYY_MM_DD_HH_MM_SS);
String endTimeStr = dateToString(endTime, YYYY_MM_DD_HH_MM_SS);
System.out.println(Parser.parse1("[包期时间]: ({} ~ {})与时间段({} ~ {})有重叠", this.startString, this.endString, startTimeStr, endTimeStr));
}
this.authOverlapCout += incr;
return this.authOverlapCout;
}
public int caculateOverLapWithStay(Date startTime, Date endTime) {
int incr = caculateOverLapWith(startTime, endTime);
if (incr > 0) {
String startTimeStr = dateToString(startTime, YYYY_MM_DD_HH_MM_SS);
String endTimeStr = dateToString(endTime, YYYY_MM_DD_HH_MM_SS);
System.out.println(Parser.parse1("[停留时间]: ({} ~ {})与时间段({} ~ {})有重叠", this.startString, this.endString, startTimeStr, endTimeStr));
}
this.stayOverlapCount += incr;
return this.stayOverlapCount;
}
public boolean needCharge() {
return predicateIsCharge.test(this);
}
public boolean notInHoliday() {
return predicateNotInHoliday.test(this);
}
public int caculateOverLapWithAuth(List dates) {
int count = this.authOverlapCout;
if (dates == null) {
return count;
}
final int batch = 2;
while (dates.size() >= batch) {
List li = dates.subList(0, batch);
count = caculateOverLapWithAuth(li.get(0), li.get(1));
li.clear();
}
return count;
}
public int caculateOverLapWithStay(List dates) {
int count = this.stayOverlapCount;
if (dates == null) {
return count;
}
final int batch = 2;
while (dates.size() >= batch) {
List li = dates.subList(0, batch);
count = caculateOverLapWithStay(li.get(0), li.get(1));
li.clear();
}
return count;
}
@Override
public String toString() {
if (startString == null) {
startString = dateToString(startTime, YYYY_MM_DD_HH_MM_SS);
}
if (endString == null) {
endString = dateToString(endTime, YYYY_MM_DD_HH_MM_SS);
}
return "(" + startString + " ~ " + endString + ") : auth:" + this.authOverlapCout + " stay:" + this.stayOverlapCount;
}
}
private static class Pair {
public A first;
public B second;
public Pair(A first, B second) {
this.first = first;
this.secOnd= second;
}
@Override
public String toString() {
return Parser.parse1("<{}, {}>\n\t",
first instanceof Date ? dateToString((Date) first, YYYY_MM_DD_HH_MM_SS) : first,
second instanceof Date ? dateToString((Date) second, YYYY_MM_DD_HH_MM_SS) : second);
}
}
public interface Predicate {
public boolean test(T t);
}
}