输出指定日期区间内的所有天、周、月
部分方法需要依赖hutool工具包。
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>4.5.10</version>
</dependency>`
需求:输出2023-04-17到2023-05-23期间所有的天、周、月。
天:2023-04-17、2023-04-18、…2023-05-23
周:202317(第17周)、202318(第18周)…
周的范围(周日作为每周第一天):2023-04-17至2023-04-23、2023-04-24至2023-04-30…
周的范围(周一作为每周第一天):2023-04-23至2023-04-29、2023-04-30至2023-05-06…
月:2023-04、2023-05
输入输出yyyy-MM-dd格式
String startDateString = "2023-04-23";
String endDateString = "2023-05-07";
输出这两个日期之间所有的日期
输入输出yyyy-MM-dd格式
public static List<String> getDatesBetween(String startDateString, String endDateString) {List<DateTime> datesBetween = DateUtil.rangeToList(DateUtil.parseDate(startDateString), DateUtil.parseDate(endDateString), DateField.DAY_OF_MONTH);return datesBetween.stream().map(p -> DateUtil.format(p, DatePattern.NORM_DATE_PATTERN)).collect(Collectors.toList());
}
测试:
System.out.println("getDatesBetween:"+ JSON.toJSONString(getDatesBetween(startDateString,endDateString)));
输出:
getDatesBetween:["2023-04-23","2023-04-24","2023-04-25","2023-04-26","2023-04-27","2023-04-28","2023-04-29","2023-04-30","2023-05-01","2023-05-02","2023-05-03","2023-05-04","2023-05-05","2023-05-06","2023-05-07"]
输出这两个日期之间所有的周(数字)
比如:[“202318”,“202319”] 表示2023年第18、19周
public static List<String> getWeeksBetween(String startDateString, String endDateString) {// 这种情况必须重置结束日期,结束日期最好改成这周的最后一天,不然会丢失最后不足一周的数据endDateString = DateUtil.format(DateUtil.endOfWeek(DateUtil.parse(endDateString)), DatePattern.NORM_DATE_PATTERN);List<DateTime> datesBetween = DateUtil.rangeToList(DateUtil.parseDate(startDateString), DateUtil.parseDate(endDateString), DateField.WEEK_OF_YEAR);return datesBetween.stream().map(p -> String.format("%d%02d", DateUtil.year(p), DateUtil.weekOfYear(p))).collect(Collectors.toList());
}
我在测试的时候发现,如果结束日期不是这周的最后一天,它可能会少一周数据,所以直接重置结束日期。
测试:
System.out.println("getMonthsBetween:"+ JSON.toJSONString(getMonthsBetween(startDateString,endDateString)));
输出:
getWeeksBetween:["202317","202318","202319"]
输出这两个日期之间所有的周(周一为每周的第一天)
比如:[“2023-04-24至2023-04-30”,“2023-05-01至2023-05-07”]
public static List<String> getWeeksMonBetween(String startDateString, String endDateString) {return getWeeksBetween(startDateString, endDateString, Calendar.MONDAY);
}private static List<String> getWeeksBetween(String startDateString, String endDateString ,int firstDay) {Date startDate = DateUtil.parse(startDateString);Date endDate = DateUtil.parse(endDateString);List<String> weekStartDates = new ArrayList<>();Calendar calendar = Calendar.getInstance();calendar.setTime(startDate);while (calendar.getTime().compareTo(endDate) <= 0) {// 获取当前日期所在周的起始日期int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);int diff = (dayOfWeek - firstDay + 7) % 7;calendar.add(Calendar.DAY_OF_YEAR, -diff);String weekStart = DateUtil.format(calendar.getTime(), DatePattern.NORM_DATE_PATTERN);// 获取当前日期所在周的结束日期calendar.add(Calendar.DAY_OF_YEAR, 6);String weekEnd = DateUtil.format(calendar.getTime(), DatePattern.NORM_DATE_PATTERN);weekStartDates.add(weekStart + "至" + weekEnd);// 将日期移动到下一周的起始日期calendar.add(Calendar.DAY_OF_YEAR, 1);}return weekStartDates;
}
测试:
System.out.println("getWeeksMonBetween:"+ JSON.toJSONString(getWeeksMonBetween(startDateString,endDateString)));
输出:
getWeeksMonBetween:["2023-04-17至2023-04-23","2023-04-24至2023-04-30","2023-05-01至2023-05-07"]
输出这两个日期之间所有的周(周日为一周的第一天)
比如:[“2023-04-24至2023-04-30”,“2023-05-01至2023-05-07”]
public static List<String> getWeeksSunBetween(String startDateString, String endDateString) {return getWeeksBetween(startDateString, endDateString, Calendar.SUNDAY);
}
还是调用上边的方法,只是参数换成Calendar.SUNDAY
。
测试:
System.out.println("getWeeksSunBetween:"+ JSON.toJSONString(getWeeksSunBetween(startDateString,endDateString)));
输出:
getWeeksSunBetween:["2023-04-23至2023-04-29","2023-04-30至2023-05-06","2023-05-07至2023-05-13"]
输出这两个日期之间所有的月
比如:[“2023-04”,“2023-05”]
public static List<String> getMonthsBetween(String startDateString, String endDateString) {// 这种情况必须重置结束日期,结束日期最好改成这月的最后一天endDateString = DateUtil.format(DateUtil.endOfMonth(DateUtil.parse(endDateString)), DatePattern.NORM_DATE_PATTERN);List<DateTime> datesBetween = DateUtil.rangeToList(DateUtil.parseDate(startDateString), DateUtil.parseDate(endDateString), DateField.MONTH);return datesBetween.stream().map(p -> DateUtil.format(p, "yyyy-MM")).collect(Collectors.toList());
}
测试:
System.out.println("getMonthsBetween:"+ JSON.toJSONString(getMonthsBetween(startDateString,endDateString)));
输出:
getMonthsBetween:["2023-04","2023-05"]
输出这两个日期之间所有的周(周一为每周的第一天)方案B
private static List<String> getWeeksMonBetweenPlanB(String startDateString, String endDateString) {// 这种情况必须重置结束日期,结束日期最好改成这周的最后一天endDateString = DateUtil.format(DateUtil.endOfWeek(DateUtil.parse(endDateString)), DatePattern.NORM_DATE_PATTERN);List<DateTime> datesBetween = DateUtil.rangeToList(DateUtil.parseDate(startDateString), DateUtil.parseDate(endDateString), DateField.WEEK_OF_YEAR);return datesBetween.stream().map(p -> {String startOfWeek = DateUtil.format(DateUtil.beginOfWeek(p), DatePattern.NORM_DATE_PATTERN);String endOfWeek = DateUtil.format(DateUtil.endOfWeek(p), DatePattern.NORM_DATE_PATTERN);return startOfWeek + "至" + endOfWeek;}).collect(Collectors.toList());
}
测试:
System.out.println("getWeeksMonBetweenPlanB:"+ JSON.toJSONString(getWeeksMonBetweenPlanB(startDateString,endDateString)));
输出:
getWeeksMonBetweenPlanB:["2023-04-17至2023-04-23","2023-04-24至2023-04-30","2023-05-01至2023-05-07"]
完整工具类
package com.test.util;import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;/*** @Description: 日期范围工具* @title: DateRangeUtil* @Date: 2023/5/23 16:06* @Version 1.0*/
public class DateRangeUtil {/*** 输出这两个日期之间所有的日期 yyyy-MM-dd格式* @param startDateString* @param endDateString* @return*/public static List<String> getDatesBetween(String startDateString, String endDateString) {List<DateTime> datesBetween = DateUtil.rangeToList(DateUtil.parseDate(startDateString), DateUtil.parseDate(endDateString), DateField.DAY_OF_MONTH);return datesBetween.stream().map(p -> DateUtil.format(p, DatePattern.NORM_DATE_PATTERN)).collect(Collectors.toList());}/*** 输出这两个日期之间所有的周(数字) 比如:["202318","202319"] 表示2023年第18、19周* @param startDateString* @param endDateString* @return*/public static List<String> getWeeksBetween(String startDateString, String endDateString) {// 这种情况必须重置结束日期,结束日期最好改成这周的最后一天,不然会丢失最后不足一周的数据endDateString = DateUtil.format(DateUtil.endOfWeek(DateUtil.parse(endDateString)), DatePattern.NORM_DATE_PATTERN);List<DateTime> datesBetween = DateUtil.rangeToList(DateUtil.parseDate(startDateString), DateUtil.parseDate(endDateString), DateField.WEEK_OF_YEAR);return datesBetween.stream().map(p -> String.format("%d%02d", DateUtil.year(p), DateUtil.weekOfYear(p))).collect(Collectors.toList());}/*** 输出这两个日期之间所有的周(周一为一周的第一天) 比如:["2023-04-24至2023-04-30","2023-05-01至2023-05-07"]* @param startDateString* @param endDateString* @return*/public static List<String> getWeeksMonBetween(String startDateString, String endDateString) {return getWeeksBetween(startDateString, endDateString, Calendar.MONDAY);}/*** 输出这两个日期之间所有的周(周日为一周的第一天) 比如:["2023-04-24至2023-04-30","2023-05-01至2023-05-07"]* @param startDateString* @param endDateString* @return*/public static List<String> getWeeksSunBetween(String startDateString, String endDateString) {return getWeeksBetween(startDateString, endDateString, Calendar.SUNDAY);}private static List<String> getWeeksBetween(String startDateString, String endDateString ,int firstDay) {Date startDate = DateUtil.parse(startDateString);Date endDate = DateUtil.parse(endDateString);List<String> weekStartDates = new ArrayList<>();Calendar calendar = Calendar.getInstance();calendar.setTime(startDate);while (calendar.getTime().compareTo(endDate) <= 0) {// 获取当前日期所在周的起始日期int dayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);int diff = (dayOfWeek - firstDay + 7) % 7;calendar.add(Calendar.DAY_OF_YEAR, -diff);String weekStart = DateUtil.format(calendar.getTime(), DatePattern.NORM_DATE_PATTERN);// 获取当前日期所在周的结束日期calendar.add(Calendar.DAY_OF_YEAR, 6);String weekEnd = DateUtil.format(calendar.getTime(), DatePattern.NORM_DATE_PATTERN);weekStartDates.add(weekStart + "至" + weekEnd);// 将日期移动到下一周的起始日期calendar.add(Calendar.DAY_OF_YEAR, 1);}return weekStartDates;}/*** 输出这两个日期之间所有的月 比如:["2023-04","2023-05"]* @param startDateString* @param endDateString* @return*/public static List<String> getMonthsBetween(String startDateString, String endDateString) {// 这种情况必须重置结束日期,结束日期最好改成这月的最后一天endDateString = DateUtil.format(DateUtil.endOfMonth(DateUtil.parse(endDateString)), DatePattern.NORM_DATE_PATTERN);List<DateTime> datesBetween = DateUtil.rangeToList(DateUtil.parseDate(startDateString), DateUtil.parseDate(endDateString), DateField.MONTH);return datesBetween.stream().map(p -> DateUtil.format(p, "yyyy-MM")).collect(Collectors.toList());}// B方案 未使用private static List<String> getWeeksMonBetweenPlanB(String startDateString, String endDateString) {// 这种情况必须重置结束日期,结束日期最好改成这周的最后一天endDateString = DateUtil.format(DateUtil.endOfWeek(DateUtil.parse(endDateString)), DatePattern.NORM_DATE_PATTERN);List<DateTime> datesBetween = DateUtil.rangeToList(DateUtil.parseDate(startDateString), DateUtil.parseDate(endDateString), DateField.WEEK_OF_YEAR);return datesBetween.stream().map(p -> {String startOfWeek = DateUtil.format(DateUtil.beginOfWeek(p), DatePattern.NORM_DATE_PATTERN);String endOfWeek = DateUtil.format(DateUtil.endOfWeek(p), DatePattern.NORM_DATE_PATTERN);return startOfWeek + "至" + endOfWeek;}).collect(Collectors.toList());}public static void main(String[] args) {String startDateString = "2023-04-23";String endDateString = "2023-05-07";System.out.println("getDatesBetween:"+ JSON.toJSONString(getDatesBetween(startDateString,endDateString)));System.out.println("getWeeksMonBetween:"+ JSON.toJSONString(getWeeksMonBetween(startDateString,endDateString)));System.out.println("getWeeksSunBetween:"+ JSON.toJSONString(getWeeksSunBetween(startDateString,endDateString)));System.out.println("getWeeksBetween:"+ JSON.toJSONString(getWeeksBetween(startDateString,endDateString)));System.out.println("getMonthsBetween:"+ JSON.toJSONString(getMonthsBetween(startDateString,endDateString)));System.out.println("getWeeksMonBetweenPlanB:"+ JSON.toJSONString(getWeeksMonBetweenPlanB(startDateString,endDateString)));}}