YunaiV/yudao-cloud · error · IllegalArgumentException
Invalid interval: {}
Error message
Invalid interval: {} What it means
LocalDateTimeUtils.addTimeRange loops over an interval enum splitting a time span into day/week/month/quarter/year buckets. The switch's default branch throws IllegalArgumentException for any enum constant outside those five — this is a coding/extension error, not a data error.
Source
Thrown at yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java:338
case QUARTER:
while (startTime.isBefore(endTime)) {
int quarterOfYear = getQuarterOfYear(startTime);
LocalDateTime quarterEnd = quarterOfYear == 4
? startTime.with(TemporalAdjusters.lastDayOfYear()).plusDays(1).minusNanos(1)
: startTime.withMonth(quarterOfYear * 3 + 1).withDayOfMonth(1).minusNanos(1);
timeRanges.add(new LocalDateTime[]{startTime, quarterEnd});
startTime = quarterEnd.plusNanos(1);
}
break;
case YEAR:
while (startTime.isBefore(endTime)) {
LocalDateTime endOfYear = startTime.with(TemporalAdjusters.lastDayOfYear()).plusDays(1).minusNanos(1);
timeRanges.add(new LocalDateTime[]{startTime, endOfYear});
startTime = endOfYear.plusNanos(1);
}
break;
default:
throw new IllegalArgumentException("Invalid interval: " + interval);
}
// 3. 兜底,最后一个时间,需要保持在 endTime 之前
LocalDateTime[] lastTimeRange = CollUtil.getLast(timeRanges);
if (lastTimeRange != null) {
lastTimeRange[1] = endTime;
}
return timeRanges;
}
/**
* 获取从开始日期起的日期列表
*
* @param startDate 开始日期
* @param days 天数
* @return 日期列表,包含开始日期
*/
public static List<LocalDate> getDateList(LocalDate startDate, int days) {
List<LocalDate> dateList = new ArrayList<>(days);View on GitHub (pinned to 477be9dd49)
Solutions
- Pass only DAY, WEEK, MONTH, QUARTER or YEAR to this method.
- If a coarser/finer bucket is needed, add an explicit case instead of reusing an unhandled constant.
- Convert before calling: e.g. aggregate HOUR data upstream and call with DAY.
- Add a unit test enumerating all enum constants against this method so new constants fail the build, not production.
Example fix
// before List<LocalDateTime[]> ranges = LocalDateTimeUtils.addTimeRange(start, end, IntervalEnum.HOUR); // after List<LocalDateTime[]> ranges = LocalDateTimeUtils.addTimeRange(start, end, IntervalEnum.DAY);
Defensive patterns
Strategy: type-guard
Validate before calling
Set<IntervalEnum> supported = EnumSet.of(DAY, WEEK, MONTH, QUARTER, YEAR);
if (!supported.contains(interval)) throw new IllegalArgumentException("Unsupported interval: " + interval); Type guard
static boolean isSupportedInterval(IntervalEnum i) {
return i == IntervalEnum.DAY || i == IntervalEnum.WEEK || i == IntervalEnum.MONTH
|| i == IntervalEnum.QUARTER || i == IntervalEnum.YEAR;
} Prevention
- Expose only supported granularities from API DTOs (enum validation on input)
- Add an exhaustive-switch unit test over all enum constants so new constants fail CI
When it happens
Trigger: Calling the method with an interval enum value such as HOUR or MINUTE (present in many interval enums but not handled here), or after someone adds a new constant (e.g. HALF_YEAR) to the enum without extending the switch.
Common situations: Reusing a generic TimeIntervalEnum across features where chart aggregation only supports day..year; adding enum constants in a PR without touching this utility; copy-pasting the util for a new report and passing an unsupported granularity.
Related errors
AI-assisted analysis of YunaiV/yudao-cloud@477be9dd49 (2026-08-14).
Data as JSON: /api/errors/ccec7c9371a3e1a4.
Report an issue: GitHub.