package com.lihong.DDPush.pms;
import com.lihong.DDPush.mybatis.Parser;
import org.junit.Test;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Created by lihong10 on 2017/9/30.
*/
public class SplitJoinTest {
public static final String YYYY_MM_DD = "yyyy-MM-dd";
public static final String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static final long MIN_SECOND = 60 * 1000;
public static final long DAY_OF_MILLISECOND = 24 * 60 * 60 * 1000;
private static final Integer COMPLEMENT = 1;
@Test
public void test() {
List<Integer[]> li01 = new ArrayList<Integer[]>() {{
add(new Integer[]{420, 900});
add(new Integer[]{900, 1140});
add(new Integer[]{1140, 420});
}};
splitTime(stringToDate("2017-09-28 08:10:00", YYYY_MM_DD_HH_MM_SS).getTime(),
stringToDate("2017-09-30 23:10:00", YYYY_MM_DD_HH_MM_SS).getTime(),
li01);
}
/**
* @param crossBeginTime
* @param crossEndTime
* @param timeList 一天中的离散时间段列表, 该列表中的元素, 只有最后一个元素有可能出现开始时间大于结束时间的情况,
* 比如: [07:00 - 15:00, 15:00 - 19:00, 19:00 - 07:00]
* @Author: lihong10
* @Description:
* @Date: 2017/9/30 16:08
*/
public static List<TimePair> splitTime(Long crossBeginTime, Long crossEndTime, List<Integer[]> timeList) {
Date crossBeginDate = new Date(crossBeginTime);
Date crossEndDate = new Date(crossEndTime);
Integer[] first = timeList.get(0);
if (first[0] > first[1]) {
Collections.reverse(timeList);
first = timeList.get(0);
}
Integer firstStart = first[0];
List<String> dates = getDatesBetween(crossBeginDate, crossEndDate);
List<TimePair> pairs = new ArrayList<TimePair>();
for (int i = 0; i < dates.size(); i++) {
String baseDateStr = dates.get(i);
Date baseDate = stringToDate(baseDateStr + " 00:00:00", YYYY_MM_DD_HH_MM_SS);
for (int j = 0; j < timeList.size(); j++) {
Integer[] time = timeList.get(j);
Integer start = time[0];
Integer end = time[1];
String startTimeStr = getTimeStr(start);
String endTimeStr = getTimeStr(end);
if (start < end) {
TimePair.Builder tb = new TimePair.Builder();
tb.startTime(baseDate.getTime() + start * MIN_SECOND)
.endTime(baseDate.getTime() + end * MIN_SECOND)
.startTimeStr(baseDateStr + " " + startTimeStr)
.endTimeStr(baseDateStr + " " + endTimeStr);
pairs.add(tb.build());
}
else if (start > end) {
Integer fixedEndTime = 0;
if (end > firstStart) {
fixedEndTime = firstStart;
} else if (end < firstStart) {
fixedEndTime = COMPLEMENT == 1 ? firstStart : end;
} else {
fixedEndTime = firstStart;
}
String nextDateStr = dateToString(new Date(baseDate.getTime() + DAY_OF_MILLISECOND), YYYY_MM_DD);
TimePair.Builder tb = new TimePair.Builder();
tb.startTime(baseDate.getTime() + firstStart * MIN_SECOND)
.endTime(baseDate.getTime() + DAY_OF_MILLISECOND + fixedEndTime * MIN_SECOND)
.startTimeStr(baseDateStr + " " + startTimeStr)
.endTimeStr(nextDateStr + " " + getTimeStr(fixedEndTime));
pairs.add(tb.build());
}
}
}
Integer[] last = timeList.get(timeList.size() - 1);
if (last[0] > last[1]) {
String baseDateStr = dates.get(0);
Date baseDate = stringToDate(baseDateStr + " 00:00:00", YYYY_MM_DD_HH_MM_SS);
TimePair.Builder tb = new TimePair.Builder();
tb.startTime(baseDate.getTime())
.endTime(baseDate.getTime() + firstStart * MIN_SECOND)
.startTimeStr(baseDateStr + " 00:00:00").endTimeStr(baseDateStr + " " + getTimeStr(firstStart));
pairs.add(0, tb.build());
}
System.out.println("拼接得到的时间串是:\n" + pairs);
return pairs;
}
private static List<String> getDatesBetween(Date startDate, Date endDate) {
String startDateStr = dateToString(startDate, YYYY_MM_DD);
String endDateStr = dateToString(endDate, YYYY_MM_DD);
startDate = stringToDate(startDateStr + " 00:00:00", YYYY_MM_DD_HH_MM_SS);
endDate = stringToDate(endDateStr + " 00:00:00", YYYY_MM_DD_HH_MM_SS);
List<String> dates = new ArrayList();
Calendar startCalendar = Calendar.getInstance();
startCalendar.clear();
startCalendar.setTime(startDate);
Calendar endCalendar = Calendar.getInstance();
endCalendar.clear();
endCalendar.setTime(endDate);
while (startCalendar.compareTo(endCalendar) <= 0) {
dates.add(dateToString(startCalendar.getTime(), YYYY_MM_DD));
startCalendar.add(Calendar.DAY_OF_YEAR, 1);
}
System.out.println(Parser.parse1("开始日期{}到结束日期{}之间的所有日期是:{}", startDateStr, endDateStr, dates));
return dates;
}
private static String getTimeStr(Integer time) {
time = time == null ? 0 : time;
String hour = time / 60 > 9 ? ("" + time / 60) : ("0" + time / 60);
String minute = time % 60 > 9 ? ("" + time % 60) : ("0" + time % 60);
return hour + ":" + minute + ":00";
}
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);
}
}
class TimePair {
private Long startTime;
private Long endTime;
private String startTimeStr;
private String endTimeStr;
private Long freeTime;
private Long thresholdTime;
private BigDecimal inThresholdTimeFee;
private BigDecimal overThresholdTimeFee;
private BigDecimal feeBetween;
public TimePair() {
super();
}
public TimePair(Long startTime, Long endTime) {
super();
this.startTime = startTime;
this.endTime = endTime;
}
public void setStartTimeStr(String startTimeStr) {
this.startTimeStr = startTimeStr;
}
public void setEndTimeStr(String endTimeStr) {
this.endTimeStr = endTimeStr;
}
public Long getStartTime() {
return startTime;
}
public void setStartTime(Long startTime) {
this.startTime = startTime;
}
public Long getEndTime() {
return endTime;
}
public void setEndTime(Long endTime) {
this.endTime = endTime;
}
public String getStartTimeStr() {
return startTimeStr;
}
public String getEndTimeStr() {
return endTimeStr;
}
public Long getFreeTime() {
return freeTime;
}
public void setFreeTime(Long freeTime) {
this.freeTime = freeTime;
}
public Long getThresholdTime() {
return thresholdTime;
}
public void setThresholdTime(Long thresholdTime) {
this.thresholdTime = thresholdTime;
}
public BigDecimal getInThresholdTimeFee() {
return inThresholdTimeFee;
}
public void setInThresholdTimeFee(BigDecimal inThresholdTimeFee) {
this.inThresholdTimeFee = inThresholdTimeFee;
}
public BigDecimal getOverThresholdTimeFee() {
return overThresholdTimeFee;
}
public void setOverThresholdTimeFee(BigDecimal overThresholdTimeFee) {
this.overThresholdTimeFee = overThresholdTimeFee;
}
public BigDecimal getFeeBetween() {
return feeBetween;
}
public void setFeeBetween(BigDecimal feeBetween) {
this.feeBetween = feeBetween;
}
/**
* 根据进场时间和出场时间,计算车辆在 startTime ~ endTime 之间的时段内停留了多久
*
* @param crossBeginTime
* @param crossEndTime
* @return
*/
public Long getParkTime(Long crossBeginTime, Long crossEndTime) {
if (crossBeginTime >= crossEndTime) {
return 0L;
}
if (crossEndTime <= startTime || crossBeginTime >= endTime) {
return 0L;
}
if (crossBeginTime <= startTime && crossEndTime >= startTime && crossEndTime <= endTime) {
return crossEndTime - startTime >= 0 ? crossEndTime - startTime : 0;
} else if (crossBeginTime <= startTime && crossEndTime >= endTime) {
return endTime - startTime >= 0 ? endTime - startTime : 0;
} else if (crossBeginTime >= startTime && crossEndTime <= endTime) {
return crossEndTime - crossBeginTime >= 0 ? crossEndTime - crossBeginTime : 0;
} else if (crossBeginTime >= startTime && crossBeginTime <= endTime && crossEndTime >= endTime) {
return endTime - crossBeginTime >= 0 ? endTime - crossBeginTime : 0;
}
return 0L;
}
/**
* 覆盖父类方法,目的是为了打印详细日志信息
*/
@Override
public String toString() {
return "(" + startTimeStr + " - " + endTimeStr + ")\n";
}
public static class Builder {
private Long startTime;
private Long endTime;
private String startTimeStr;
private String endTimeStr;
private Long freeTime;
private Long thresholdTime;
private BigDecimal inThresholdTimeFee;
private BigDecimal overThresholdTimeFee;
private BigDecimal feeBetween;
public Builder() {
super();
}
public Builder(Long startTime, Long endTime) {
this.startTime = startTime;
this.endTime = endTime;
}
public Builder startTime(Long startTime) {
this.startTime = startTime;
return this;
}
public Builder endTime(Long endTime) {
this.endTime = endTime;
return this;
}
public Builder startTimeStr(String startTimeStr) {
this.startTimeStr = startTimeStr;
return this;
}
public Builder endTimeStr(String endTimeStr) {
this.endTimeStr = endTimeStr;
return this;
}
public Builder freeTime(Long freeTime) {
this.freeTime = freeTime;
return this;
}
public Builder thresholdTime(Long thresholdTime) {
this.thresholdTime = thresholdTime;
return this;
}
public Builder inThresholdTimeFee(BigDecimal inThresholdTimeFee) {
this.inThresholdTimeFee = inThresholdTimeFee;
return this;
}
public Builder overThresholdTimeFee(BigDecimal overThresholdTimeFee) {
this.overThresholdTimeFee = overThresholdTimeFee;
return this;
}
public Builder feeBetween(BigDecimal feeBetween) {
this.feeBetween = feeBetween;
return this;
}
public TimePair build() {
TimePair pair = new TimePair(startTime, endTime);
pair.setStartTimeStr(startTimeStr);
pair.setEndTimeStr(endTimeStr);
pair.setFreeTime(freeTime);
pair.setThresholdTime(thresholdTime);
pair.setInThresholdTimeFee(inThresholdTimeFee);
pair.setOverThresholdTimeFee(overThresholdTimeFee);
pair.setFeeBetween(feeBetween);
return pair;
}
}
}