chinabugotech/hutool · error · ParseException
Unparseable date: {}
Error message
Unparseable date: {} What it means
The generic parse failure: FastDateParser.parse(String, ParsePosition) returned null because the input string did not match the configured pattern (or could not be fully consumed). The exception carries the original source string and the ParsePosition error index.
Source
Thrown at hutool-core/src/main/java/cn/hutool/core/date/format/FastDateParser.java:222
*/
private void readObject(final ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
final Calendar definingCalendar = Calendar.getInstance(timeZone, locale);
init(definingCalendar);
}
@Override
public Date parse(String source) throws ParseException {
final ParsePosition pp = new ParsePosition(0);
final Date date = parse(source, pp);
if (date == null) {
// Add a note re supported date range
if (locale.equals(JAPANESE_IMPERIAL)) {
throw new ParseException("(The " + locale + " locale does not support dates before 1868 AD)\n" +
"Unparseable date: \"" + source, pp.getErrorIndex());
}
throw new ParseException("Unparseable date: " + source, pp.getErrorIndex());
}
return date;
}
@Override
public Date parse(String source, ParsePosition pos) {
// timing tests indicate getting new instance is 19% faster than cloning
final Calendar cal = Calendar.getInstance(timeZone, locale);
cal.clear();
return parse(source, pos, cal) ? cal.getTime() : null;
}
@Override
public boolean parse(String source, ParsePosition pos, Calendar calendar) {
final ListIterator<StrategyAndWidth> lt = patterns.listIterator();
while (lt.hasNext()) {
final StrategyAndWidth strategyAndWidth = lt.next();View on GitHub (pinned to 8870454b2a)
Solutions
- Align the pattern to the actual input format (verify separators, field lengths, AM/PM markers, timezone tokens).
- Normalize/sanitize input before parsing (trim, convert separators).
- When multiple formats are possible, try them in sequence or use DateUtil.parse with auto-detection instead of a strict pattern.
- Inspect the ParsePosition error index from a lower-level parse call to locate the exact mismatch column.
Example fix
// before
Date d = DateUtil.parse("2024/01/01", "yyyy-MM-dd");
// after
Date d = DateUtil.parse("2024-01-01", "yyyy-MM-dd");
// or align pattern to input:
Date d = DateUtil.parse("2024/01/01", "yyyy/MM/dd"); Defensive patterns
Strategy: try-catch
Validate before calling
void assertMatchesFormat(String src, String pattern){
try { new SimpleDateFormat(pattern).parse(src); } catch (ParseException e){ throw new IllegalArgumentException("source does not match "+pattern+" at col "+e.getErrorOffset()); }
} Try / catch
try { d = DateUtil.parse(source, pattern); }
catch (Exception e) { log.warn("bad date '{}', using null", source); d = null; } Prevention
- Sanitize input (trim, normalize separators) before parsing.
- When the input format is unknown, try multiple candidate patterns.
- Log the error offset to localize mismatches quickly.
When it happens
Trigger: Calling DateUtil.parse(source, pattern) where source does not conform to pattern; partial matches (e.g. pattern 'yyyy-MM-dd' against '2024/01/01'); trailing characters; non-numeric tokens where numbers expected; out-of-range values (month 13, hour 25).
Common situations: Mismatched separators (- vs /), wrong field order, user-typed input, data exported from another system with a different default format, daylight-saving/timezone edge cases producing invalid local times.
Related errors
- Unterminated quote
- Format '{}' not supported
- (The {} locale does not support dates before 1868 AD) Unpars
- invalid number of X
- Illegal pattern component: {}
AI-assisted analysis of chinabugotech/hutool@8870454b2a (2026-08-14).
Data as JSON: /api/errors/589d159ab8176d20.
Report an issue: GitHub.