使用Calendar实现自定义规则生成动态日期

使用Calendar实现自定义规则生成动态日期

1、支持配置的规则、配置含义
配置规则:Y(年)、M(月)、W(周)、D(日)
配置字段:subjectStart(标的开始类型)、subjectEnd(标的结束类型)
配置含义:如subjectStart(Y+1),subjectEnd(Y+1)-->从当前年份的次年1月1日开始,执行周期为一年,到次年年底结束的日期。如subjectStart(M-3),subjectEnd(M+4)-->从当前月份的前3个月开始,到执行周期为4个月结束的日期,依次类推。
支持通过提供开始日期,根据配置规则生成结束日期
2、根据配置规则,生成对应的开始、结束日期。看代码
    /**
     * 根据配置的规则,生成默认的开始日期、标的结束日期
     * 通过标的约束时段计算日期
     *
     * @param model
     * @return
     */
    public BaseResponse computeDefaultTargetDate(DynamicDateVO model) {
        if(StringUtils.isBlank(model.getSubjectStart()) || StringUtils.isBlank(model.getSubjectEnd())){
            return baseUtilService.setResultError("配置的规则不能为空");
        }
        String targetStartType = model.getSubjectStart().substring(0,1);
        String targetEndType = model.getSubjectEnd().substring(0,1);
        int parseIntStartParam = Integer.parseInt(model.getSubjectStart().substring(1));
        int parseIntEndParam = parseIntStartParam + Integer.parseInt(model.getSubjectEnd().substring(1));
        if(StringUtils.isBlank(targetStartType) || StringUtils.isBlank(targetEndType) || !targetStartType.equals(targetEndType)){
            return baseUtilService.setResultError("配置规则的类型不一致");
        }
        Integer calendarType = null;
        String formatParam = "";
        if("Y".equals(targetStartType)){
            //年
            calendarType = Calendar.YEAR;
            formatParam = "yyyy";
        }else if ("M".equals(targetStartType)){
            //月
            calendarType = Calendar.MONTH;
            formatParam = "yyyy-MM";
        }else if("W".equals(targetStartType)){
            //周
            calendarType = Calendar.WEEK_OF_YEAR;
            formatParam = "yyyy-MM-dd";
        }else if ("D".equals(targetStartType)){
            //日
            calendarType = Calendar.DAY_OF_MONTH;
            formatParam = "yyyy-MM-dd";
        } else {
            return baseUtilService.setResultError("当前标的类型暂不支持");
        }
        ComputeTime computeTime = computeTime(model.getSubjectStart(), model.getSubjectEnd(), calendarType,formatParam);
        return baseUtilService.setResult(GetSetCode.HTTP_RES_CODE_200,"默认标的时段计算成功",computeTime);
    }
    
    
    /**
     * 生成开始/结束日期
     * @author yanyapan
     */
    @Data
    public class ComputeTime implements Serializable {

        private static final long serialVersionUID = 1L;

        private String startTime;

        private String endTime;

    }
    
    
        /**
     * 根据标的时段计算默认时间
     * @param targetStartTime
     * @param targetEndTime
     * @param calendarType 日期类型
     * @param formatParam 日期格式类型
     * @return
     */
    private  ComputeTime computeTime(String targetStartTime, String targetEndTime, int calendarType,String formatParam){
        ComputeTime computeTime = new ComputeTime();
        //截取类型后面的参数
        int targetStartParam = Integer.parseInt(targetStartTime.substring(1));
        int targetEndParam = Integer.parseInt(targetEndTime.substring(1));
        DateFormat format = new SimpleDateFormat(formatParam);
        Calendar startCalendar = Calendar.getInstance();
        startCalendar.setTime(new Date());
        startCalendar.add(calendarType, targetStartParam);
        Date startDate = startCalendar.getTime();
        
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(startDate);
        endCalendar.add(calendarType, targetEndParam-1);
        Date endDate = endCalendar.getTime();
        if(Calendar.YEAR == calendarType){
            //年
            computeTime.setStartTime(format.format(startDate) + "-01-01");
            computeTime.setEndTime(format.format(endDate) + "-12-31");
        }else if(Calendar.MONTH == calendarType){
            //月
            int startTimeSetYear = Integer.parseInt(format.format(startDate).substring(0, 4));
            int startTimeSetMonth = Integer.parseInt(format.format(startDate).substring(5));
            int endTimeSetYear = Integer.parseInt(format.format(endDate).substring(0, 4));
            int endTimeSetMonth = Integer.parseInt(format.format(endDate).substring(5));
            computeTime.setStartTime(format.format(startDate) + "-" + "01");
            computeTime.setEndTime(format.format(endDate) + "-" + getDaysByYearMonth(endTimeSetYear,endTimeSetMonth));
        }else if(Calendar.WEEK_OF_YEAR == calendarType){
            //周
            //查看当前日期是年份内的第几周
            TargetItem targetItem = whatWeek(format.format(new Date()));
            computeTime.setStartTime(getStartDayOfWeekNo(targetItem.getYear(),targetItem.getWeek() + targetStartParam));
            computeTime.setEndTime(getEndDayOfWeekNo(targetItem.getYear(),targetItem.getWeek() + targetStartParam + targetEndParam - 1));
        }else {
            //日
            computeTime.setStartTime(format.format(startDate));
            computeTime.setEndTime(format.format(endDate));
        }
        return computeTime;
    }
    
    
    /**
    * 当配置类型为W(周)时,获取对应的周和年份
    *
    */
    @Data
    public class TargetItem {

        private int year;

        private int week;
    }
    
    
    private TargetItem whatWeek(String datetime) {
        TargetItem targetItem = new TargetItem();
        int year = Integer.parseInt(datetime.substring(0, 4));

        //获取过去7天的日期
        String pastDate = getPastDate(7, strToDate(datetime));

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date parsePastDate = null;
        try {
            parsePastDate = format.parse(pastDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        Calendar calendarPast = Calendar.getInstance();
        calendarPast.setFirstDayOfWeek(Calendar.MONDAY);
        calendarPast.setTime(parsePastDate);
        Integer pastWeekNumbe = calendarPast.get(Calendar.WEEK_OF_YEAR);

        Date currentDate = null;
        try {
            currentDate = format.parse(datetime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.setTime(currentDate);
        Integer weekNumbe = calendar.get(Calendar.WEEK_OF_YEAR);

        if(pastWeekNumbe >= 52){
            targetItem.setYear(year + 1);
            targetItem.setWeek(weekNumbe);
        }else{
            targetItem.setYear(year);
            targetItem.setWeek(weekNumbe);
        }
        return targetItem;
    }
    
    /**
     * 获取指定年份、周对应的开始日期
     */
    private String getStartDayOfWeekNo(int year,int weekNo) {
        Calendar cal = getCalendarFormYear(year);
        cal.set(Calendar.WEEK_OF_YEAR, weekNo);
        Date time = cal.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String dateTime = format.format(time);
        return dateTime;
    }

   /**
     * 获取指定年份、周对应的结束日期
     */
    private String getEndDayOfWeekNo(int year,int weekNo) {
        Calendar cal = getCalendarFormYear(year);
        cal.set(Calendar.WEEK_OF_YEAR, weekNo);
        cal.add(Calendar.DAY_OF_WEEK, 6);
        Date time = cal.getTime();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String dateTime = format.format(time);
        return dateTime;
    }
    
    /**
     * 根据年 月 获取对应的月份 天数
     * 
     */
    private int getDaysByYearMonth(int year, int month) {
        Calendar a = Calendar.getInstance();
        a.set(Calendar.YEAR, year);
        a.set(Calendar.MONTH, month - 1);
        a.set(Calendar.DATE, 1);
        a.roll(Calendar.DATE, -1);
        int maxDate = a.get(Calendar.DATE);
        return maxDate;
    }
    /**
     * 日期转date
     * @param str
     * @return
     */
    private Date strToDate(String str) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = format.parse(str);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
3、根据配置的日期、规则自动生成结束日期
    /**
     * 根据配置的日期、规则,结束日期自动生成
     *
     * @param dynamicDateVO
     * @return
     */
    public BaseResponse computeDynamicDateTime(DynamicDateVO dynamicDateVO) {
        if(StringUtils.isBlank(dynamicDateVO.getDeclareStartTime())){
            return baseUtilService.setResultError("配置开始日期不能为空");
        }
        if(StringUtils.isBlank(dynamicDateVO.getSubjectStart()) || StringUtils.isBlank(dynamicDateVO.getSubjectEnd())){
            return baseUtilService.setResultError("配置规则类型不能为空");
        }
        String targetStartType = dynamicDateVO.getSubjectStart().substring(0,1);
        String targetEndType = dynamicDateVO.getSubjectEnd().substring(0,1);
        Integer calendarType = null;
        if("Y".equals(targetStartType)){
            //年
            calendarType = Calendar.YEAR;
            if(!dynamicDateVO.getDeclareStartTime().substring(5).equals("01-01")){
                return baseUtilService.setResultError("当前规则时段是年,开始时间请设置为选择年份的1月1日");
            }
        }else if ("M".equals(targetStartType)){
            //月
            calendarType = Calendar.MONTH;
            if(!dynamicDateVO.getDeclareStartTime().substring(8).equals("01")){
                return baseUtilService.setResultError("当前配置规则时段是月,开始时间请设置为选择月份的1日");
            }
        }else if("W".equals(targetStartType)){
            //周
            calendarType = Calendar.WEEK_OF_YEAR;
        }else if ("D".equals(targetStartType)){
            //日
            calendarType = Calendar.DAY_OF_MONTH;
        } else {
            return baseUtilService.setResultError("当前配置规则类型类型暂不支持");
        }
        DynamicDateVO dynamicDate = computeTime(dynamicDateVO.getDeclareStartTime(), dynamicDateVO.getSubjectStart(), dynamicDateVO.getSubjectEnd(), calendarType);
        return baseUtilService.setResult(GetSetCode.HTTP_RES_CODE_200,"结束日期生成成功",dynamicDate);
    }
    
    
    /**
     * 当标的时段日期发生变动时,标的结束日期自动生成
     * @param chooseTime
     * @param targetStartTime
     * @param targetEndTime
     * @param calendarType
     * @return
     */
    private  DynamicDateVO computeTime(String chooseTime,String targetStartTime,String targetEndTime,int calendarType){
        DynamicDateVO dynamicDateVO = new DynamicDateVO();

        String formatParam = "";
        Calendar startCalendar = Calendar.getInstance();
        DateFormat format = null;
        if(Calendar.YEAR == calendarType){
            formatParam = "yyyy";
            format = new SimpleDateFormat(formatParam);
            try {
                startCalendar.setTime(format.parse(chooseTime.substring(0,4)));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }else if(Calendar.MONTH == calendarType){
            formatParam = "yyyy-MM";
            format = new SimpleDateFormat(formatParam);
            try {
                startCalendar.setTime(format.parse(chooseTime));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }else if(Calendar.WEEK_OF_YEAR == calendarType){
            formatParam = "yyyy-MM-dd";
            format = new SimpleDateFormat(formatParam);
            try {
                startCalendar.setTime(format.parse(chooseTime));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }else if(Calendar.DAY_OF_MONTH == calendarType){
            formatParam = "yyyy-MM-dd";
            format = new SimpleDateFormat(formatParam);
            try {
                startCalendar.setTime(format.parse(chooseTime));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        //截取类型后面的参数
        int targetStartParam = Integer.parseInt(targetStartTime.substring(1));
        int targetEndParam = Integer.parseInt(targetEndTime.substring(1));

        Date startDate = startCalendar.getTime();
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(startDate);
        endCalendar.add(calendarType, targetEndParam-1);
        Date endDate = endCalendar.getTime();
        if(calendarType == Calendar.YEAR){
            dynamicDateVO.setDeclareStartTime(chooseTime);
            dynamicDateVO.setDeclareEndTime(format.format(endDate) + "-12-31");
        }
        if(calendarType == Calendar.MONTH){
            int endTimeSetYear = Integer.parseInt(format.format(endDate).substring(0, 4));
            int endTimeSetMonth = Integer.parseInt(format.format(endDate).substring(5));
            dynamicDateVO.setDeclareStartTime(chooseTime);
            dynamicDateVO.setDeclareEndTime(format.format(endDate) + "-" + getDaysByYearMonth(endTimeSetYear,endTimeSetMonth));
        }
        if(calendarType == Calendar.WEEK_OF_YEAR){
            TargetItem targetItem = whatWeek(chooseTime);
            dynamicDateVO.setDeclareStartTime(chooseTime);
            dynamicDateVO.setDeclareEndTime(getEndDayOfWeekNo(targetItem.getYear(),targetItem.getWeek() + targetEndParam - 1));
        }
        if(calendarType == Calendar.DAY_OF_MONTH){
            dynamicDateVO.setDeclareStartTime(chooseTime);
            dynamicDateVO.setDeclareEndTime(format.format(endDate));
        }
        return dynamicDateVO;
    }
    


/**
 * 当标的开始日期发生变化时,标的结束日期自动变化
 */
@Data
public class DynamicDateVO implements Serializable {

    /**
     * 配置开始时间
     */
    private String declareStartTime;

    /**
     * 配置结束时间
     */
    private String declareEndTime;

    /**
     * 配置类型规则
     */
    private String subjectStart;

    /**
     * 配置类型规则
     */
    private String subjectEnd;
}
4、总结
  • 该日期配置规则工具类使用Calendar封装,在开发中也学习参考了corn日期表达式。
  • 对开发工具API的使用熟练程度,对解决问题来说有一定的影响。深入理解,对遇到问题设计解决方案时有事半功倍的作用。
posted @ 2020-03-30 09:57  yanyapan  阅读(897)  评论(0编辑  收藏  举报