时间段的拼接

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;
        }
    }


}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值