import lombok.extern.slf4j.Slf4j;
import java.text.SimpleDateFormat;
import java.util.*;
@Slf4j
public class DateUtils {
public static String DATE_FORMAT_MONTH = "yyyy-MM";
public static String DATE_FORMAT_DAY = "yyyy-MM-dd";
/**
* 获取日期范围内每一月
*
* @param startDateString 日期开始
* @param endDateString 日期结束
* @return 日期范围内每一月
*/
public static Map<String, Object> getEveryMonth(String startDateString, String endDateString) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_MONTH);
Map<String, Object> dateMap = new LinkedHashMap<>(16);
try {
Date startDate = sdf.parse(startDateString);
Date endDate = sdf.parse(endDateString);
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
dateMap.put(startDateString.substring(0, 7), null);
// 开始日期月份不断加1,直到大于结束日期
while (endDate.after(calendar.getTime())) {
calendar.add(Calendar.MONTH, 1);
dateMap.put(sdf.format(calendar.getTime()), null);
}
} catch (Exception e) {
log.error("获取日期范围内每一月异常");
}
return dateMap;
}
/**
* 获取日期范围内每一周
*
* @param startDateString 日期开始
* @param endDateString 日期结束
* @return 日期范围内每一周
*/
public static Map<MonthAndWeek, Object> getEveryWeek(String startDateString, String endDateString) {
SimpleDateFormat monthSdf = new SimpleDateFormat(DATE_FORMAT_MONTH);
SimpleDateFormat daySdf = new SimpleDateFormat(DATE_FORMAT_DAY);
Map<MonthAndWeek, Object> dateMap = new LinkedHashMap<>(16);
try {
Date startDate = daySdf.parse(startDateString);
Date endDate = daySdf.parse(endDateString);
Calendar calendar = Calendar.getInstance();
// 设置一周的第一天为星期一,默认为星期日
calendar.setFirstDayOfWeek(Calendar.MONDAY);
calendar.setTime(startDate);
// 开始日期所在月份特殊处理(首月)
MonthAndWeek startMonthAndWeek = new MonthAndWeek();
String startMonth = startDateString.substring(0, 7);
startMonthAndWeek.setMonth(startMonth);
int startWeek = calendar.get(Calendar.WEEK_OF_MONTH);
// 判断当月最后一天所属周数
int startMonthLastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
Calendar startMonthLastDayCalendar = (Calendar) calendar.clone();
startMonthLastDayCalendar.set(Calendar.DAY_OF_MONTH, startMonthLastDay);
int endWeek = startMonthLastDayCalendar.get(Calendar.WEEK_OF_MONTH);
// 循环添加每一周
for (int i = startWeek; i <= endWeek; i++) {
MonthAndWeek monthAndWeek = new MonthAndWeek();
monthAndWeek.setMonth(startMonth);
monthAndWeek.setWeekOfMonth(String.valueOf(i));
dateMap.put(monthAndWeek, null);
}
// 开始日期月份不断加1,直到大于结束日期
while (endDate.after(calendar.getTime())) {
calendar.add(Calendar.MONTH, 1);
// 判断当月最后一天所属周数
int lastDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
Calendar lastDayCalendar = (Calendar) calendar.clone();
lastDayCalendar.set(Calendar.DAY_OF_MONTH, lastDay);
// 当月最后一天大于结束日期时,替换为结束日期
if (lastDayCalendar.getTime().compareTo(endDate) > 0) {
lastDayCalendar.setTime(endDate);
}
int week = lastDayCalendar.get(Calendar.WEEK_OF_MONTH);
// 循环添加每一周
for (int i = 1; i <= week; i++) {
MonthAndWeek monthAndWeek = new MonthAndWeek();
String month = monthSdf.format(lastDayCalendar.getTime());
monthAndWeek.setMonth(month);
monthAndWeek.setWeekOfMonth(String.valueOf(i));
dateMap.put(monthAndWeek, null);
}
}
} catch (Exception e) {
log.error("获取日期范围内每一周异常");
}
return dateMap;
}
/**
* 获取日期范围内每一天
*
* @param startDateString 日期开始
* @param endDateString 日期结束
* @return 日期范围内每一天
*/
public static Map<String, Object> getEveryDay(String startDateString, String endDateString) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_DAY);
Map<String, Object> dateMap = new LinkedHashMap<>(16);
try {
Date startDate = sdf.parse(startDateString);
Date endDate = sdf.parse(endDateString);
Calendar calendar = Calendar.getInstance();
calendar.setTime(startDate);
dateMap.put(startDateString, null);
// 开始日期天数不断加1,直到大于结束日期
while (endDate.after(calendar.getTime())) {
calendar.add(Calendar.DAY_OF_MONTH, 1);
dateMap.put(sdf.format(calendar.getTime()), null);
}
} catch (Exception e) {
log.error("获取日期范围内每一天异常");
}
return dateMap;
}
}
import lombok.Data;
import java.util.Objects;
@Data
public class MonthAndWeek {
/**
* 年月(yyyy-MM)
*/
private String month;
/**
* 所属当月周数
*/
private String weekOfMonth;
@Override
public int hashCode(){
// 需注意字段为空时会报空指针
return month.hashCode() + weekOfMonth.hashCode();
}
@Override
public boolean equals(Object o){
return (o instanceof MonthAndWeek)
&& (Objects.equals(month, ((MonthAndWeek) o).month))
&& (Objects.equals(weekOfMonth, ((MonthAndWeek) o).weekOfMonth));
}
}
import java.util.Map;
public class MyTest {
public static void main(String[] args) {
Map<String, Object> monthMap = DateUtils.getEveryMonth("2022-12", "2023-09");
System.out.println(monthMap.keySet());
Map<MonthAndWeek, Object> weekMap = DateUtils.getEveryWeek("2022-12-12", "2023-01-02");
System.out.println(weekMap.keySet());
Map<String, Object> dayMap = DateUtils.getEveryDay("2022-12-12", "2023-01-02");
System.out.println(dayMap.keySet());
}
}
[2022-12, 2023-01, 2023-02, 2023-03, 2023-04, 2023-05, 2023-06, 2023-07, 2023-08, 2023-09]
[MonthAndWeek(month=2022-12, weekOfMonth=3), MonthAndWeek(month=2022-12, weekOfMonth=4), MonthAndWeek(month=2022-12, weekOfMonth=5), MonthAndWeek(month=2023-01, weekOfMonth=1), MonthAndWeek(month=2023-01, weekOfMonth=2)]
[2022-12-12, 2022-12-13, 2022-12-14, 2022-12-15, 2022-12-16, 2022-12-17, 2022-12-18, 2022-12-19, 2022-12-20, 2022-12-21, 2022-12-22, 2022-12-23, 2022-12-24, 2022-12-25, 2022-12-26, 2022-12-27, 2022-12-28, 2022-12-29, 2022-12-30, 2022-12-31, 2023-01-01, 2023-01-02]
注意:
1.基于个人业务开发,用于展示前端图表的X轴和填充数据,请根据需求自行调整返回类型与计算逻辑。如有优化建议或实用工具类欢迎指出。
2.周的计算是以星期一为一周开始,对首尾进行特殊处理。如上图所示,4月3号是当月第2周,4月27号是第5周,每月有4-6周,如果以7天为一周需另行调整。