{"id":"81be8f7cafd7491b","repo":"google/gson","slug":"failed-parsing-s-as-sql-time-at-path","errorCode":null,"errorMessage":"Failed parsing '\" + s + \"' as SQL Time; at path \" + in.getPreviousPath()","messagePattern":"Failed parsing '\" \\+ s \\+ \"' as SQL Time; at path \" \\+ in\\.getPreviousPath\\(\\)","errorType":"exception","errorClass":"JsonSyntaxException","httpStatus":null,"severity":"error","filePath":"gson/src/main/java/com/google/gson/internal/sql/SqlTimeTypeAdapter.java","lineNumber":70,"sourceCode":"\n  private final DateFormat format = new SimpleDateFormat(\"hh:mm:ss a\");\n\n  private SqlTimeTypeAdapter() {}\n\n  @Override\n  public Time read(JsonReader in) throws IOException {\n    if (in.peek() == JsonToken.NULL) {\n      in.nextNull();\n      return null;\n    }\n    String s = in.nextString();\n    synchronized (this) {\n      TimeZone originalTimeZone = format.getTimeZone(); // Save the original time zone\n      try {\n        Date date = format.parse(s);\n        return new Time(date.getTime());\n      } catch (ParseException e) {\n        throw new JsonSyntaxException(\n            \"Failed parsing '\" + s + \"' as SQL Time; at path \" + in.getPreviousPath(), e);\n      } finally {\n        format.setTimeZone(originalTimeZone); // Restore the original time zone\n      }\n    }\n  }\n\n  @Override\n  public void write(JsonWriter out, Time value) throws IOException {\n    if (value == null) {\n      out.nullValue();\n      return;\n    }\n    String timeString;\n    synchronized (this) {\n      timeString = format.format(value);\n    }\n    out.value(timeString);","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/google/gson/blob/8b8628c65699bc4421696183c62ae0c1b9b281dc/gson/src/main/java/com/google/gson/internal/sql/SqlTimeTypeAdapter.java#L52-L88","documentation":"SqlTimeTypeAdapter parses the JSON string with SimpleDateFormat(\"hh:mm:ss a\") (12-hour clock with AM/PM marker, e.g. '01:30:00 PM'). A ParseException is wrapped as JsonSyntaxException. The format is locale-sensitive and synchronized.","triggerScenarios":"Deserializing a JSON value into a java.sql.Time field where the string is not in 'hh:mm:ss a' 12-hour form (e.g. '14:30:00' 24-hour, ISO format, or missing AM/PM).","commonSituations":"Producer emits 24-hour ISO times, missing AM/PM marker, or a locale whose DateTimeSymbols lack the expected symbols; mismatched conventions across system layers.","solutions":["Provide the time string in 'hh:mm:ss a' form (e.g. '02:30:00 PM').","Register a custom TypeAdapter<java.sql.Time> using a 24-hour format like 'HH:mm:ss'.","Deserialize as java.time.LocalTime and convert if the SQL type is not essential."],"exampleFix":"// before\njava.sql.Time t = gson.fromJson(\"\\\"14:30:00\\\"\", java.sql.Time.class);\n\n// after\nGson gson = new GsonBuilder().registerTypeAdapter(java.sql.Time.class, new TypeAdapter<java.sql.Time>() {\n    @Override public java.sql.Time read(JsonReader in) throws IOException { return java.sql.Time.valueOf(in.nextString()); }\n    @Override public void write(JsonWriter out, java.sql.Time v) throws IOException { out.value(v.toString()); }\n}).create();","handlingStrategy":"validation","validationCode":"boolean isSqlTimeParsable(String s) {\n  if (s == null) return false;\n  try { java.text.DateFormat f = new java.text.SimpleDateFormat(\"hh:mm:ss a\", Locale.ENGLISH); f.parse(s); return true; }\n  catch (java.text.ParseException e) { return false; }\n}","typeGuard":"static boolean matchesDefaultSqlTimeFormat(String s) {\n  return s != null && s.matches(\"\\\\d{2}:\\\\d{2}:\\\\d{2} (AM|PM)\");\n}","tryCatchPattern":"try {\n  java.sql.Time t = gson.fromJson(json, java.sql.Time.class);\n} catch (JsonSyntaxException e) {\n  // register a 24-hour HH:mm:ss adapter and retry\n}","preventionTips":["Register a java.sql.Time adapter with the producer's 24-hour format.","Pin Locale.ENGLISH for AM/PM symbols if you keep the default format.","Prefer java.time.LocalTime for new code."],"tags":["gson","deserialization","sql-time","date-parsing","locale","json"],"analyzedSha":"8b8628c65699bc4421696183c62ae0c1b9b281dc","analyzedAt":"2026-08-04T19:12:22.202Z","schemaVersion":2}