Java按经理报表时段筛选记录的优化方案咨询
优化按报表时段筛选记录的重复代码方案
我需要将记录发送至其他系统,但得依据不同经理的报表时段筛选发送。比如周二要获取周一6:00至周二6:00创建的记录,用于周二7:00的报表。目前的实现需要重复编写不同时段的判断代码,想找更优的实现方式,系统用Date库记录事件日期。
当前代码:
Date disturbanceDate = disruptionEventEntity.getDisturbanceDate(); Calendar now = Calendar.getInstance(); now.setTime(disturbanceDate); Calendar before = Calendar.getInstance(); before.set(Calendar.HOUR_OF_DAY, 6); before.set(Calendar.MINUTE, 0); before.set(Calendar.DAY_OF_WEEK,Calendar.MONDAY); Calendar after = Calendar.getInstance(); after.set(Calendar.HOUR_OF_DAY, 6); after.set(Calendar.MINUTE, 0); after.set(Calendar.DAY_OF_WEEK, Calendar.TUESDAY); boolean between = now.before(after) && now.after(before); if (between){ // 将符合条件的记录发送到集成系统 }
方案1:封装通用判断方法
把时段判断逻辑封装成可复用方法,通过传入起始星期、结束星期、时段小时参数来复用逻辑,彻底避免重复代码。
示例代码:
/** * 判断事件日期是否在指定报表时段内 * @param eventDate 事件日期 * @param startWeekday 时段起始星期(如Calendar.MONDAY) * @param endWeekday 时段结束星期(如Calendar.TUESDAY) * @param hourOfDay 时段的小时点(如6) * @return 是否在目标时段内 */ private boolean isInReportPeriod(Date eventDate, int startWeekday, int endWeekday, int hourOfDay) { Calendar eventCal = Calendar.getInstance(); eventCal.setTime(eventDate); // 构造起始时间:指定星期的hourOfDay点,清零分秒毫秒 Calendar startCal = Calendar.getInstance(); startCal.set(Calendar.HOUR_OF_DAY, hourOfDay); startCal.set(Calendar.MINUTE, 0); startCal.set(Calendar.SECOND, 0); startCal.set(Calendar.MILLISECOND, 0); startCal.set(Calendar.DAY_OF_WEEK, startWeekday); // 构造结束时间:同起始时间规则 Calendar endCal = Calendar.getInstance(); endCal.set(Calendar.HOUR_OF_DAY, hourOfDay); endCal.set(Calendar.MINUTE, 0); endCal.set(Calendar.SECOND, 0); endCal.set(Calendar.MILLISECOND, 0); endCal.set(Calendar.DAY_OF_WEEK, endWeekday); // 处理跨周情况(比如周日6点到周一6点) if (endCal.before(startCal)) { endCal.add(Calendar.WEEK_OF_YEAR, 1); } return eventCal.after(startCal) && eventCal.before(endCal); }
调用示例:
Date disturbanceDate = disruptionEventEntity.getDisturbanceDate(); // 周二报表:筛选周一6点到周二6点的记录 boolean shouldSend = isInReportPeriod(disturbanceDate, Calendar.MONDAY, Calendar.TUESDAY, 6); if (shouldSend) { // 发送记录到集成系统 } // 其他时段调用示例:周三报表用周二6点到周三6点 // boolean shouldSend = isInReportPeriod(disturbanceDate, Calendar.TUESDAY, Calendar.WEDNESDAY, 6);
方案2:用枚举统一管理报表规则
如果经理的报表时段是固定配置,可以把每个规则定义成枚举,集中管理更易维护,后续新增或修改时段只需调整枚举即可。
示例代码:
enum ReportPeriod { MANAGER_A(Calendar.MONDAY, Calendar.TUESDAY, 6, "周二7点报表"), MANAGER_B(Calendar.TUESDAY, Calendar.WEDNESDAY, 6, "周三7点报表"), MANAGER_C(Calendar.SUNDAY, Calendar.MONDAY, 6, "周一7点报表"); private final int startWeekday; private final int endWeekday; private final int hourOfDay; private final String desc; ReportPeriod(int startWeekday, int endWeekday, int hourOfDay, String desc) { this.startWeekday = startWeekday; this.endWeekday = endWeekday; this.hourOfDay = hourOfDay; this.desc = desc; } // 内置时段判断逻辑 public boolean isInPeriod(Date eventDate) { Calendar eventCal = Calendar.getInstance(); eventCal.setTime(eventDate); Calendar startCal = Calendar.getInstance(); startCal.set(Calendar.HOUR_OF_DAY, hourOfDay); startCal.set(Calendar.MINUTE, 0); startCal.set(Calendar.SECOND, 0); startCal.set(Calendar.MILLISECOND, 0); startCal.set(Calendar.DAY_OF_WEEK, startWeekday); Calendar endCal = Calendar.getInstance(); endCal.set(Calendar.HOUR_OF_DAY, hourOfDay); endCal.set(Calendar.MINUTE, 0); endCal.set(Calendar.SECOND, 0); endCal.set(Calendar.MILLISECOND, 0); endCal.set(Calendar.DAY_OF_WEEK, endWeekday); if (endCal.before(startCal)) { endCal.add(Calendar.WEEK_OF_YEAR, 1); } return eventCal.after(startCal) && eventCal.before(endCal); } }
调用示例:
Date disturbanceDate = disruptionEventEntity.getDisturbanceDate(); // 给经理A的报表筛选符合条件的记录 if (ReportPeriod.MANAGER_A.isInPeriod(disturbanceDate)) { // 发送记录到集成系统 }
注意事项
Calendar.DAY_OF_WEEK的取值规则:周日为1,周一为2,……,周六为7,需确认系统默认的星期起始设置是否符合业务需求。- 两种方案都处理了跨周时段的边界情况,避免结束时间早于起始时间导致的判断错误。
内容的提问来源于stack exchange,提问作者Siya Nxuseka
相关产品推荐
相关产品推荐

