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);
	}

	@Override

View on GitHub (pinned to 8870454b2a)

Solutions

  1. Convert the value to Date, Calendar, or long (millis) before formatting: Date.from(instant), Date.from(LocalDateTime.atZone(zone).toInstant()), or instant.toEpochMilli().
  2. Guard against null and throw a domain-specific exception earlier.
  3. 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

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


AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14). Data as JSON: /api/errors/2e63c6206908885a. Report an issue: GitHub.