时间段的拼接
来源:互联网 发布:沈航网络自助平台套餐 编辑:程序博客网 时间: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; } }}
阅读全文
0 0
- 时间段的拼接
- sql 时间段的提取
- 时间段之间的断点
- 循环指定的时间段
- 时间段
- js对时间段的选择 C#对时间段的选择
- 任意时间段量的统计
- 复制时间段里的文件
- ORACLE 字段的时间段查询。。。
- 某一时间段的取平均值
- 查询 某个时间段的时间
- 年月日和时间段的转换
- java 遍历时间段的方法
- mybatis查询mysql的时间段
- 基于jQuery的时间段组件
- SQL合并时间段的问题
- mybatis的时间段动态查询
- Date时间段的相关操作
- Nginx源码剖析--ngx_cycle_t的初始化
- 1180: [NOIP2013普及组]表达式求值
- 计算多段时间的重叠
- Rsrudio使用出现问题
- spark work task 源码分析
- 时间段的拼接
- JVM(PART III)对象的内存布局
- Linux文件的查看与权限
- CodeForces-776D The Door Problem
- Laravel5.4快速开发简书网站
- 牛客网--链表反转打印
- 常见智力题总结
- 2.5类型别名,auto, decltype
- Coursera 《Machine Learning》 编程作业7:K-means聚类和主成分分析