stanfordnlp/CoreNLP · error · RuntimeException

Could not parse date string

Error message

Could not parse date string: [${docDate}]

What it means

Thrown when the document date string passed to extractTimeExpressionCoreMaps cannot be parsed by SUTime.parseDateTime into a usable date. The CoreMap extraction pipeline needs a reference date to resolve relative temporal expressions (e.g. "next week"), and an unparseable docDate makes that impossible. It is wrapped in a RuntimeException so it escapes as an unchecked failure during annotation.

Solutions

  1. Normalize docDate to ISO 8601 (yyyy-MM-dd or full ISO datetime) before calling the extractor.
  2. Catch the RuntimeException and re-run extraction with docDate=null so expressions resolve against no reference date.
  3. Pre-validate the string with a strict date parser (Joda DateTimeFormat or java.time) and sanitize before annotation.
  4. Prepend a century if the string is 6 digits (yyyy can be omitted per the source TODO).

Example fix

// before
String docDate = metadata.get("creation-date"); // "Mar 3, 2020"
extractor.extractTimeExpressionCoreMaps(annotation, docDate, timeIndex);

// after
String docDate = metadata.get("creation-date");
DateTime dt = DateTimeFormat.forPattern("MMM d, yyyy").parseDateTime(docDate);
String iso = ISODateTimeFormat.date().print(dt); // "2020-03-03"
extractor.extractTimeExpressionCoreMaps(annotation, iso, timeIndex);
Defensive patterns

Strategy: validation

Validate before calling

static boolean isValidDocDate(String s) {
  if (s == null) return true; // null is allowed
  try { ISODateTimeFormat.dateParser().parseDateTime(s); return true; }
  catch (IllegalArgumentException e) { return false; }
}

Try / catch

try {
  extractor.extractTimeExpressionCoreMaps(annotation, docDate, timeIndex);
} catch (RuntimeException e) {
  if (e.getMessage() != null && e.getMessage().startsWith("Could not parse date string")) {
    extractor.extractTimeExpressionCoreMaps(annotation, null, timeIndex); // degrade gracefully
  } else throw e;
}

Prevention

When it happens

Trigger: Calling TimeExpressionExtractorImpl.extractTimeExpressionCoreMaps(annotation, docDate, timeIndex) with a docDate string that is not in an ISO-8601-like format SUTime accepts (e.g. "March 3rd, 2020", "03/2020", empty-but-non-null string).

Common situations: DocDate annotation populated by a custom document reader from a non-ISO header field (PDF metadata, email Date headers, news article bylines), or dates missing the century (e.g. "990304"), a case the TODO comments explicitly flag.

Related errors


AI-assisted analysis of stanfordnlp/CoreNLP@1b7edd19c4 (2026-09-10). Data as JSON: /api/errors/8054a72c76175698. Report an issue: GitHub.

Appendix: source

Thrown at src/edu/stanford/nlp/time/TimeExpressionExtractorImpl.java:101

          }
        } else {
          SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd:hh:mm:ss");
          docDate = dateFormat.format(cal.getTime());
        }
      }
    } else {
      timeIndex = new SUTime.TimeIndex();
    }
    if (StringUtils.isNullOrEmpty(docDate)) {
      docDate = null;
    }
    if (timeIndex.docDate == null && docDate != 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
        timeIndex.docDate = SUTime.parseDateTime(docDate,true);
      } catch (Exception e) {
        throw new RuntimeException("Could not parse date string: [" + docDate + "]", e);
      }
    }
    String sectionDate = annotation.get(CoreAnnotations.SectionDateAnnotation.class);
    String refDate = (sectionDate != null) ? sectionDate: docDate;
    return extractTimeExpressionCoreMaps(annotation, refDate, timeIndex);
  }

  @Override
  public List<CoreMap> extractTimeExpressionCoreMaps(CoreMap annotation, String docDate) {
    SUTime.TimeIndex timeIndex = new SUTime.TimeIndex();
    return extractTimeExpressionCoreMaps(annotation, docDate, timeIndex);
  }

  public List<CoreMap> extractTimeExpressionCoreMaps(CoreMap annotation, String docDate, SUTime.TimeIndex timeIndex) {
    List<TimeExpression> timeExpressions = extractTimeExpressions(annotation, docDate, timeIndex);
    return toCoreMaps(annotation, timeExpressions, timeIndex);
  }

View on GitHub (pinned to 1b7edd19c4)