{"id":"e8b0197508e6b2cb","repo":"google/gson","slug":"value","errorCode":null,"errorMessage":"{value}","messagePattern":"\\{value\\}","errorType":"exception","errorClass":"NumberFormatException","httpStatus":null,"severity":"error","filePath":"extras/src/main/java/com/google/gson/typeadapters/UtcDateTypeAdapter.java","lineNumber":258,"sourceCode":"   * @return true if the expected character exist at the given offset\n   */\n  private static boolean checkOffset(String value, int offset, char expected) {\n    return (offset < value.length()) && (value.charAt(offset) == expected);\n  }\n\n  /**\n   * Parse an integer located between 2 given offsets in a string\n   *\n   * @param value the string to parse\n   * @param beginIndex the start index for the integer in the string\n   * @param endIndex the end index for the integer in the string\n   * @return the int\n   * @throws NumberFormatException if the value is not a number\n   */\n  private static int parseInt(String value, int beginIndex, int endIndex)\n      throws NumberFormatException {\n    if (beginIndex < 0 || endIndex > value.length() || beginIndex > endIndex) {\n      throw new NumberFormatException(value);\n    }\n    // use same logic as in Integer.parseInt() but less generic we're not supporting negative values\n    int i = beginIndex;\n    int result = 0;\n    int digit;\n    if (i < endIndex) {\n      digit = Character.digit(value.charAt(i++), 10);\n      if (digit < 0) {\n        throw new NumberFormatException(\"Invalid number: \" + value);\n      }\n      result = -digit;\n    }\n    while (i < endIndex) {\n      digit = Character.digit(value.charAt(i++), 10);\n      if (digit < 0) {\n        throw new NumberFormatException(\"Invalid number: \" + value);\n      }\n      result *= 10;","sourceCodeStart":240,"sourceCodeEnd":276,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/extras/src/main/java/com/google/gson/typeadapters/UtcDateTypeAdapter.java#L240-L276","documentation":"Thrown internally by UtcDateTypeAdapter.parseInt() when the requested character range is out of bounds: beginIndex < 0, endIndex > string length, or beginIndex > endIndex. This indicates the date string is shorter than the parser expected at that field (e.g. a 2-digit month where the string ended early). It is a NumberFormatException whose message is the raw value; it propagates up and becomes part of the umbrella ParseException (error 7).","triggerScenarios":"A date string too short for the field being extracted, e.g. \"2024\" when the parser tries to read 2 more chars for the month; truncated payloads; off-by-one slicing from upstream processing. Ultimately surfaced as JsonParseException via the ParseException wrapper.","commonSituations":"Truncated timestamps; strings that were accidentally trimmed; non-ISO formats that happen to parse partially then run out of characters; encoding issues dropping bytes.","solutions":["Ensure the date string is complete and conforms to ISO-8601 length expectations (year=4, month=2, day=2, etc.).","Validate length/format with a regex before parsing (e.g. ^\\d{4}-?\\d{2}-?\\d{2}.*).","Switch to a custom adapter using java.time with a lenient or optional-section pattern if input is variable.","Inspect the raw input shown in the wrapped ParseException to see where truncation occurred."],"exampleFix":"// before: truncated date\nString json = \"\\\"2024\\\"\";\nDate d = gson.fromJson(json, Date.class); // ultimately JsonParseException\n\n// after: full ISO-8601 date\nString json = \"\\\"2024-01-01T00:00:00Z\\\"\";\nDate d = gson.fromJson(json, Date.class);","handlingStrategy":"validation","validationCode":"// Reject truncated date strings before parsing\nstatic void requireMinLength(String date, int min) {\n  if (date == null || date.length() < min) {\n    throw new IllegalArgumentException(\"Date too short (expected >= \" + min + \"): \" + date);\n  }\n}","typeGuard":"static boolean isCompleteIsoDate(String date) {\n  // basic completeness check for yyyy-MM-ddThh:mm:ss[Z|+HH:mm]\n  return date != null && date.length() >= 20 && date.matches(\"^\\\\d{4}-\\\\d{2}-\\\\d{2}T\\\\d{2}:\\\\d{2}:\\\\d{2}.*\");\n}","tryCatchPattern":"try {\n  Date d = gson.fromJson(json, Date.class);\n} catch (JsonParseException e) {\n  Throwable c = e.getCause();\n  if (c != null && c.getMessage() != null && c.getCause() instanceof NumberFormatException) {\n    // truncated input; reject or pad/retry\n  } else throw e;\n}","preventionTips":["Ensure producer emits full ISO-8601 strings (no truncation).","Validate minimum length and digit-position regex before parsing.","Guard transport/serialization layers against trimming or dropping characters.","Use java.time with optional sections if some components are legitimately absent."],"tags":["date","iso8601","utc-adapter","parsing","number-format","truncated-input"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}