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
- Ensure the source string includes an explicit timezone (append 'Z' for UTC, or '+HH:mm').
- Pre-process the string to append a default timezone before parsing.
- 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
- Mandate timezone-suffixed ISO-8601 strings at the producer boundary.
- Prefer java.time.Instant which enforces an offset/zone.
- Register a Date adapter that defaults to UTC when the zone is missing.
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
- Mismatching time zone indicator: " + timezoneId + " given, r
- Invalid time zone indicator '" + timezoneIndicator + "'
- value
- Invalid number: " + value.substring(beginIndex, endIndex)
- Failed parsing '" + s + "' as SQL Date; at path " + in.getPr
AI-assisted analysis of google/gson@8b8628c656 (2026-08-04).
Data as JSON: /data/errors/259e4b186f2efdf8.json.
Report an issue: GitHub.