业务场景:一个时间区间对多个时间区间取差集,也就是计算出一个时间区间内其他时间区间没有占有的时间段 如下图:
整个时间段为一天的开始至结尾,蓝色为占用的时间段(跨天情况带上日期计算 如2019-10-01 22:00:00-2019-10-02 07:00:00),橙色箭头为需要计算出的时间段
代码实现以一个月为维度,计算当前时间到月底的时间段内所有空闲时段
模拟数据库查询出的List<UnitTime>
@Data
public class UnitTime {
/**
* 当天日期 YYYY-MM-dd
*/
private String dateTime;
/**
* 开始时间戳
*/
private Integer startDate;
/**
* 结束时间戳
*/
private Integer endDate;
}
DateUtil工具类
public class DateUtil {
private static String LONGDATE_DATEMONTH = "yyyy-MM";
private static String LONGDATE_DATE = "yyyy-MM-dd";
/**
* Map的Key,用于获取某月第一天{@link #LONGDATE_DATE}格式的日期
*/
public static final String START_DATE = "START_DATE";
/**
* Map的Key,用于获取某月最后一天{@link #LONGDATE_DATE}格式的日期
*/
public static final String STOP_DATE = "STOP_DATE";
/**
* 获得指定年月日期的月份第一天和最后一天
* 如果日期在本月以内 则返回当天日期和月末日期
* @param yearMonth 2019-05
* @return
*/
public static Map<String, String> getStartDateAndStopDate(String yearMonth) throws ParseException {
SimpleDateFormat sdf = new SimpleDateFormat(LONGDATE_DATEMONTH);
Calendar cale = getCalendar(sdf.parse(yearMonth));
SimpleDateFormat format = new SimpleDateFormat(LONGDATE_DATE);
String firstDay, lastDay;
if (isThisTime(cale.getTime().getTime(),LONGDATE_DATEMONTH)) {
firstDay = format.format(new Date());
} else {
cale.add(Calendar.MONTH, 0);
cale.set(Calendar.DAY_OF_MONTH, 1);
firstDay = format.format(cale.getTime());
}
cale.add(Calendar.MONTH, 1);
cale.set(Calendar.DAY_OF_MONTH, 0);
lastDay = format.format(cale.getTime());
Map<String, String> date = new HashMap<String, String>();
date.put(START_DATE, firstDay);
date.put(STOP_DATE, lastDay);
return date;
}
public static Calendar getCalendar(Date date) {
Calendar cal