{"id":"19592c0d56bf74c8","repo":"google/gson","slug":"invalid-time-zone-indicator-timezoneindicator-19592c","errorCode":null,"errorMessage":"Invalid time zone indicator '\" + timezoneIndicator + \"'","messagePattern":"Invalid time zone indicator '\" \\+ timezoneIndicator \\+ \"'","errorType":"exception","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/bind/util/ISO8601Utils.java","lineNumber":279,"sourceCode":"          String act = timezone.getID();\n          if (!act.equals(timezoneId)) {\n            /* 22-Jan-2015, tatu: Looks like canonical version has colons, but we may be given\n             *    one without. If so, don't sweat.\n             *   Yes, very inefficient. Hopefully not hit often.\n             *   If it becomes a perf problem, add 'loose' comparison instead.\n             */\n            String cleaned = act.replace(\":\", \"\");\n            if (!cleaned.equals(timezoneId)) {\n              throw new IndexOutOfBoundsException(\n                  \"Mismatching time zone indicator: \"\n                      + timezoneId\n                      + \" given, resolves to \"\n                      + timezone.getID());\n            }\n          }\n        }\n      } else {\n        throw new IndexOutOfBoundsException(\n            \"Invalid time zone indicator '\" + timezoneIndicator + \"'\");\n      }\n\n      Calendar calendar = new GregorianCalendar(timezone);\n      calendar.setLenient(false);\n      calendar.set(Calendar.YEAR, year);\n      calendar.set(Calendar.MONTH, month - 1);\n      calendar.set(Calendar.DAY_OF_MONTH, day);\n      calendar.set(Calendar.HOUR_OF_DAY, hour);\n      calendar.set(Calendar.MINUTE, minutes);\n      calendar.set(Calendar.SECOND, seconds);\n      calendar.set(Calendar.MILLISECOND, milliseconds);\n\n      pos.setIndex(offset);\n      return calendar.getTime();\n      // If we get a ParseException it'll already have the right message/offset.\n      // Other exception types can convert here.\n    } catch (IndexOutOfBoundsException | IllegalArgumentException e) {","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/internal/bind/util/ISO8601Utils.java#L261-L297","documentation":"ISO8601Utils reaches the timezone position but the character there is not 'Z', '+', or '-', indicating a structurally malformed date string. It throws IndexOutOfBoundsException 'Invalid time zone indicator'.","triggerScenarios":"A date string where the timezone slot is occupied by an unexpected character, e.g. trailing 'X', a letter, or a stray separator after the time component.","commonSituations":"Truncated/garbled date strings, mixed formats, or a producer that emits a non-ISO marker at the end.","solutions":["Inspect the string at the reported offset and correct the timezone marker to Z or +/-.","Pre-validate the string against an ISO-8601 pattern before deserialization.","Register a custom TypeAdapter<Date> using a more lenient parser."],"exampleFix":"// before\nDate d = gson.fromJson(\"\\\"2024-01-01T00:00:00X\\\"\", Date.class);\n\n// after\nString s = source.substring(0, source.length() - 1) + \"Z\";\nDate d = gson.fromJson('\"' + s + '\"', Date.class);","handlingStrategy":"validation","validationCode":"boolean hasValidTimezoneIndicatorChar(String iso) {\n  if (iso == null || iso.isEmpty()) return false;\n  char c = iso.charAt(iso.length() - 1);\n  if (c == 'Z') return true;\n  return iso.matches(\".*[+\\\\-][0-9]{2}:?[0-9]{2}$\");\n}","typeGuard":"static boolean endsWithIsoTimezone(String iso) {\n  return iso != null && (iso.endsWith(\"Z\") || iso.matches(\".*[+\\\\-]\\\\d{2}:?\\\\d{2}$\"));\n}","tryCatchPattern":"try {\n  Date d = gson.fromJson(json, Date.class);\n} catch (JsonSyntaxException e) {\n  // strip stray trailing chars, append Z, retry\n}","preventionTips":["Reject strings whose timezone slot is not Z or +/- at validation time.","Use java.time with strict parsers to surface format issues early.","Run producer/consumer contract tests on date formats."],"tags":["gson","date-parsing","iso8601","timezone","json"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}