chinabugotech/hutool · error · IllegalArgumentException
Unknown class: {}
Error message
Unknown class: {} What it means
FastDatePrinter.format(Object) only accepts Date, Calendar, or Long (epoch millis). Any other type, including null, throws IllegalArgumentException reporting the offending class name (or '<null>').
Source
Thrown at hutool-core/src/main/java/cn/hutool/core/date/format/FastDatePrinter.java:310
// -----------------------------------------------------------------------
/**
* <p>
* Formats a {@code Date}, {@code Calendar} or {@code Long} (milliseconds) object.
* </p>
*
* @param obj the object to format
* @return The formatted value.
*/
String format(Object obj) {
if (obj instanceof Date) {
return format((Date) obj);
} else if (obj instanceof Calendar) {
return format((Calendar) obj);
} else if (obj instanceof Long) {
return format(((Long) obj).longValue());
} else {
throw new IllegalArgumentException("Unknown class: " + (obj == null ? "<null>" : obj.getClass().getName()));
}
}
@Override
public String format(long millis) {
final Calendar c = Calendar.getInstance(timeZone, locale);
c.setTimeInMillis(millis);
return applyRulesToString(c);
}
@Override
public String format(Date date) {
final Calendar c = Calendar.getInstance(timeZone, locale);
c.setTime(date);
return applyRulesToString(c);
}
@OverrideView on GitHub (pinned to 8870454b2a)
Solutions
- Convert the value to Date, Calendar, or long (millis) before formatting: Date.from(instant), Date.from(LocalDateTime.atZone(zone).toInstant()), or instant.toEpochMilli().
- Guard against null and throw a domain-specific exception earlier.
- Use DateUtil.formatDate / DateUtil.format with the correctly typed overload.
Example fix
// before
FastDateFormat fdf = FastDateFormat.getInstance("yyyy-MM-dd");
String s = fdf.format(java.time.LocalDate.now()); // throws
// after
String s = fdf.format(java.sql.Date.valueOf(java.time.LocalDate.now()));
// or
String s = fdf.format(Date.from(java.time.LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant())); Defensive patterns
Strategy: type-guard
Validate before calling
boolean isFormattable(Object o){ return o instanceof Date || o instanceof Calendar || o instanceof Long; } Type guard
boolean canFormat(Object o){ return o != null && (o instanceof java.util.Date || o instanceof java.util.Calendar || o instanceof Long); } Try / catch
try { s = fdf.format(obj); }
catch (IllegalArgumentException e){ if(e.getMessage().startsWith("Unknown class")) { s = fdf.format(toDate(obj)); } else throw e; } Prevention
- Convert java.time values to Date/long before formatting.
- Never pass null to format(Object); branch on null first.
- Use the typed format(Date)/format(long) overloads.
When it happens
Trigger: Passing an Integer, String, BigInteger, java.time types (LocalDate/Instant), or null to a FastDateFormat.format(Object) overload; reflective/generic code that forwards arbitrary objects to the formatter.
Common situations: Mixing java.time (Instant/LocalDateTime) with the legacy Date API; passing epoch as int instead of long; null values from upstream optional fields.
Related errors
- Illegal pattern component: {}
- Unterminated quote
- (The {} locale does not support dates before 1868 AD) Unpars
- Unparseable date: {}
- Format '{}' not supported
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/2e63c6206908885a.
Report an issue: GitHub.