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

  1. Convert the reference date to ISO 8601 (yyyy-MM-ddTHH:mm:ss) before passing it.
  2. Catch the RuntimeException and retry with null refDate so the extractor skips date anchoring.
  3. Use the SUTime.ISO_DATE_FORMAT-style pattern (or Joda ISODateTimeFormat) to format your Date object instead of toString().
  4. 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

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)