{"record":{"id":"de74d24cac92d6cb","repo":"languagetool-org/languagetool","slug":"expected-date-in-format-yyyy-mm-dd-datestr","errorCode":null,"errorMessage":"Expected date in format 'yyyy-mm-dd': '\" + dateString + \"'","messagePattern":"Expected date in format 'yyyy-mm-dd': '\" \\+ dateString \\+ \"'","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/YMDDateHelper.java","lineNumber":38,"sourceCode":"\nimport java.util.Map;\n\n/**\n * @since 4.3\n */\npublic class YMDDateHelper {\n\n  public YMDDateHelper() {\n  }\n\n  public Map<String, String> parseDate(Map<String, String> args) {\n    String dateString = args.get(\"date\");\n    if (dateString == null) {\n      throw new IllegalArgumentException(\"Missing key 'date'\");\n    }\n    String[] parts = dateString.split(\"-\");\n    if (parts.length != 3) {\n      throw new RuntimeException(\"Expected date in format 'yyyy-mm-dd': '\" + dateString + \"'\");\n    }\n    args.put(\"year\", parts[0]);\n    args.put(\"month\", parts[1]);\n    args.put(\"day\", parts[2]);\n    return args;\n  }\n\n  public RuleMatch correctDate(RuleMatch match, Map<String, String> args) {\n    String year = args.get(\"year\");\n    String month = args.get(\"month\");\n    String day = args.get(\"day\");\n    int correctYear = Integer.parseInt(year) + 1;\n    String correctDate = String.format(\"%d-%s-%s\", correctYear, month, day);\n    String message = match.getMessage()\n            .replace(\"{realDate}\", correctDate);\n    RuleMatch ruleMatch = new RuleMatch(match.getRule(), match.getSentence(), match.getFromPos(),\n            match.getToPos(), message, match.getShortMessage());\n    ruleMatch.setType(match.getType());","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/YMDDateHelper.java#L20-L56","documentation":"YMDDateHelper.parseDate splits the 'date' value on '-' and requires exactly 3 parts (year, month, day). This RuntimeException is thrown when the date string does not have the yyyy-mm-dd shape (wrong separator, missing fields, or extra dashes).","triggerScenarios":"Passing a 'date' argument like '2026/12/31', '20261231', '31.12.2026', or a malformed value with more than two dashes (e.g. '2026-12-31-x').","commonSituations":"Locale-formatted dates pasted into rule XML; using slashes instead of hyphens; dynamic dates generated in a different format by upstream code.","solutions":["Format the 'date' value as exactly yyyy-mm-dd, e.g. '2026-12-31'.","Replace alternate separators ('/', '.') with '-'.","If generating the date programmatically, use a formatter with pattern yyyy-MM-dd and zero-padded fields."],"exampleFix":"// before\n<filter class=\"...YMDDateHelper\" date=\"2026/12/31\"/>\n// after\n<filter class=\"...YMDDateHelper\" date=\"2026-12-31\"/>","handlingStrategy":"validation","validationCode":"// validate date format before use\nString date = args.get(\"date\");\nif (date != null && !date.matches(\"\\\\d{4}-\\\\d{2}-\\\\d{2}\"))\n    throw new IllegalArgumentException(\"date must be yyyy-mm-dd: \" + date);","typeGuard":null,"tryCatchPattern":"try { helper.parseDate(args); } catch (RuntimeException e) { log.error(\"Invalid date value: \" + e.getMessage()); throw e; }","preventionTips":["Always use hyphens and zero-padded yyyy-MM-dd","Generate dates with DateTimeFormatter.ofPattern(\"yyyy-MM-dd\")","Never paste locale-formatted dates into rule XML"],"tags":["java","date-format","argument-validation","languagetool"],"backgroundTag":"invalid-date-format","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}