最近项目中有个需求,需要统计显示
一组日期,要求输出其中连续的,不连续的也要输出,并且按照年,按照月份统计每个月的天数,以及显示日期段(连续的显示,不连续的单个显示) 并且按照 时间顺序排序,如出现跨年,夸月时候也要顺序显示,并且跨年跨月不能连续。
日期
2020-11-01 , 2020-11-02 , 2020-11-03 ,2020-11-05 , 2020-11-30 , 2020-11-31, 2022-01-01,2022-01-02,2022-01-04,2022-01-05,2021-12-01 , 2021-01-02, 2021-01-05
结果
11 月
1~3号
5号
30~31号
共6天
12 月
1~2号
4 号
共 3天
1月(这里可能会是下一年)
1~2号
3号
4~5号
共 5天
日期工具类
/**
* 日期工具类
*
* @author pilgrim
*/
public class DateUtil {
DateUtil() {
}
private static LoggerHelper loggerHelper = LoggerHelper.getLoggerHelper(Constants.ModuleName.COMMON,
DateUtil.class.getSimpleName());
private static Map<String, DateTimeFormatter> dateFormatCache = new ConcurrentHashMap<>();
/** 日期格式 **/
public static final String DATE_PATTERN_HH_MM_SS = "HH:mm:ss";
public static final String DATE_PATTERN_YYYY_MM = "yyyy-MM";
public static final String DATE_PATTERN_YYYY_MM_DD = "yyyy-MM-dd";
public static final String DATE_PATTERN_YYYY_MM_DD_START_TIME = "yyyy-MM-dd 00:00:00";
public static final String DATE_PATTERN_YYYY_MM_DD_END_TIME = "yyyy-MM-dd 23:59:59";
public static final String DATE_PATTERN_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static final String DATE_PATTERN_YYYY_MM_DD_HH_MM_SS_1 = "yyyy/MM/dd HH:mm:ss";
public static final String DATE_PATTERN_YYYY_MM_DD_HH_MM = "yyyy-MM-dd HH:mm";
public static final String DATE_PATTERN_YYYY_MM_DD_HH_MM_1 = "yyyy/MM/dd HH:mm";
public static final String DATE_PATTERN_YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
public static final String DATE_PATTERN_YYMMDDHHMMSS = "yyMMddHHmmss";
public static final String DATE_PATTERN_MONTH_DAY = "M月d日";
public static final String DATE_PATTERN_HH_MM = "HH:mm";
public static final String DATE_PATTERN_HH_MM_YYYY_MM_DD = "HH:mm YYYY-MM-dd";
public static final String DATE_PATTERN_MONTH_DAY_HH_MM = "MM月dd日 HH:mm";
public static final String DATE_PATTERN_MONTH_DAY_DOUBLE = "MM月dd日";
public static final String DATE_PATTERN_YEAR_MONTH_DAY = "yyyy年MM月dd日";
public static final String DATE_PATTERN_YEAR_MONTH_DAY_HH_MM = "yyyy年MM月dd日 HH:mm";
public static final String TIME_STAMP_PATTERN = "yyyyMMddHHmmssSSS";
public static final String DATE_PATTERN_HHMMSS_SSS = "HHmmssSSS";
public static final String DATE_PATTERN_YYYYMMDD = "yyyyMMdd";
public static final String DATE_PATTERN_YYYYMM = "yyyyMM";
public static DateTimeFormatter getDateFormat(String pattern) {
return dateFormatCache.computeIfAbsent(pattern, v -> DateTimeFormatter.ofPattern(pattern));
}
/**
* 生成日期字符串
*
* @param date
* 日期
* @param pattern
* 模板
* @return
*/
public static String date2String(Date date, String pattern) {
return format(date, pattern);
}
public static Date string2Date(String dateString, String pattern) {
return parse(dateString, pattern);
}
/**
* 获取服务器IP
*/
public static String getLocalIP() {
InetAddress addr = null;
StringBuilder ipAddrStr = new StringBuilder();
try {
addr = InetAddress.getLocalHost();
byte[] ipAddr = addr.getAddress();
for (int i = 0; i < ipAddr.length; i++) {
if (i > 0) {
ipAddrStr.append('.');
}
ipAddrStr.append(ipAddr[i] & 0xFF);
}
} catch (UnknownHostException e) {
throw new UtilsException(ResultCode.INTERNAL_SERVER_ERROR.val(), UtilsException.UNKNOWN_LOCAL_HOST);
}
return ipAddrStr.toString();
}
public static String format(Date date, String pattern) {
if (null == date) {
return null;
}
return getDateFormat(pattern).format(LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()));
}
public static Date parse(String dateStr, String pattern) {
if (StringUtils.isBlank(dateStr)) {
return null;
}
TemporalAccessor temporalAccessor = getDateFormat(pattern).parse(dateStr);
LocalDateTime localDateTime = LocalDateTime.of(0, 1, 1, 0, 0);
LocalDate localDate = null;
try {
localDate = LocalDate.from(temporalAccessor);
} catch (DateTimeException e) {
localDate = localDateTime.toLocalDate();
loggerHelper.debugLog("error for parse date", e);
}
LocalTime localTime = null;
try {
localTime = LocalTime.from(temporalAccessor);
} catch (DateTimeException e) {
localTime = localDateTime.toLocalTime();
loggerHelper.debugLog("error for parse time", e);
}
return Date.from(LocalDateTime.of(localDate, localTime).atZone(ZoneId.systemDefault()).toInstant());
}
public static Date addSecond(Date date, int amount) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.SECOND, amount);
return cal.getTime();
}
public static Date addMinute(Date date, int amount) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.MINUTE, amount);
return cal.getTime();
}
public static Date addDay(Date date, int amount) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DAY_OF_MONTH, amount);
return cal.getTime();
}
public static Date addMonth(Date date, int amount) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.MONTH, amount);
return cal.getTime();
}
public static Date addYear(Date date, int amount) {
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.YEAR, amount);
return cal.getTime();
}
/**
* 获取两个日期之间的分钟数
*
* @param before
* @param after
* @return
*/
public static double getDistanceMinsOfTwoDate(Date before, Date after) {
long beforeTime = before.getTime();
long afterTime = after.getTime();
return (afterTime - beforeTime) / (1000 * 60D);
}
/**
* 获取两个日期之间的天数
*
* @param before
* @param after
* @return
*/
public static double getDistanceDaysOfTwoDate(Date before, Date after) {
long beforeTime = before.getTime();
long afterTime = after.getTime();
return (afterTime - beforeTime) / (1000 * 60D * 60D * 24D);
}
public static String getStrTime(String time, String oriPattern, String targetPattern) {
Date dateTime = parse(time, oriPattern);
return format(dateTime, targetPattern);
}
/**
* @param dateStr
* @return
* @Description:判断是否为今天
*/
public static boolean isToday(String dateStr, String pattern) {
Calendar pre = Calendar.getInstance();
Date predate = new Date(System.currentTimeMillis());
pre.setTime(predate);
Calendar cal = Calendar.getInstance();
Date date = parse(dateStr, pattern);
cal.setTime(date);
return cal.get(Calendar.YEAR) == pre.get(Calendar.YEAR)
&& cal.get(Calendar.DAY_OF_YEAR) == pre.get(Calendar.DAY_OF_YEAR);
}
/**
* @param date
* @return
* @Description:判断是否为今天
*/
public static boolean isToday(Date date) {
Calendar pre = Calendar.getInstance();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
return cal.get(Calendar.YEAR) == pre.get(Calendar.YEAR)
&& cal.get(Calendar.DAY_OF_YEAR) == pre.get(Calendar.DAY_OF_YEAR);
}
/**
* 添加指定分钟数
*
* @param time
* @param minute
* @return
*/
public static String addMinute(String time, String minute) {
if (StringUtils.isEmpty(time)) {
return StringUtils.EMPTY;
}
String[] times = time.split(Constants.Punctuation.COLON);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(times[0]));
calendar.set(Calendar.MINUTE, Integer.valueOf(times[1]));
calendar.add(Calendar.MINUTE, Integer.valueOf(minute));
return format(calendar.getTime(), DATE_PATTERN_HH_MM);
}
/**
* 添加指定分钟数
*
* @param dateTime
* @param minute
* @return
*/
public static String addMinuteToDate(String dateTime, String minute) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(DateUtil.parse(dateTime, DateUtil.DATE_PATTERN_YYYY_MM_DD_HH_MM));
calendar.add(Calendar.MINUTE, Integer.valueOf(minute));
return DateUtil.date2String(calendar.getTime(), DateUtil.DATE_PATTERN_YYYY_MM_DD_HH_MM);
}
/**
* 添加指定分钟数
*
* @param date
* @param time
* @param minute
* @return yyyy-MM-dd HH:mm
*/
public static String addMinute(String date, String time, String minute) {
String[] times = time.split(Constants.Punctuation.COLON);
Calendar calendar = Calendar.getInstance();
calendar.setTime(DateUtil.string2Date(date, DateUtil.DATE_PATTERN_YYYY_MM_DD));
calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(times[0]));
calendar.set(Calendar.MINUTE, Integer.valueOf(times[1]));
calendar.add(Calendar.MINUTE, Integer.valueOf(minute));
return DateUtil.date2String(calendar.getTime(), DateUtil.DATE_PATTERN_YYYY_MM_DD_HH_MM);
}
protected static Date add(final Date date, final int calendarField, final int amount) {
if (date == null) {
throw new IllegalArgumentException("The date must not be null");
}
final Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(calendarField, amount);
return c.getTime();
}
/**
* 日期增加天数
*
* @param dateStr
* @param pattern
* @param amount
* @return
*/
public static String addDay(String dateStr, int amount, String pattern) {
try {
Date date = parse(dateStr, pattern);
Calendar cal = Calendar.getInstance();
cal.setTime(date);
cal.add(Calendar.DAY_OF_MONTH, amount);
return date2String(cal.getTime(), pattern);
} catch (Exception e) {
loggerHelper.errorLog("转换日期异常!", e);
return null;
}
}
/**
* 拼接时间
*
* @param depTime
* @return
*/
public static String handleTime(String depTime) {
if (depTime.length() > 2) {
depTime = depTime.substring(0, depTime.length() - 2) + Constants.Punctuation.COLON
+ depTime.substring(depTime.length() - 2, depTime.length());
} else {
if (depTime.length() == 1) {
depTime = "00:0" + depTime;
} else {
depTime = "00:" + depTime;
}
}
return depTime;
}
/**
* 判断用车时间是否是明天及以后时间
*
* @param useCarTime
* @return
*/
public static boolean checkTime(String useCarTime) {
Date useCarDate = parse(useCarTime, DATE_PATTERN_YYYY_MM_DD);
if (null == useCarDate) {
return false;
}
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 59);
calendar.set(Calendar.SECOND, 59);
Date date = calendar.getTime();
// 判断用车时间是否是明天及以后时间
return useCarDate.before(date);
}
/**
* 时间校验
*
* @param time
* @param advanceTime
* @return
*/
public static boolean checkTimePeriod(String time, String advanceTime) {
if (!StringUtils.isBlank(time) && !StringUtils.isBlank(advanceTime)) {
String[] timeStr = time.split(Constants.Punctuation.COLON);
if (timeStr.length > 1) {
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(timeStr[0]));
calendar.set(Calendar.MINUTE, Integer.valueOf(timeStr[1]));
calendar.add(Calendar.MINUTE, -(Integer.valueOf(advanceTime) + Constants.InterCityTime.SHOW_TIME));
calendar.set(Calendar.SECOND, 0);
Date date = calendar.getTime();
if (new Date().before(date)) {
return false;
}
}
}
return true;
}
/**
* 分钟取10的整数
*
* @param time
* @return
*/
public static String getRoundTime(String time) {
Date date = parse(time, DATE_PATTERN_HH_MM);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int minute = calendar.get(Calendar.MINUTE);
int space = 10 - minute % 10;
calendar.add(Calendar.MINUTE, space);
return date2String(calendar.getTime(), DATE_PATTERN_HH_MM);
}
public static boolean timeAfter(String time1, String time2) {
Date date1 = parse(time1, DATE_PATTERN_YYYY_MM_DD);
Date date2 = parse(time2, DATE_PATTERN_YYYY_MM_DD);
if (null == date1 || null == date2) {
return false;
}
return date1.after(date2);
}
public static boolean timeAfter(Date date1, Date date2) {
if (null == date1 || null == date2) {
return false;
}
return date1.after(date2);
}
/**
* 增加时间
*
* @param time
* @param advanceTime
* @param flag
* @return
*/
public static String addHour(String time, String advanceTime, boolean flag) {
Date date = parse(time, DATE_PATTERN_HH_MM);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
if (flag) {
if (StringUtils.isNotBlank(advanceTime)) {
calendar.add(Calendar.MINUTE, Integer.valueOf(advanceTime) + Constants.InterCityTime.SHOW_TIME);
} else {
calendar.add(Calendar.MINUTE, Constants.InterCityTime.SHOW_TIME);
}
} else {
calendar.add(Calendar.MINUTE, -Constants.InterCityTime.SHOW_TIME);
}
return date2String(calendar.getTime(), DATE_PATTERN_HH_MM);
}
/**
* 获取前一天当前时间
*
* @return
*/
public static Date getYesterdayDate() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
return cal.getTime();
}
/**
* 获取当前时间
*
* @return
*/
public static Date getCurrentDate() {
Calendar cal = Calendar.getInstance();
return cal.getTime();
}
/**
* 获取本周的开始时间
*
* @return
*/
public static Date getBeginTimeOfWeek() {
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
if (dayofweek == 1) {
dayofweek += 7;
}
cal.add(Calendar.DATE, 2 - dayofweek);
return getDayStartTime(cal.getTime());
}
/**
* 获取本周的结束时间
*
* @return
*/
public static Date getEndTimeOfWeek() {
Calendar cal = Calendar.getInstance();
cal.setTime(getBeginTimeOfWeek());
cal.add(Calendar.DAY_OF_WEEK, 6);
Date weekEndSta = cal.getTime();
return getDayEndTime(weekEndSta);
}
/**
* 获取本月的开始时间
*
* @return
*/
public static Date getBeginTimeOfMonth() {
Calendar calendar = Calendar.getInstance();
calendar.set(getNowYear(), getNowMonth() - 1, 1);
return getDayStartTime(calendar.getTime());
}
/**
* 获取本月的结束时间
*
* @return
*/
public static Date getEndTimeOfMonth() {
Calendar calendar = Calendar.getInstance();
calendar.set(getNowYear(), getNowMonth() - 1, 1);
int day = calendar.getActualMaximum(5);
calendar.set(getNowYear(), getNowMonth() - 1, day);
return getDayEndTime(calendar.getTime());
}
/**
* 获取指定年月的第一天
*
* @param year
* @param month
* @return
*/
public static String getFirstDayOfMonth(String dateStr, String pattern) {
String[] dateStrArr = dateStr.split("-");
Calendar cal = Calendar.getInstance();
//设置年份
cal.set(Calendar.YEAR, Integer.parseInt(dateStrArr[0]));
//设置月份
cal.set(Calendar.MONTH, Integer.parseInt(dateStrArr[1]) - 1);
//获取某月最小天数
int firstDay = cal.getActualMinimum(Calendar.DAY_OF_MONTH);
//设置日历中月份的最小天数
cal.set(Calendar.DAY_OF_MONTH, firstDay);
//格式化日期
return format(cal.getTime(), pattern);
}
/**
* 获取指定年月的最后一天
*
* @param year
* @param month
* @return
*/
public static String getLastDayOfMonth(String dateStr, String pattern) {
String[] dateStrArr = dateStr.split("-");
Calendar cal = Calendar.getInstance();
//设置年份
cal.set(Calendar.YEAR, Integer.parseInt(dateStrArr[0]));
//设置月份
cal.set(Calendar.MONTH, Integer.parseInt(dateStrArr[1]) - 1);
//获取某月最大天数
int lastDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
//设置日历中月份的最大天数
cal.set(Calendar.DAY_OF_MONTH, lastDay);
//格式化日期
return format(cal.getTime(), pattern);
}
/**
* 获取本年的开始时间
*
* @return
*/
public static Date getBeginTimeOfYear() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, getNowYear());
// cal.set
cal.set(Calendar.MONTH, Calendar.JANUARY);
cal.set(Calendar.DATE, 1);
return getDayStartTime(cal.getTime());
}
/**
* 获取本年的结束时间
*
* @return
*/
public static Date getEndTimeOfYear() {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, getNowYear());
cal.set(Calendar.MONTH, Calendar.DECEMBER);
cal.set(Calendar.DATE, 31);
return getDayEndTime(cal.getTime());
}
/**
* 获取某个日期的开始时间
*
* @param d
* @return
*/
public static Timestamp getDayStartTime(Date d) {
Calendar calendar = Calendar.getInstance();
if (null != d)
calendar.setTime(d);
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 0,
0, 0);
calendar.set(Calendar.MILLISECOND, 0);
return new Timestamp(calendar.getTimeInMillis());
}
/**
* 获取某个日期的结束时间
*
* @param d
* @return
*/
public static Timestamp getDayEndTime(Date d) {
Calendar calendar = Calendar.getInstance();
if (null != d)
calendar.setTime(d);
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH), 23,
59, 59);
calendar.set(Calendar.MILLISECOND, 999);
return new Timestamp(calendar.getTimeInMillis());
}
/**
* 获取今年是哪一年
*
* @return
*/
public static Integer getNowYear() {
Date date = new Date();
GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
gc.setTime(date);
return Integer.valueOf(gc.get(Calendar.YEAR));
}
/**
* 获取本月是哪一月
*
* @return
*/
public static int getNowMonth() {
Date date = new Date();
GregorianCalendar gc = (GregorianCalendar) Calendar.getInstance();
gc.setTime(date);
return gc.get(Calendar.MONTH) + 1;
}
/**
* 获取上一月当前天的时间
*
* @return
*/
public static Date getLastMonthCurDate() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MONTH, -1);
return cal.getTime();
}
/**
* 获取上一周当前天的时间
*
* @return
*/
public static Date getLastWeekCurDate() {
Calendar cal = Calendar.getInstance();
cal.add(Calendar.WEEK_OF_MONTH, -1);
return cal.getTime();
}
/**
* 获取上周的开始时间
*
* @return
*/
public static Date getBeginTimeOfLastWeek() {
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.setTime(date);
int dayofweek = cal.get(Calendar.DAY_OF_WEEK);
if (dayofweek == 1) {
dayofweek += 7;
}
cal.add(Calendar.DATE, 2 - dayofweek - 7);
return getDayStartTime(cal.getTime());
}
/**
* 获取上月的开始时间
*
* @return
*/
public static Date getBeginTimeOfLastMonth() {
Calendar calendar = Calendar.getInstance();
calendar.set(getNowYear(), getNowMonth() - 2, 1);
return getDayStartTime(calendar.getTime());
}
// 获取当天的开始时间
public static Date getBeginTimeOfDay() {
Calendar cal = new GregorianCalendar();
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
return cal.getTime();
}
// 获取当天的结束时间
public static Date getEndTimeOfDay() {
Calendar cal = new GregorianCalendar();
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
return cal.getTime();
}
public static String localTimeToString(Date date) {
StringBuilder sb = new StringBuilder("/Date(");
String dateString = JSON.toJSONString(date);
sb.append(dateString).append("+0800)/");
return sb.toString();
}
/**
* 获取开始时间
*
* @param startDate yyyy-MM-dd
* @param timePeriod
* @return
*/
public static String getStartTimeYYYYMMDD(String startDate, Integer timePeriod) {
switch (timePeriod) {
case 0:
return DateUtil.format(DateUtil.parse(startDate, DateUtil.DATE_PATTERN_YYYY_MM_DD), DateUtil.DATE_PATTERN_YYYY_MM_DD);
case 1:
return DateUtil.format(DateUtil.getBeginTimeOfWeek(), DateUtil.DATE_PATTERN_YYYY_MM_DD);
case 2:
return DateUtil.format(DateUtil.getBeginTimeOfMonth(), DateUtil.DATE_PATTERN_YYYY_MM_DD);
case 3:
return DateUtil.format(DateUtil.getBeginTimeOfYear(), DateUtil.DATE_PATTERN_YYYY_MM_DD);
case 4:
// 获取昨天的日期
return DateUtil.format(DateUtil.addDay(new Date(), -1), DateUtil.DATE_PATTERN_YYYY_MM_DD);
case 5:
// 获取前天的日期
return DateUtil.format(DateUtil.addDay(new Date(), -2), DateUtil.DATE_PATTERN_YYYY_MM_DD);
default:
return DateUtil.format(DateUtil.getBeginTimeOfDay(), DateUtil.DATE_PATTERN_YYYY_MM_DD);
}
}
/**
* 获取结束时间
*
* @param endDate yyyy-MM-dd
* @param timePeriod
* @return
*/
public static String getEndTimeYYYYMMDD(String endDate, Integer timePeriod) {
switch (timePeriod) {
case 0:
return DateUtil.format(DateUtil.parse(endDate, DateUtil.DATE_PATTERN_YYYY_MM_DD), DateUtil.DATE_PATTERN_YYYY_MM_DD);
case 1:
return DateUtil.format(DateUtil.getEndTimeOfWeek(), DateUtil.DATE_PATTERN_YYYY_MM_DD);
case 2:
return DateUtil.format(DateUtil.getEndTimeOfMonth(), DateUtil.DATE_PATTERN_YYYY_MM_DD);
case 3:
return DateUtil.format(DateUtil.getEndTimeOfYear(), DateUtil.DATE_PATTERN_YYYY_MM_DD);
case 4:
// 获取昨天的日期
return DateUtil.format(DateUtil.addDay(new Date(), -1), DateUtil.DATE_PATTERN_YYYY_MM_DD);
case 5:
// 获取前天的日期
return DateUtil.format(DateUtil.addDay(new Date(), -2), DateUtil.DATE_PATTERN_YYYY_MM_DD);
default:
return DateUtil.format(DateUtil.getEndTimeOfDay(), DateUtil.DATE_PATTERN_YYYY_MM_DD);
}
}
public static Date getDefaultDate(){
return DateUtil.parse("1900-01-01 00:00:00", DateUtil.DATE_PATTERN_YYYY_MM_DD_HH_MM_SS);
}
}
核心代码
/**
* @author pilgrim
*/
public class Demo {
/**
* 组装数据 统计每个月下共多少天
* @param startDayList
* @param dateStrDateMap
* @param map
* @return
*/
private static List<MonthDays> getMonthDays(List<String> startDayList, Map<String, Date> dateStrDateMap, Map<Integer, Map<Integer, List<List<String>>>> map) {
List<MonthDays> monthDaysList = new ArrayList<>(startDayList.size());
map.forEach((year,monthDaysLists)->{
monthDaysLists.forEach((key,daysList)->{
MonthDays monthDays = new MonthDays();
//简化后日
List<String> days = new ArrayList<>();
//元数据
List<List<String>> daysListList = new ArrayList<>();
daysListList.addAll(daysList);
monthDays.setList(daysListList);
//月份
monthDays.setMonth(key.toString());
int totalDays = 0;
for (List<String> stringList : daysList) {
if (stringList.size() == 1) {
totalDays += 1;
monthDays.setDays(days);
days.add(getDay(stringList.get(0),dateStrDateMap) + "");
continue;
}
int dayStart = getDay(stringList.get(0),dateStrDateMap);
int dayEnd = getDay(stringList.get(stringList.size() - 1),dateStrDateMap);
days.add(dayStart + "-" + dayEnd);
monthDays.setDays(days);
totalDays += stringList.size();
}
monthDays.setTotalDays(totalDays);
monthDaysList.add(monthDays);
});
});
return monthDaysList;
}
private static int getDay(String dateStr, Map<String,Date> dateStrDateMap ){
Date date = dateStrDateMap.get(dateStr);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int dayStart = calendar.get(Calendar.DAY_OF_MONTH);
return dayStart;
}
public static Map<String,Boolean> initDay(Date startDate,Date endDate,List<String> dateList, Map<String,Date> dateStrDateMap, Map<Date,String> dataDateStrMap){
Map<String,Boolean> dateMap = new LinkedHashMap<>();
while(startDate.getTime() <= endDate.getTime() ){
dateMap.put(DateUtil.date2String(startDate,DATE_PATTERN_YYYY_MM_DD),false);
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
calendar.add(Calendar.DAY_OF_MONTH,1);
startDate = calendar.getTime();
}
for (String date : dateList) {
if (dateMap.containsKey(date)) {
dateMap.put(date,true);
Date dateObj = string2Date(date, DATE_PATTERN_YYYY_MM_DD);
dateStrDateMap.put(date,dateObj);
dataDateStrMap.put(dateObj,date);
}
}
return dateMap;
}
public static List<List<String>> getDateList( Map<String,Boolean> dayMap){
StringJoiner xs = new StringJoiner("","","");
dayMap.forEach((x,y)->{
if (y){
xs.add(x);
xs.add(",");
}else {
xs.add("=");
}
});
List<List<String>> list = new ArrayList<>();
String[] split = xs.toString().split("=");
for (String dataList : split) {
String[] dataArray = dataList.split(",");
if (dataArray == null || dataArray.length == 0) {
continue;
}
List<String> dataStringList = new ArrayList<>();
for (String data : dataArray) {
if (StringUtils.isEmpty(data)) {
continue;
}
dataStringList.add(data);
}
list.add(dataStringList);
}
return list;
}
/**
* 分割数据 以及 排序月份对应的日期
* @param dayMap
* @param dateStrDateMap
* @param dataDateStrMap
* @return
*/
public static Map<Integer, Map<Integer, List<List<String>>>> dealAndSort(Map<String, Boolean> dayMap,Map<String,Date> dateStrDateMap, Map<Date,String> dataDateStrMap){
List<List<String>> dayListList = getDateList(dayMap);
//分割数据
List<List<String>> newList = getLists(dayListList, dateStrDateMap, dataDateStrMap);
//分割之后的数据
//System.out.println(newList);
//存储数据
Map<Integer, Map<Integer, List<List<String>>>> finaYearListMap = new LinkedHashMap<>(4);
List<Integer> years = new ArrayList<>();
for (List<String> stringList : dayListList) {
for (String s : stringList) {
Date date = dateStrDateMap.get(s);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
years.add(calendar.get(Calendar.YEAR));
}
}
//年
years = years.stream().distinct().sorted().collect(Collectors.toList());
Map<Integer,List<List<String> >> yearsDateList = new LinkedHashMap<>();
for (Integer year : years) {
List<List<String> > dateList = new ArrayList<>();
for (List<String> stringList : newList) {
String s1 = stringList.get(0);
if (s1.contains(year+"")) {
dateList.add(stringList);
}
}
yearsDateList.put(year,dateList);
}
for (Integer year : years) {
//年下的日期
List<List<String>> yearDateList = yearsDateList.get(year);
//年下 月下 日期
Map<Integer, List<List<String>>> finaMonthListMap = new LinkedHashMap<>();
for (List<String> stringList : yearDateList) {
//月份
int month = dateStrDateMap.get(stringList.get(0)).getMonth() + 1;
List<List<String>> lists = null;
if (finaMonthListMap.containsKey(month)) {
lists = finaMonthListMap.get(month);
}else {
lists = new ArrayList<>();
}
lists.add(stringList);
finaMonthListMap.put(month,lists);
}
finaYearListMap.put(year,finaMonthListMap);
}
return finaYearListMap;
}
public static void main(String[] args) {
List<String> startDayList = Arrays.asList("2021-01-01","2021-01-02","2021-01-03","2021-01-05","2021-11-01","2021-11-02","2021-11-03","2021-11-04"
,"2021-11-06","2021-11-07","2021-11-30",
"2021-12-01","2021-12-02",
"2021-12-30",
"2022-01-01",
"2022-01-02",
"2022-01-03",
"2022-01-06",
"2022-01-09",
"2022-01-30",
"2022-01-31",
"2022-02-01",
"2022-02-02",
"2022-05-01",
"2022-05-02",
"2022-05-05"
);
String endDays = startDayList.get(startDayList.size() - 1);
String startDay = startDayList.get(0);
//str -> Date
Map<String,Date> dateStrDateMap = new HashMap<>((int)(startDayList.size()/0.75) + 1);
//Date -> str
Map<Date,String> dataDateStrMap = new LinkedHashMap<>((int)(startDayList.size()/0.75) + 1);
Map<String, Boolean> dayMap = initDay(DateUtil.string2Date(startDay, DATE_PATTERN_YYYY_MM_DD), DateUtil.string2Date(endDays, DATE_PATTERN_YYYY_MM_DD), startDayList,dateStrDateMap,dataDateStrMap);
Map<Integer, Map<Integer, List<List<String>>>> map = dealAndSort(dayMap,dateStrDateMap,dataDateStrMap);
List<MonthDays> monthDaysList = getMonthDays(startDayList, dateStrDateMap, map);
System.out.println(JSON.toJSONString(monthDaysList));
}
/**
* 跨年夸月分割
* @param dayListList
* @param dateStrDateMap
* @param dataDateStrMap
* @return
*/
private static List<List<String>> getLists(List<List<String>> dayListList, Map<String, Date> dateStrDateMap, Map<Date, String> dataDateStrMap) {
List<List<String>> newList = new ArrayList<>();
for (List<String> stringList : dayListList) {
if (stringList.size() == 1) {
newList.add(stringList);
continue;
}
List<Date> dateObjeList = new ArrayList<>();
for (String s : stringList) {
dateObjeList.add(dateStrDateMap.get(s));
}
//先判断 月
List<Integer> month = dateObjeList.stream().map(x -> x.getMonth() + 1).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
if (CollectionUtils.isEmpty(month)){
continue;
}
if (month.size() == 1){
List<String> collect = dateObjeList.stream().map(x -> dataDateStrMap.get(x)).collect(Collectors.toList());
newList.add(collect);
continue;
}
//分组
Map<Integer, List<Date>> collect = dateObjeList.stream().collect(Collectors.groupingBy(x -> x.getMonth() + 1));
if (collect.size() == 0) {
continue;
}
//表示同月 不需要分数据
if (collect.size() == 1) {
newList.add(stringList);
continue;
}
//先按照年 去重防止是不同年份
List<Integer> years = new ArrayList<>();
for (Date date : dateObjeList) {
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
int year = calendar.get(Calendar.YEAR);
years.add(year);
}
years = years.stream().distinct().sorted().collect(Collectors.toList());
//System.out.println("年: " + years);
//不同年份 表示跨年
if (years.size() > 1) {
// 12 月在前面 1月再后
List<Date> month12List = collect.get(12);
if (CollectionUtils.isNotEmpty(month12List)){
List<String> month12StrList = month12List.stream().map(x -> dataDateStrMap.get(x)).collect(Collectors.toList());
newList.add(month12StrList);
collect.remove(12);
}
for (Integer mongth : collect.keySet()) {
List<String> dataList = collect.get(mongth).stream().map(x -> dataDateStrMap.get(x)).collect(Collectors.toList());
newList.add(dataList);
}
} else {
//同一年
for (Integer m : collect.keySet()) {
List<String> data = collect.get(m).stream().map(x -> dataDateStrMap.get(x)).collect(Collectors.toList());
newList.add(data);
}
}
}
return newList;
}
}
最后输出
[
{
"days":[
"1-3",
"5"
],
"list":[
[
"2021-01-01",
"2021-01-02",
"2021-01-03"
],
[
"2021-01-05"
]
],
"month":"1",
"totalDays":4
},
{
"days":[
"1-4",
"6-7",
"30"
],
"list":[
[
"2021-11-01",
"2021-11-02",
"2021-11-03",
"2021-11-04"
],
[
"2021-11-06",
"2021-11-07"
],
[
"2021-11-30"
]
],
"month":"11",
"totalDays":7
},
{
"days":[
"1-2",
"30"
],
"list":[
[
"2021-12-01",
"2021-12-02"
],
[
"2021-12-30"
]
],
"month":"12",
"totalDays":3
},
{
"days":[
"1-3",
"6",
"9",
"30-31"
],
"list":[
[
"2022-01-01",
"2022-01-02",
"2022-01-03"
],
[
"2022-01-06"
],
[
"2022-01-09"
],
[
"2022-01-30",
"2022-01-31"
]
],
"month":"1",
"totalDays":7
},
{
"days":[
"1-2"
],
"list":[
[
"2022-02-01",
"2022-02-02"
]
],
"month":"2",
"totalDays":2
},
{
"days":[
"1-2",
"5"
],
"list":[
[
"2022-05-01",
"2022-05-02"
],
[
"2022-05-05"
]
],
"month":"5",
"totalDays":3
}
]