生成报表时计算报表的截止上报时间
背景
每张报表有个截止上报时间,截止时间的计算稍微复杂,下面记录一下自己的写作成果。当月月报截止时间下月xx号,当季季报截止时间下季第一个月。。。
数据结构
public enum ReportFrequencyEnum { YEAR("year", "年"), MONTH("month", "月"), HALF_YEAR("half_year", "半年"), SEASON("season", "季"); ReportFrequencyEnum(String code, String name) { this.code = code; this.name = name; } private String code; private String name; public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } /** * 获取指定code的报表频率 * * @param code 报表频率code * @return */ public static ReportFrequencyEnum codeOf(String code) { for (ReportFrequencyEnum reportFrequencyEnum : ReportFrequencyEnum.values()) { if (reportFrequencyEnum.getCode().equals(code)) { return reportFrequencyEnum; } } log.warn("找不到指定code的报表频率,code={}", code); return null; } }
@Data @ApiModel("报表时间") public class ReportTime { @NotNull @ApiModelProperty("年") private Integer year; @ApiModelProperty("月(1-12)") private Integer month; @ApiModelProperty("季(1-4)") private Integer season; @ApiModelProperty("半年(上/下)") private String halfYear; }
/** * 报表上报截止时间配置 * <p> * 示例:配置月报上报截止时间为下月18号 * [{ * "frequency":"month", * "monthAdd":0, * "day":18 * }] * * @author wanghuidong * @date 2022/5/21 21:29 */ @Data public class ReportDeadlineTimeConfig { /** * 频度 */ private String frequency; /** * 月度增量 */ private Integer monthAdd; /** * 几号 */ private Integer day; }
算法
/** * 计算报表上报截止时间 * * @param reportFrequencyEnum 报表频度 * @param reportTime 报表时间 * @param reportDeadlineTimeConfigs 报表截止时间配置 * @return 截止时间 */ private Date calculateReportDeadlineTime(ReportFrequencyEnum reportFrequencyEnum, ReportTime reportTime, List<ReportDeadlineTimeConfig> reportDeadlineTimeConfigs) { //当前时间 DateTime dateTime = DateTime.now(); if (reportTime != null) { //指定报表时间计算截止时间 switch (reportFrequencyEnum) { case YEAR: //当年年报下年截止 dateTime.setField(DateField.YEAR, reportTime.getYear() + 1); dateTime = DateUtil.truncate(dateTime, DateField.YEAR); break; case MONTH: //当月月报下月截止 dateTime.setField(DateField.YEAR, reportTime.getYear()); dateTime.setField(DateField.MONTH, reportTime.getMonth() - 1); dateTime.offset(DateField.MONTH, 1); dateTime = DateUtil.truncate(dateTime, DateField.MONTH); break; case SEASON: //当季季报下季截止 dateTime.setField(DateField.YEAR, reportTime.getYear()); switch (reportTime.getSeason()) { case 1: //1季报,2季度截止 dateTime.setField(DateField.MONTH, 3); break; case 2: //2季报,3季度截止 dateTime.setField(DateField.MONTH, 6); break; case 3: //3季报,4季度截止 dateTime.setField(DateField.MONTH, 9); break; case 4: //4季报,下一年1季度截止 dateTime.offset(DateField.YEAR, 1); dateTime.setField(DateField.MONTH, 0); break; default: break; } dateTime = DateUtil.truncate(dateTime, DateField.MONTH); break; case HALF_YEAR: dateTime.setField(DateField.YEAR, reportTime.getYear()); switch (reportTime.getHalfYear()) { case "上": //上半年报,下半年第一个月截止 dateTime.setField(DateField.MONTH, 6); break; case "下": //下半年报,下一年1月份截止 dateTime.offset(DateField.YEAR, 1); dateTime.setField(DateField.MONTH, 0); break; default: break; } dateTime = DateUtil.truncate(dateTime, DateField.MONTH); break; default: break; } } //默认上报截止时间设置未15号,补报时间不超过28号 dateTime.setField(DateField.DAY_OF_MONTH, 15); //采用配置的时间 if (CollUtil.isNotEmpty(reportDeadlineTimeConfigs)) { ReportDeadlineTimeConfig reportDeadlineTimeConfig = reportDeadlineTimeConfigs.stream() .filter(x -> x.getFrequency() .equals(reportFrequencyEnum.getCode())) .findFirst() .orElse(null); if (reportDeadlineTimeConfig != null) { if (reportDeadlineTimeConfig.getMonthAdd() != null) { dateTime.offset(DateField.MONTH, reportDeadlineTimeConfig.getMonthAdd()); } if (reportDeadlineTimeConfig.getDay() != null) { int configDay = reportDeadlineTimeConfig.getDay(); //如果配置的天 大于 本月最后一天,则设置为最后一天(如31,2月则有可能是28号或29号,小月是30号,大月才是31号) if (configDay > dateTime.getLastDayOfMonth()) { configDay = dateTime.getLastDayOfMonth(); } dateTime.setField(DateField.DAY_OF_MONTH, configDay); } } } //设置时间为:23:59:59 dateTime = DateUtil.ceiling(dateTime, DateField.DAY_OF_MONTH, true); return dateTime.toJdkDate(); }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库