{"record":{"id":"8d7bff9650c90a31","repo":"stanfordnlp/CoreNLP","slug":"begin-and-end-are-equal","errorCode":null,"errorMessage":"begin and end are equal ","messagePattern":"begin and end are equal ","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/edu/stanford/nlp/time/Timex.java","lineNumber":513,"sourceCode":"      int dayRange = Integer.parseInt(this.val.substring(1, this.val.length() - 1));\n\n      // in the future\n      if (this.beginPoint < this.endPoint) {\n        Calendar start = copyCalendar(rc);\n        Calendar end = copyCalendar(rc);\n        end.add(Calendar.DAY_OF_MONTH, dayRange);\n        return new Pair<>(start, end);\n      }\n\n      // in the past\n      if (this.beginPoint > this.endPoint) {\n        Calendar start = copyCalendar(rc);\n        Calendar end = copyCalendar(rc);\n        start.add(Calendar.DAY_OF_MONTH, 0 - dayRange);\n        return new Pair<>(start, end);\n      }\n\n      throw new RuntimeException(\"begin and end are equal \" + this);\n    }\n\n    // YYYYSP\n    if (Pattern.matches(\"\\\\d+SP\", this.val)) {\n      int year = Integer.parseInt(this.val.substring(0, 4));\n      Calendar start = makeCalendar(year, 2, 1);\n      Calendar end = makeCalendar(year, 4, 31);\n      return new Pair<>(start, end);\n    }\n    // YYYYSU\n    if (Pattern.matches(\"\\\\d+SU\", this.val)) {\n      int year = Integer.parseInt(this.val.substring(0, 4));\n      Calendar start = makeCalendar(year, 5, 1);\n      Calendar end = makeCalendar(year, 7, 31);\n      return new Pair<>(start, end);\n    }\n    // YYYYFA\n    if (Pattern.matches(\"\\\\d+FA\", this.val)) {","sourceCodeStart":495,"sourceCodeEnd":531,"githubUrl":"https://github.com/stanfordnlp/CoreNLP/blob/1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a/src/edu/stanford/nlp/time/Timex.java#L495-L531","documentation":"Third variant of the 'begin and end are equal' invariant, for day durations P##D: when the dayRange parsed from the val is 0, start and end both equal the document time and getRange throws RuntimeException.","triggerScenarios":"Calling getRange(documentTime) on a Timex val matching P\\\\d+D with 0 days (e.g. 'P0D').","commonSituations":"Zero-day durations appearing in TimeML annotations or produced by a misconfigured normalizer.","solutions":["Fix upstream annotation to not emit P0D","Treat P0D as a point at documentTime.getDate()","Catch RuntimeException and build a zero-width Pair around documentTime","Pre-validate with val.matches(\"P0+D\")"],"exampleFix":"// before\nPair<Calendar,Calendar> range = timex.getRange(documentTime);\n// after\nif (timex.val().matches(\"P0+D\")) {\n  Calendar now = documentTime.getDate();\n  Pair<Calendar,Calendar> range = new Pair<>(now, now);\n} else {\n  Pair<Calendar,Calendar> range = timex.getRange(documentTime);\n}","handlingStrategy":"validation","validationCode":"if (timex.val() != null && timex.val().matches(\"P0+D\")) { handleAsPoint(); }","typeGuard":null,"tryCatchPattern":"try { range = timex.getRange(docTime); } catch (RuntimeException e) { range = new Pair<>(docTime.getDate(), docTime.getDate()); }","preventionTips":["Reject or special-case zero-length durations early","Pass a non-null documentTime when handling durations","Wrap getRange in batch jobs with per-Timex error handling"],"tags":["java","timex","duration"],"backgroundTag":"invalid-argument-value","analyzedSha":"1b7edd19c4d0d7b1f13a2591425b9b60a0b1af7a","analyzedAt":"2026-09-10T02:24:07.274Z","contentChangedAt":"2026-09-10T02:24:07.274Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}