{"record":{"id":"0a25a9ee1ace3043","repo":"chinabugotech/hutool","slug":"invalid-number-of-x-0a25a9","errorCode":null,"errorMessage":"invalid number of X","messagePattern":"invalid number of X","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hutool-core/src/main/java/cn/hutool/core/date/format/FastDatePrinter.java","lineNumber":1226,"sourceCode":"\t\t// Sign TwoDigitHours : Minutes or Z\n\t\tstatic final Iso8601_Rule ISO8601_HOURS_COLON_MINUTES = new Iso8601_Rule(6);\n\n\t\t/**\n\t\t * Factory method for Iso8601_Rules.\n\t\t *\n\t\t * @param tokenLen a token indicating the length of the TimeZone String to be formatted.\n\t\t * @return a Iso8601_Rule that can format TimeZone String of length {@code tokenLen}. If no such rule exists, an IllegalArgumentException will be thrown.\n\t\t */\n\t\tstatic Iso8601_Rule getRule(int tokenLen) {\n\t\t\tswitch (tokenLen) {\n\t\t\t\tcase 1:\n\t\t\t\t\treturn Iso8601_Rule.ISO8601_HOURS;\n\t\t\t\tcase 2:\n\t\t\t\t\treturn Iso8601_Rule.ISO8601_HOURS_MINUTES;\n\t\t\t\tcase 3:\n\t\t\t\t\treturn Iso8601_Rule.ISO8601_HOURS_COLON_MINUTES;\n\t\t\t\tdefault:\n\t\t\t\t\tthrow new IllegalArgumentException(\"invalid number of X\");\n\t\t\t}\n\t\t}\n\n\t\tfinal int length;\n\n\t\t/**\n\t\t * Constructs an instance of {@code Iso8601_Rule} with the specified properties.\n\t\t *\n\t\t * @param length The number of characters in output (unless Z is output)\n\t\t */\n\t\tIso8601_Rule(int length) {\n\t\t\tthis.length = length;\n\t\t}\n\n\t\t/**\n\t\t * {@inheritDoc}\n\t\t */\n\t\t@Override","sourceCodeStart":1208,"sourceCodeEnd":1244,"githubUrl":"https://github.com/chinabugotech/hutool/blob/8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442/hutool-core/src/main/java/cn/hutool/core/date/format/FastDatePrinter.java#L1208-L1244","documentation":"Same rule as the parser's 'X' guard, but for the printer side: Iso8601_Rule.getRule only returns a rule for token length 1, 2, or 3. Patterns with XXXX or XXXXX (four/five X's) hit the default branch and throw at printer construction time.","triggerScenarios":"Building a FastDateFormat with a pattern containing four or five consecutive X's, e.g. 'HH:mmXXXXX'. The throw happens when the formatter is created, not when it formats a value.","commonSituations":"Porting ISO-8601 / RFC-3339 patterns that use the extended zone form; patterns generated from specs that enumerate all five X variants.","solutions":["Limit the X run to 1-3 (XXX yields '+hh:mm' or 'Z').","Use java.text.SimpleDateFormat for the 4/5-X forms if required.","Prefer the 'Z' token (TimeZoneNumberRule) for fixed offset formatting."],"exampleFix":"// before\nFastDateFormat fdf = FastDateFormat.getInstance(\"HH:mm:ssXXXXX\");\n// after\nFastDateFormat fdf = FastDateFormat.getInstance(\"HH:mm:ssXXX\");","handlingStrategy":"validation","validationCode":"String collapseX(String p){ return p.replaceAll(\"X{4,}\", \"XXX\"); }","typeGuard":null,"tryCatchPattern":"try { FastDateFormat.getInstance(pattern); }\ncatch (IllegalArgumentException e){ if(e.getMessage().contains(\"invalid number of X\")) { pattern = pattern.replaceAll(\"X{4,}\",\"XXX\"); } else throw e; }","preventionTips":["Limit X to 1-3 in Hutool patterns.","Prefer Z for offset formatting when 4-5 X would be needed.","Validate printer patterns at config load."],"tags":["date","format-pattern","timezone","iso8601","fast-date","argument"],"backgroundTag":null,"analyzedSha":"8870454b2a0c29cc6ffd31dcf5667c8ceb2fc442","analyzedAt":"2026-08-14T04:01:12.892Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}