google/gson · error · IllegalArgumentException

No time zone indicator

Error message

No time zone indicator

What it means

ISO8601Utils.parse reaches the timezone-extraction step but the input string ends before any timezone character is present (offset >= length). ISO 8601 requires a trailing 'Z' or +/- offset for a complete date-time, so the parser throws IllegalArgumentException 'No time zone indicator'. The exception is later wrapped into a ParseException.

Source

Thrown at gson/src/main/java/com/google/gson/internal/bind/util/ISO8601Utils.java:231

              switch (parseEndOffset - offset) { // number of digits parsed
                case 2:
                  milliseconds = fraction * 10;
                  break;
                case 1:
                  milliseconds = fraction * 100;
                  break;
                default:
                  milliseconds = fraction;
              }
              offset = endOffset;
            }
          }
        }
      }

      // extract timezone
      if (date.length() <= offset) {
        throw new IllegalArgumentException("No time zone indicator");
      }

      TimeZone timezone = null;
      char timezoneIndicator = date.charAt(offset);

      if (timezoneIndicator == 'Z') {
        timezone = TIMEZONE_UTC;
        offset += 1;
      } else if (timezoneIndicator == '+' || timezoneIndicator == '-') {
        String timezoneOffset = date.substring(offset);

        // When timezone has no minutes, we should append it, valid timezones are, for example:
        // +00:00, +0000 and +00
        timezoneOffset = timezoneOffset.length() >= 5 ? timezoneOffset : timezoneOffset + "00";

        offset += timezoneOffset.length();
        // 18-Jun-2015, tatu: Minor simplification, skip offset of "+0000"/"+00:00"
        if (timezoneOffset.equals("+0000") || timezoneOffset.equals("+00:00")) {

View on GitHub (pinned to 8b8628c656)

Solutions

  1. Ensure the source string includes an explicit timezone (append 'Z' for UTC, or '+HH:mm').
  2. Pre-process the string to append a default timezone before parsing.
  3. Register a custom TypeAdapter<Date> that uses a SimpleDateFormat lenient with no timezone, or java.time with a fixed ZoneId.

Example fix

// before
Date d = gson.fromJson("\"2024-01-01T00:00:00\"", Date.class);

// after: normalize missing tz to UTC
String s = json;
if (!s.endsWith("Z") && !s.matches(".*[+\\-][0-9]{2}:?[0-9]{2}$")) s += "Z";
Date d = gson.fromJson('"' + s + '"', Date.class);
Defensive patterns

Strategy: validation

Validate before calling

String ensureTimezone(String iso) {
  if (iso == null || iso.isEmpty()) return iso;
  if (iso.endsWith("Z")) return iso;
  if (iso.matches(".*[+\\-][0-9]{2}:?[0-9]{2}$")) return iso;
  return iso + "Z";
}

Type guard

static boolean hasTimezoneIndicator(String iso) {
  return iso != null && (iso.endsWith("Z") || iso.matches(".*[+\\-][0-9]{2}:?[0-9]{2}$"));
}

Try / catch

try {
  Date d = gson.fromJson(json, Date.class);
} catch (JsonSyntaxException e) {
  // append a default zone, retry once
}

Prevention

When it happens

Trigger: Parsing a date string such as '2024-01-01T00:00:00' that has no trailing 'Z' or '+00:00' offset, used by Gson's Date/old date adapters that rely on ISO8601Utils.

Common situations: Producer emits ISO-8601 'local' date-times without timezone, a producer that historically included 'Z' is changed, or a field is shared between systems with different tz conventions.

Related errors


AI-assisted analysis of google/gson@8b8628c656 (2026-08-04). Data as JSON: /data/errors/259e4b186f2efdf8.json. Report an issue: GitHub.