stanfordnlp/CoreNLP · error · RuntimeException
Could not parse date string
Error message
Could not parse date string: [${refDateStr}] What it means
Thrown by extractTimeExpressions when the reference date string cannot be parsed by SUTime.parseDateTime. The refDate anchors all relative time expressions in the annotated text; a bad string aborts extraction. Same root cause as the docDate variant, but on the String-based overload used by timeExpressions().
Solutions
- Convert the reference date to ISO 8601 (yyyy-MM-ddTHH:mm:ss) before passing it.
- Catch the RuntimeException and retry with null refDate so the extractor skips date anchoring.
- Use the SUTime.ISO_DATE_FORMAT-style pattern (or Joda ISODateTimeFormat) to format your Date object instead of toString().
- Pre-validate with DateTimeFormat.forPattern(...).parseDateTime(refDateStr) in a try-catch and fall back.
Example fix
// before String ref = new Date().toString(); // "Tue Sep 08 ... PDT 2020" extractor.extractTimeExpressions(annotation, ref, timeIndex); // after String ref = ISODateTimeFormat.dateTime().print(new DateTime()); // "2026-09-09T12:00:00.000" extractor.extractTimeExpressions(annotation, ref, timeIndex);
Defensive patterns
Strategy: validation
Validate before calling
static boolean isValidRefDate(String s) {
if (s == null) return true;
try { ISODateTimeFormat.dateTimeParser().parseDateTime(s); return true; }
catch (IllegalArgumentException e) { return false; }
} Try / catch
try {
return extractor.extractTimeExpressions(annotation, refDateStr, timeIndex);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Could not parse date string")) {
return extractor.extractTimeExpressions(annotation, (String) null, timeIndex);
} else throw e;
} Prevention
- Format reference dates with ISODateTimeFormat, never Date.toString().
- Unit-test rule pipelines with representative refDate strings from your data source.
- Centralize refDate construction in one utility that guarantees ISO output.
When it happens
Trigger: Calling extractTimeExpressions(annotation, refDateStr, timeIndex) (or timeExpressions(annotation, refDateStr)) with refDateStr like "today", "2020", "Tue Sep 8 00:12:33 PDT 2020" — anything Joda-time ISO parsing with lenient=false cannot handle.
Common situations: Feeding Java Date.toString() output, locale-formatted dates, or partial dates from Tika/document metadata into the SUTime pipeline.
Related errors
AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10).
Data as JSON: /api/errors/fcc8036496f7e18f.
Report an issue: GitHub.
Appendix: source
Thrown at src/edu/stanford/nlp/time/TimeExpressionExtractorImpl.java:182
continue;
}
assert timex != null; // Timex.fromMap never returns null and if it exceptions, we've already done a continue
cm.set(TimeAnnotations.TimexAnnotation.class, timex);
coreMaps.add(cm);
}
}
return coreMaps;
}
public List<TimeExpression> extractTimeExpressions(CoreMap annotation, String refDateStr, SUTime.TimeIndex timeIndex) {
SUTime.Time refDate = null;
if (refDateStr != null) {
try {
// TODO: have more robust parsing of document date? docDate may not have century....
// TODO: if docDate didn't change, we can cache the parsing of the docDate and not repeat it for every sentence
refDate = SUTime.parseDateTime(refDateStr,true);
} catch (Exception e) {
throw new RuntimeException("Could not parse date string: [" + refDateStr + "]", e);
}
}
return extractTimeExpressions(annotation, refDate, timeIndex);
}
public List<TimeExpression> extractTimeExpressions(CoreMap annotation, SUTime.Time refDate, SUTime.TimeIndex timeIndex) {
if (!annotation.containsKey(CoreAnnotations.NumerizedTokensAnnotation.class)) {
try {
List<CoreMap> mergedNumbers = NumberNormalizer.findAndMergeNumbers(annotation);
annotation.set(CoreAnnotations.NumerizedTokensAnnotation.class, mergedNumbers);
} catch (NumberFormatException e) {
logger.warn("Caught bad number: " + e.getMessage());
annotation.set(CoreAnnotations.NumerizedTokensAnnotation.class, new ArrayList<>());
}
}
List<? extends MatchedExpression> matchedExpressions = expressionExtractor.extractExpressions(annotation);
List<TimeExpression> timeExpressions = new ArrayList<>(matchedExpressions.size());View on GitHub (pinned to 1b7edd19c4)