时间段的拼接

来源:互联网 发布:沈航网络自助平台套餐 编辑:程序博客网 时间:2024/06/05 09:32
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());                }                /*                 * 事实上只有最后一项会进入该分支,开始时间如果大于结束时间,则属于跨天的情况,举例:如果timeList是{07:00 ~ 19:00, 19:00~07:00}, 日期(baseDateStr)是2017-04-08,                       则 19:00~07:00 这个时间段会被拼接为2017-04-08 19:00 ~ 2017-04-09 07:00                */                else if (start > end) {                    Integer fixedEndTime = 0;                    if (end > firstStart) {//此处目的是为了保证时段不会重复                        fixedEndTime = firstStart;                    } else if (end < firstStart) {//这里有似乎无用的if else , 目的是为了做成可以配置的                        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);        /*         * 最后一段如果跨天,举例,如果timeList是{07:00 ~ 19:00, 19:00~07:00},入场出场日期都是2017-04-08,则最终拼接结果是         * {         *   2017-04-08 00:00 ~ 2017-04-08 07:00,         *   2017-04-08 07:00 ~ 2017-04-08 19:00,         *   2017-04-08 19:00 ~ 2017-04-09 07:00         * },         *         * 这里if语句的目的是添加2017-04-08 00:00 ~ 2017-04-08 07:00这一段时间         * */        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对象            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;        }    }}
原创粉丝点击