HMCL-dev/HMCL · error · JsonParseException
Invalid instant:
Error message
Invalid instant:
What it means
deserializeToInstant tries several DateTimeFormatter patterns (ISO offset/zoned, ISO local date-time) and throws this JsonParseException when none of them can parse the string. The original DateTimeParseException is attached as the cause.
Solutions
- Re-serialize the value in ISO-8601 format (Instant.toString() or DateTimeFormatter.ISO_OFFSET_DATE_TIME).
- Parse the legacy format yourself with DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM).withLocale(Locale.US) and convert to Instant before passing it on.
- Check the string for timezone information; ISO_LOCAL_DATE_TIME paths use ZoneId.systemDefault(), so supply an explicit zone when converting.
- Confirm no whitespace or locale-specific month/day names are present in the stored value.
Example fix
// before
{"timestamp": "07/03/24 9:06 AM"} // legacy localized format
// after
{"timestamp": "2024-07-03T09:06:00Z"} // ISO-8601 Defensive patterns
Strategy: try-catch
Validate before calling
try {
Instant.parse(value);
return true;
} catch (DateTimeParseException e) {
return false;
} Try / catch
try {
return gson.fromJson(json, Instant.class);
} catch (JsonParseException e) {
// fall back to legacy localized format
Instant t = LocalDateTime.parse(raw, LEGACY_EN_US_FORMAT).atZone(ZoneId.systemDefault()).toInstant();
} Prevention
- Store timestamps in ISO-8601 (Instant.toString()).
- Never persist locale-dependent date formats.
- Include timezone offsets in stored strings.
- Migrate legacy EN_US formatted values once on config load.
When it happens
Trigger: Deserializing an Instant field whose string value is in an unrecognized format: epoch millis as string, "dd/MM/yyyy HH:mm", a locale-specific EN_US format produced by a different JDK, or a truncated date.
Common situations: Data written by older HMCL versions using the legacy US localized formatter, values saved with a different system default timezone/locale, or hand-edited config timestamps.
Related errors
- Cannot deserialize
- Config is not an object:
- Expected JsonObject but got
- Invalid JSON schema
- Json object cannot be null.
AI-assisted analysis of HMCL-dev/HMCL@24702dc5a0 (2026-09-10).
Data as JSON: /api/errors/b45fce8893ca0c42.
Report an issue: GitHub.
Appendix: source
Thrown at HMCLCore/src/main/java/org/jackhuang/hmcl/util/gson/InstantTypeAdapter.java:111
/// Parses an instant from one of the supported textual representations.
///
/// @param string the text to parse
/// @return the parsed instant
/// @throws JsonParseException if `string` is not in a supported instant format
public static Instant deserializeToInstant(String string) {
try {
return ZonedDateTime.parse(string, EN_US_FORMAT).toInstant();
} catch (DateTimeParseException ex1) {
try {
ZonedDateTime zonedDateTime = ZonedDateTime.parse(string, ISO_DATE_TIME);
return zonedDateTime.toInstant();
} catch (DateTimeParseException e) {
try {
LocalDateTime localDateTime = LocalDateTime.parse(string, ISO_LOCAL_DATE_TIME);
return localDateTime.atZone(ZoneId.systemDefault()).toInstant();
} catch (DateTimeParseException e2) {
throw new JsonParseException("Invalid instant: " + string, e);
}
}
}
}
/// Formats an instant as an ISO offset date-time string in the given time zone.
///
/// The output is truncated to whole seconds.
///
/// @param instant the instant to format
/// @param zone the time zone used to render the instant
/// @return the formatted instant
public static String serializeToString(Instant instant, ZoneId zone) {
return DateTimeFormatter.ISO_OFFSET_DATE_TIME.format(ZonedDateTime.ofInstant(instant, zone).truncatedTo(ChronoUnit.SECONDS));
}
}
View on GitHub (pinned to 24702dc5a0)